1 2/* 3 jQuery Tags Input Plugin 1.3.3 4 Copyright (c) 2011 XOXCO, Inc 5 Documentation for this plugin lives here: 6 http://xoxco.com/clickable/jquery-tags-input 7 Licensed under the MIT license: 8 http://www.opensource.org/licenses/mit-license.php 9 [email protected] 10*/ 11!function(t){var a=new Array,e=new Array;t.fn.doAutosize=function(a){var e=t(this).data("minwidth"),i=t(this).data("maxwidth"),n="",u=t(this),r=t("#"+t(this).data("tester_id"));if(n!==(n=u.val())){var d=n.replace(/&/g,"&").replace(/\s/g," ").replace(/</g,"<").replace(/>/g,">");r.html(d);var o=r.width(),s=o+a.comfortZone>=e?o+a.comfortZone:e;(s<u.width()&&s>=e||s>e&&s<i)&&u.width(s)}},t.fn.resetAutosize=function(a){var e=t(this).data("minwidth")||a.minInputWidth||t(this).width(),i=t(this).data("maxwidth")||a.maxInputWidth||t(this).closest(".tagsinput").width()-a.inputPadding,n=t(this),u=t("<tester/>").css({position:"absolute",top:-9999,left:-9999,width:"auto",fontSize:n.css("fontSize"),fontFamily:n.css("fontFamily"),fontWeight:n.css("fontWeight"),letterSpacing:n.css("letterSpacing"),whiteSpace:"nowrap"}),r=t(this).attr("id")+"_autosize_tester";!t("#"+r).length>0&&(u.attr("id",r),u.appendTo("body")),n.data("minwidth",e),n.data("maxwidth",i),n.data("tester_id",r),n.css("width",e)},t.fn.addTag=function(i,n){return n=jQuery.extend({focus:!1,callback:!0},n),this.each(function(){var u=t(this).attr("id"),r=t(this).val().split(a[u]);if(""==r[0]&&(r=new Array),i=jQuery.trim(i),n.unique)1==(d=t(this).tagExist(i))&&t("#"+u+"_tag").addClass("not_valid");else var d=!1;if(""!=i&&1!=d){if(t("<span>").addClass("tag").append(t("<span>").text(i).append(" "),t("<a>",{href:"#",title:"Removing tag",text:"x"}).click(function(){return t("#"+u).removeTag(escape(i))})).insertBefore("#"+u+"_addTag"),r.push(i),t("#"+u+"_tag").val(""),n.focus?t("#"+u+"_tag").focus():t("#"+u+"_tag").blur(),t.fn.tagsInput.updateTagsField(this,r),n.callback&&e[u]&&e[u].onAddTag)e[u].onAddTag.call(this,i);if(e[u]&&e[u].onChange){var o=r.length;e[u].onChange.call(this,t(this),r[o-1])}}}),!1},t.fn.removeTag=function(n){return n=unescape(n),this.each(function(){var u=t(this).attr("id"),r=t(this).val().split(a[u]);for(t("#"+u+"_tagsinput .tag").remove(),str="",i=0;i<r.length;i++)r[i]!=n&&(str=str+a[u]+r[i]);(t.fn.tagsInput.importTags(this,str),e[u]&&e[u].onRemoveTag)&&e[u].onRemoveTag.call(this,n)}),!1},t.fn.tagExist=function(e){var i=t(this).attr("id"),n=t(this).val().split(a[i]);return jQuery.inArray(e,n)>=0},t.fn.importTags=function(a){var e=t(this).attr("id");t("#"+e+"_tagsinput .tag").remove(),t.fn.tagsInput.importTags(this,a)},t.fn.tagsInput=function(i){var u=jQuery.extend({interactive:!0,defaultText:"add a tag",minChars:0,width:"300px",height:"100px",autocomplete:{selectFirst:!1},hide:!0,delimiter:",",unique:!0,removeWithBackspace:!0,placeholderColor:"#666666",autosize:!0,comfortZone:20,inputPadding:12},i),r=0;return this.each(function(){if(void 0===t(this).attr("data-tagsinput-init")){t(this).attr("data-tagsinput-init",!0),u.hide&&t(this).hide();var i=t(this).attr("id");i&&!a[t(this).attr("id")]||(i=t(this).attr("id","tags"+(new Date).getTime()+r++).attr("id"));var d=jQuery.extend({pid:i,real_input:"#"+i,holder:"#"+i+"_tagsinput",input_wrapper:"#"+i+"_addTag",fake_input:"#"+i+"_tag"},u);a[i]=d.delimiter,(u.onAddTag||u.onRemoveTag||u.onChange)&&(e[i]=new Array,e[i].onAddTag=u.onAddTag,e[i].onRemoveTag=u.onRemoveTag,e[i].onChange=u.onChange);var o='<div id="'+i+'_tagsinput" class="tagsinput form-control"><div id="'+i+'_addTag">';if(u.interactive&&(o=o+'<input id="'+i+'_tag" value="" data-default="'+u.defaultText+'" />'),t(o+='</div><div class="tags_clear"></div></div>').insertAfter(this),t(d.holder).css("width",u.width),t(d.holder).css("min-height",u.height),t(d.holder).css("height",u.height),""!=t(d.real_input).val()&&t.fn.tagsInput.importTags(t(d.real_input),t(d.real_input).val()),u.interactive){if(t(d.fake_input).val(t(d.fake_input).attr("data-default")),t(d.fake_input).css("color",u.placeholderColor),t(d.fake_input).resetAutosize(u),t(d.holder).bind("click",d,function(a){t(a.data.fake_input).focus()}),t(d.fake_input).bind("focus",d,function(a){t(a.data.fake_input).val()==t(
11a.data.fake_input).attr("data-default")&&t(a.data.fake_input).val(""),t(a.data.fake_input).css("color","#000000")}),null!=u.autocomplete_url){for(attrname in autocomplete_options={source:u.autocomplete_url},u.autocomplete)autocomplete_options[attrname]=u.autocomplete[attrname];void 0!==jQuery.Autocompleter?(t(d.fake_input).autocomplete(u.autocomplete_url,u.autocomplete),t(d.fake_input).bind("result",d,function(a,e,n){e&&t("#"+i).addTag(e[0]+"",{focus:!0,unique:u.unique})})):void 0!==jQuery.ui.autocomplete&&(t(d.fake_input).autocomplete(autocomplete_options),t(d.fake_input).bind("autocompleteselect",d,function(a,e){return t(a.data.real_input).addTag(e.item.value,{focus:!0,unique:u.unique}),!1}))}else t(d.fake_input).bind("blur",d,function(a){var e=t(this).attr("data-default");return""!=t(a.data.fake_input).val()&&t(a.data.fake_input).val()!=e?a.data.minChars<=t(a.data.fake_input).val().length&&(!a.data.maxChars||a.data.maxChars>=t(a.data.fake_input).val().length)&&t(a.data.real_input).addTag(t(a.data.fake_input).val(),{focus:!0,unique:u.unique}):(t(a.data.fake_input).val(t(a.data.fake_input).attr("data-default")),t(a.data.fake_input).css("color",u.placeholderColor)),!1});t(d.fake_input).bind("keypress",d,function(a){if(n(a))return a.preventDefault(),a.data.minChars<=t(a.data.fake_input).val().length&&(!a.data.maxChars||a.data.maxChars>=t(a.data.fake_input).val().length)&&t(a.data.real_input).addTag(t(a.data.fake_input).val(),{focus:!0,unique:u.unique}),t(a.data.fake_input).resetAutosize(u),!1;a.data.autosize&&t(a.data.fake_input).doAutosize(u)}),d.removeWithBackspace&&t(d.fake_input).bind("keydown",function(a){if(8==a.keyCode&&""==t(this).val()){a.preventDefault();var e=t(this).closest(".tagsinput").find(".tag:last").text(),i=t(this).attr("id").replace(/_tag$/,"");e=e.replace(/[\s]+x$/,""),t("#"+i).removeTag(escape(e)),t(this).trigger("focus")}}),t(d.fake_input).blur(),d.unique&&t(d.fake_input).keydown(function(a){(8==a.keyCode||String.fromCharCode(a.which).match(/\w+|[áéÃóúÃÃÃÃÃñÃ,\/]+/))&&t(this).removeClass("not_valid")})}}}),this},t.fn.tagsInput.updateTagsField=function(e,i){var n=t(e).attr("id");t(e).val(i.join(a[n]))},t.fn.tagsInput.importTags=function(n,u){t(n).val("");var r=t(n).attr("id"),d=u.split(a[r]);for(i=0;i<d.length;i++)t(n).addTag(d[i],{focus:!1,callback:!1});e[r]&&e[r].onChange&&e[r].onChange.call(n,n,d[i])};var n=function(a){var e=!1;return 13==a.which||("string"==typeof a.data.delimiter?a.which==a.data.delimiter.charCodeAt(0)&&(e=!0):t.each(a.data.delimiter,function(t,i){a.which==i.charCodeAt(0)&&(e=!0)}),e)}}(jQuery); 12 13var searchFormMap; 14var accessToken = 'pk.eyJ1IjoiamFraWIiLCJhIjoiY2xha3RmbXBuMHE2czNxbjNiaThlMzE3eCJ9.OPqokjncM4xpF2OgMW6XMA'; 15var latLng; 16var searchFormMapRadiusCircle; 17var defaults = $('input[name="_defaults"]').length ? JSON.parse($('input[name="_defaults"]').val()) : {}; 18 19$(document).ready(function() { 20 // Default map to the embedable map's position if available, otherwise centre of the UK 21 latLng = (typeof latitude !== 'undefined' && typeof longitude !== 'undefined') 22 ? new L.LatLng(latitude, longitude) 23 : new L.LatLng(54.002595, -2.548889); 24 25 handleAutocomplete(); 26 handleRadius(); 27 showMap(); 28 handleTags(); 29 initRadiusField(); 30 profileTypesFilter(); 31 32 updateFilters(); 33 34 advancedFiltersToggle(); 35 $('input[type="checkbox"]').each(function() { 36 checkboxHandleCheckedClass($(this)) 37 }) 38}); 39 40/** 41 * When a user choses an address, update the map with the location/radius 42 */ 43function handleAutocomplete() 44{ 45 $(window).on('addressChosen', function(event, data) { 46 $('#search-form-map').show(); 47 48 if(typeof searchFormMap !== 'undefined' && searchFormMap) { 49 searchFormMap.invalidateSize(); 50 } 51 52 updateSearchFormMap(data.lat, data.lng); 53 }); 54} 55 56/** 57 * When the radius changes, update the circle on the map 58 */ 59function handleRadius() 60{ 61 $('select[name="radius"]').change(function() { 62 if ($(this).val() == 999) { 63 var ukLat = 54.002595; 64 var ukLng = -2.548889; 65 var $form = $(this).closest('form'); 66 67 $form.find('input[name="location"]').val('United Kingdom'); 68 69 if ($form.find('input[name="lat"]').length) { 70 $form.find('input[name="lat"]').val(ukLat); 71 } else { 72 $('<input type="hidden" name="lat">').val(ukLat).appendTo($form); 73 } 74 75 if ($form.find('input[name="lng"]').length) { 76 $form.find('input[name="lng"]').val(ukLng); 77 } else { 78 $('<input type="hidden" name="lng">').val(ukLng).appendTo($form); 79 } 80 81 updateSearchFormMap(ukLat, ukLng); 82 } else { 83 updateSearchFormMap(latLng.lat, latLng.lng); 84 } 85 86 if($(this).val() == 0) { 87 $('input#enable_radius').prop('checked', false).change(); 88 } 89 }); 90} 91 92function showMap() 93{ 94 L.mapbox.accessToken = accessToken; 95 96 var mapboxTiles = L.tileLayer('https://api.mapbox.com/styles/v1/jakib/ckkl2o2ok3dv417nu339jmkqs/tiles/256/{z}/{x}/{y}
96@2x?access_token=' + L.mapbox.accessToken, { 97 attribution: '© <a href="https://www.mapbox.com/feedback/">Mapbox</a> © <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>', 98 tileSize: 512, 99 zoomOffset: -1 100 }); 101 102 // Initalize the map 103 searchFormMap = L.map('search-form-map', { 104 dragging: false, 105 doubleClickZoom: false, 106 zoomControl: false, 107 scrollWheelZoom: false 108 }).addLayer(mapboxTiles) 109 .setView(latLng, (typeof searchFormMapZoom !== 'undefined' && searchFormMapZoom) ? searchFormMapZoom : 4); 110 111 if(defaults.lat && defaults.lng) { 112 if($('#filter-form').length == 1) { 113 $('body').on('moreFiltersLoaded', function() { 114 updateSearchFormMap(defaults.lat, defaults.lng); 115 }) 116 } 117 } 118 119 // In the embedable context, show the map preview if a location was previously chosen 120 if($('#embedable-filter-form').length == 1) { 121 $('body').on('moreFiltersLoaded', function() { 122 var lat = $('input[name="lat"]').val(); 123 var lng = $('input[name="lng"]').val(); 124 125 if(lat && lng) { 126 $('#search-form-map').show(); 127 128 if(typeof searchFormMap !== 'undefined' && searchFormMap) { 129 searchFormMap.invalidateSize(); 130 } 131 132 updateSearchFormMap(lat, lng); 133 } 134 }); 135 } 136} 137 138/** 139 * Update the circle on the map based on the center lat/lng 140 * @param lat - the latitude integer 141 * @param lng - the longitude integer 142 */ 143function updateSearchFormMap(lat, lng) 144{ 145 var targetMap = (typeof searchFormMap !== 'undefined' && searchFormMap) 146 ? searchFormMap 147 : (typeof map !== 'undefined' && map ? map : null); 148 149 if(!targetMap) return false; 150 151 console.log(targetMap); 152 console.log(lat, lng); 153 154 // Get radius and convert to meters 155 if($('#search-form select[name="radius"]').val() != '') { 156 var radius = parseInt($('#search-form select[name="radius"]').val()) * 1609.344; 157 } else { 158 var radius = false; 159 } 160 161 if(lat === undefined || lng === undefined) { 162 return false; 163 } 164 165 latLng = new L.latLng(lat, lng); 166 167 // Delete old circle 168 if (searchFormMapRadiusCircle !== undefined) { 169 targetMap.removeLayer(searchFormMapRadiusCircle); 170 } 171 172 if(radius) { 173 searchFormMapRadiusCircle = L.circle(latLng, radius, { 174 'color': '#6c007a', 175 'fillOpacity': 0 176 }).addTo(targetMap); 177 178 targetMap.fitBounds(searchFormMapRadiusCircle.getBounds()); 179 } else { 180 targetMap.setView(latLng, 15); 181 } 182} 183 184/** 185 * Display an input field where user's can add multiple tags 186 */ 187function handleTags() 188{ 189 $('.tag-field').each(function() { 190 $(this).tagsInput({ 191 defaultText: 'Add a keyword', 192 193 }); 194 }); 195} 196 197/** 198 * Handles how the filters are updated within the results 199 * If the form has a # within the action, this will determine an Ajax request 200 * Otherwise the filters will be sent to the action value with GET parameters 201 */ 202function updateFilters() 203{ 204 $('#search-form').submit(function(event) { 205 event.preventDefault(); 206 event.stopImmediatePropagation(); 207 208 var form = $(this); 209 210 // Get form data in key/value pairs 211 var data = {}; 212 213 data.location = form.find('input[name="location"]').val(); 214 215 if(form.find('input[name="lat"]').length == 1 && form.find('input[name="lat"]').val() != '') { 216 data.lat = form.find('input[name="lat"]').val(); 217 } 218 219 if(form.find('input[name="lng"]').length == 1 && form.find('input[name="lng"]').val() != '') { 220 data.lng = form.find('input[name="lng"]').val(); 221 } 222 223 if(form.find('select[name="radius"]').val() != null && form.find('select[name="radius"]').val() != 0) { 224 data.radius = form.find('select[name="radius"]').val(); 225 226 if(typeof searchFilters === 'function') { 227 // Delete bounds data from URL 228 searchFilters({ ne_bounds: '', sw_bounds: ''}, true); 229 } 230 } else { 231 // Prior to searching for new projects, the system will update map bounds to enable search 232 if(typeof updateURLMapBounds === 'function') { 233 // As the radius is not enabled, make sure it's deleted from the query string 234 data.radius = 'delete'; 235 236 updateURLMapBounds(true); 237 } 238 } 239 240 data.categories = getSelectedCheckboxValues(form.find('input[name="categories[]"]')); 241 data.tags = getSelectedCheckboxValues(form.find('input[name="tags[]"]')); 242 if (!$('#show_all_profile_types').is(':checked')) { 243 data.types = getSelectedCheckboxValues(form.find('input[name="types[]"]')); 244 245 if (data.types.length == 0) { 246 alert('Please select some profile types otherwise, enable the "Show all profile types" toggle.') 247 return false; 248 } 249 } else { 250 data.types = [] 251 } 252 data.keywords = form.find('input[name="keywords"]').val(); 253 254 if(data.lat === undefined || data.lat == '' || data.lng === undefined || data.lng == '') { 255 256 if(typeof searchFilters === 'function') { 257 // We're on the map page so double check there is bounds data 258 filters = searchFilters(); 259 260 if(!filters.get('ne_bounds') && !filters.get('sw_bounds')) { 261 262 alert('Please choose a location that you\'d like the find projects in (you need to choose an address from the dropdown box which appears as you type in the \'Location\' field) or alternatively, navigate on the map to area that you would like to find projects in.'); 263 return false; 264 } 265 } else if(typeof searchForProjects !== 'function') { 266 // This is the /app/search page, so just indicate the user needs to choose a location 267 alert('Please choose a location that you\'d like the find projects in (you need to choose an address from the dropdown box which appears as you type in the \'Location\' field).'); 268 return false; 269 } 270 271 } 272 273 $(this).find('input[type="submit"]').val('Updating...') 274 275 if(form.attr('action') == '#') { 276 $('body').trigger('closeMoreFilters'); 277
278 $(document).on('filterFormClosed', function() { 279 // Update the global filters object before calling searchForProjects() so 280 // embedable.js's searchForProjects() picks up the new filter values when it reads from it 281 filters = data; 282 283 searchForProjects(data); 284 285 $('#search-form').find('input[type="submit"]').val('Update Filters'); 286 287 $(document).off('filterFormClosed'); 288 }); 289 } else { 290 // We'll submit the data to the specified action 291 var action = form.attr('action') + '?'; 292 293 f = 0; 294 for(var field in data) { 295 if(f > 0) { 296 action += '&'; 297 } 298 299 action += field + '=' + data[field]; 300 301 f++; 302 } 303 304 window.location.href = action; 305 } 306 }); 307} 308 309function advancedFiltersToggle() 310{ 311 var advancedFilters = $('#search-form').find('.advanced-filters'); 312 313 $('.advanced-filters-toggle').click(function(event) { 314 event.preventDefault(); 315 316 if(advancedFilters.is(':visible')) { 317 advancedFilters.slideUp(); 318 $(this).find('.icon-minus').replaceWith('<span class="icon-plus"></span>'); 319 } else { 320 advancedFilters.slideDown(); 321 $(this).find('.icon-plus').replaceWith('<span class="icon-minus"></span>'); 322 } 323 }); 324 325 // Show the advanced filters if there is data in it on page load 326 if(advancedFilters.find('input[name="categories[]"]').is(':checked') || advancedFilters.find('input[name="keywords"]').val() != '') { 327 $('.advanced-filters-toggle').click(); 328 } 329} 330 331function initRadiusField() 332{ 333 $('.radius-field-container').each(function() { 334 var checkbox = $(this).find('input[name="enable_radius"]'); 335 336 if(!$(this).hasClass('active')) { 337 338 $(this).addClass('active'); 339 340 handleRadiusField(checkbox); 341 342 checkbox.change(function() { 343 handleRadiusField(checkbox); 344 }); 345 } 346 }); 347} 348 349/** 350 * Handle the radius field for the search functionality 351 */ 352function handleRadiusField(field) 353{ 354 var container = field.parents('.radius-field-container'); 355 var radiusField = field.parents('.radius-field-container').find('select[name="radius"]'); 356 357 if(field.is(':checked')) { 358 container.addClass('visible'); 359 360 container.find('.radius-field').fadeIn(function() { 361 362 363 if(radiusField.val() == 0 || radiusField.val() == null) { 364 radiusField.val('10'); 365 366 if(typeof updateSearchFormMap == 'function') { 367 var lat = $('input[name="lat"]').val() || latLng.lat; 368 var lng = $('input[name="lng"]').val() || latLng.lng; 369 updateSearchFormMap(lat, lng); 370 } 371 } 372 }); 373 } else { 374 container.find('.radius-field').fadeOut().find('select').val(''); 375 376 container.removeClass('visible'); 377 378 if(typeof updateSearchFormMap == 'function') { 379 updateSearchFormMap($('input[name="lat"]').val(), $('input[name="lng"]').val()); 380 } 381 } 382} 383 384/** 385 * Returns a string of values from the selected checkboxes 386 * @param checkboxes - the selector for the checkbox fields 387 */ 388function getSelectedCheckboxValues(checkboxes) 389{ 390 var values = ''; 391 392 checkboxes.each(function() { 393 if(this.checked) { 394 values += $(this).val() + ','; 395 } 396 }); 397 398 // Remove trailing comma from string 399 values = values.substring(0, values.length - 1); 400 401 return values; 402} 403 404function profileTypesFilter() 405{ 406 const handle = (show) => { 407 if (show) { 408 $('.filter-types-options').animate({ 'opacity': '.2' }) 409 $('.filter-types-options input').attr('disabled', true).prop('checked', true) 410 $('.filter-types-options label').css('font-weight', 'normal') 411 412 } else { 413 $('.filter-types-options').animate({ 'opacity': '1' }) 414 $('.filter-types-options input').attr('disabled', false) 415 $('.filter-types-options label').css('font-weight', 'bold') 416 } 417 } 418 419 handle($('#show_all_profile_types').is(':checked')) 420 421 $('#show_all_profile_types').off('change').on('change', function() { 422 handle($('#show_all_profile_types').is(':checked')) 423 }) 424}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.