PageSourceSearch

https://adoddle.org/app/js/views/search/search-form.js?v245

js adoddle.org collected 2026-10-04 02:16:45 UTC 19,178 bytes, 424 lines download raw bytes

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,"&amp;").replace(/\s/g," ").replace(/</g,"&lt;").replace(/>/g,"&gt;");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("&nbsp;&nbsp;"),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.