PageSourceSearch

https://aztues.bg/app/plugins/events-manager/includes/js/events-manager.js?ver=5.981

js aztues.bg collected 2026-10-04 05:47:15 UTC 52,843 bytes, 1,152 lines download raw bytes

1jQuery(document).ready( function($){
2	var load_ui_css = false; //load jquery ui css?
3	/* Time Entry */
4	$('#start-time').each(function(i, el){
5		$(el).addClass('em-time-input em-time-start').next('#end-time').addClass('em-time-input em-time-end').parent().addClass('em-time-range');
6	});
7	if( $(".em-time-input").length > 0 ){
8		em_setup_timepicker('body');
9	}
10	/* Calendar AJAX */
11	$('.em-calendar-wrapper a').off("click");
12	$('.em-calendar-wrapper').on('click', 'a.em-calnav, a.em-calnav', function(e){
13		e.preventDefault();
14		$(this).closest('.em-calendar-wrapper').prepend('<div class="loading" id="em-loading"></div>');
15		var url = em_ajaxify($(this).attr('href'));
16		$(this).closest('.em-calendar-wrapper').load(url, function(){$(this).trigger('em_calendar_load');});
17	} );
18
19	//Events Search
20	$(document).on('click change', '.em-toggle', function(e){
21		e.preventDefault();
22		//show or hide advanced tickets, hidden by default
23		var el = $(this);
24		var rel = el.attr('rel').split(':');
25		if( el.hasClass('show-search') ){
26			if( rel.length > 1 ){ el.closest(rel[1]).find(rel[0]).slideUp(); }
27			else{ $(rel[0]).slideUp(); }
28			el.find('.show, .show-advanced').show();
29			el.find('.hide, .hide-advanced').hide();
30			el.removeClass('show-search');
31		}else{
32			if( rel.length > 1 ){ el.closest(rel[1]).find(rel[0]).slideDown(); }
33			else{ $(rel[0]).slideDown(); }
34			el.find('.show, .show-advanced').hide();
35			el.find('.hide, .hide-advanced').show();
36			el.addClass('show-search');
37		}
38		
39	});
40	if( EM.search_term_placeholder ){
41		if( 'placeholder' in document.createElement('input') ){
42			$('input.em-events-search-text, input.em-search-text').attr('placeholder', EM.search_term_placeholder);
43		}else{
44			$('input.em-events-search-text, input.em-search-text').blur(function(){
45				if( this.value=='' ) this.value = EM.search_term_placeholder;
46			}).focus(function(){
47				if( this.value == EM.search_term_placeholder ) this.value='';
48			}).trigger('blur');
49		}
50	}
51	$('.em-search-form select[name=country]').change( function(){
52		var el = $(this);
53		$('.em-search select[name=state]').html('<option value="">'+EM.txt_loading+'</option>');
54		$('.em-search select[name=region]').html('<option value="">'+EM.txt_loading+'</option>');
55		$('.em-search select[name=town]').html('<option value="">'+EM.txt_loading+'</option>');
56		if( el.val() != '' ){
57			el.closest('.em-search-location').find('.em-search-location-meta').slideDown();
58			var data = {
59				action : 'search_states',
60				country : el.val(),
61				return_html : true
62			};
63			$('.em-search select[name=state]').load( EM.ajaxurl, data );
64			data.action = 'search_regions';
65			$('.em-search select[name=region]').load( EM.ajaxurl, data );
66			data.action = 'search_towns';
67			$('.em-search select[name=town]').load( EM.ajaxurl, data );
68		}else{
69			el.closest('.em-search-location').find('.em-search-location-meta').slideUp();
70		}
71	});
72
73	$('.em-search-form select[name=region]').change( function(){
74		$('.em-search select[name=state]').html('<option value="">'+EM.txt_loading+'</option>');
75		$('.em-search select[name=town]').html('<option value="">'+EM.txt_loading+'</option>');
76		var data = {
77			action : 'search_states',
78			region : $(this).val(),
79			country : $('.em-search-form select[name=country]').val(),
80			return_html : true
81		};
82		$('.em-search select[name=state]').load( EM.ajaxurl, data );
83		data.action = 'search_towns';
84		$('.em-search select[name=town]').load( EM.ajaxurl, data );
85	});
86
87	$('.em-search-form select[name=state]').change( function(){
88		$('.em-search select[name=town]').html('<option value="">'+EM.txt_loading+'</option>');
89		var data = {
90			action : 'search_towns',
91			state : $(this).val(),
92			region : $('.em-search-form select[name=region]').val(),
93			country : $('.em-search-form select[name=country]').val(),
94			return_html : true
95		};
96		$('.em-search select[name=town]').load( EM.ajaxurl, data );
97	});
98	
99	//in order for this to work, you need the above classes to be present in your templates
100	$(document).on('submit', '.em-search-form, .em-events-search-form', function(e){
101		var form = $(this);
102    	if( this.em_search && this.em_search.value == EM.txt_search){ this.em_search.value = ''; }
103    	var results_wrapper = form.closest('.em-search-wrapper').find('.em-search-ajax');
104    	if( results_wrapper.length == 0 ) results_wrapper = $('.em-search-ajax');
105    	if( results_wrapper.length > 0 ){
106    		results_wrapper.append('<div class="loading" id="em-loading"></div>');
107    		var submitButton = form.find('.em-search-submit');
108    		submitButton.data('buttonText', submitButton.val()).val(EM.txt_searching);
109    		var img = submitButton.children('img');
110    		if( img.length > 0 ) img.attr('src', img.attr('src').replace('search-mag.png', 'search-loading.gif'));
111    		var vars = form.serialize();
112    		$.ajax( EM.ajaxurl, {
113				type : 'POST',
114	    		dataType : 'html',
115	    		data : vars,
116			    success : function(responseText){
117			    	submitButton.val(submitButton.data('buttonText'));
118			    	if( img.length > 0 ) img.attr('src', img.attr('src').replace('search-loading.gif', 'search-mag.png'));
119		    		results_wrapper.replaceWith(responseText);
120		        	if( form.find('input[name=em_search]').val() == '' ){ form.find('input[name=em_search]').val(EM.txt_search); }
121		        	//reload results_wrapper
122		        	results_wrapper = form.closest('.em-search-wrapper').find('.em-search-ajax');
123		        	if( results_wrapper.length == 0 ) results_wrapper = $('.em-search-ajax');
124			    	jQuery(document).triggerHandler('em_search_ajax', [vars, results_wrapper, e]); //ajax has loaded new results
125			    }
126	    	});
127    		e.preventDefault();
128			return false;
129    	}
130	});
131	if( $('.em-search-ajax').length > 0 ){
132		$(document).on('click', '.em-search-ajax a.page-numbers', function(e){
133			var a = $(this);
134			var data = a.closest('.em-pagination').attr('data-em-ajax');
135			var wrapper = a.closest('.em-search-ajax');
136			var wrapper_parent = wrapper.parent();
137		    var qvars = a.attr('href').split('?');
138		    var vars = qvars[1];
139		    //add data-em-ajax att if it exists
140		    if( data != '' ){
141		    	vars = vars != '' ? vars+'&'+data : data;
142		    }
143		    wrapper.append('<div class="loading" id="em-loading"></div>');
144		    $.ajax( EM.ajaxurl, {
145				type : 'POST',
146	    		dataType : 'html',
147	    		data : vars,
148			    success : function(responseText) {
149			    	wrapper.replaceWith(responseText);
150			    	wrapper = wrapper_parent.find('.em-search-ajax');
151			    	jQuery(document).triggerHandler('em_search_ajax', [vars, wrapper, e]); //ajax has loaded new results
152			    }
153	    	});
154			e.preventDefault();
155			return false;
156		});
157	}
158		
159	/*
160	 * ADMIN AREA AND PUBLIC FORMS (Still polishing this section up, note that form ids and classes may change accordingly)
161	 */
162	//Events List
163		//Approve/Reject Links
164		$('.events-table').on('click', '.em-event-delete', function(){
165			if( !confirm("Are you sure you want to delete?") ){ return false; }
166			window.location.href = this.href;
167		});
168	//Forms
169	$('#event-form #event-image-delete, #location-form #location-image-delete').on('click', function(){
170		var el = $(this);
171		if( el.is(':checked') ){
172			el.closest('.event-form-image, .location-form-image').find('#event-image-img, #location-image-img').hide();
173		}else{
174			el.closest('.event-form-image, .location-form-image').find('#event-image-img, #location-image-img').show();
175		}
176	});
177	//Event Editor 
178		//Recurrence Warnings
179		$('#event-form.em-event-admin-recurring').submit( function(event){
180			var form = $(this);
181			if( form.find('input[name="event_reschedule"]').first().val() == 1 ){
182				var warning_text = EM.event_reschedule_warning;
183			}else if( form.find('input[name="event_recreate_tickets"]').first().val() == 1 ){
184				var warning_text = EM.event_recurrence_bookings;
185			}else{
186				var warning_text = EM.event_recurrence_overwrite;
187			}
188			confirmation = confirm(warning_text);
189			if( confirmation == false ){
190				event.preventDefault();
191			}
192		});
193		//Buttons for recurrence warnings within event editor forms
194		$('.em-reschedule-trigger').click(function(e){
195			e.preventDefault();
196			var trigger = $(this);
197			trigger.closest('.em-recurrence-reschedule').find(trigger.data('target')).removeClass('reschedule-hidden');
198			trigger.siblings('.em-reschedule-value').val(1);
199			trigger.addClass('reschedule-hidden').siblings('a').removeClass('reschedule-hidden');
200		});
201		$('.em-reschedule-cancel').click(function(e){
202			e.preventDefault();
203			var trigger = $(this);
204			trigger.closest('.em-recurrence-reschedule').find(trigger.data('target')).addClass('reschedule-hidden');
205			trigger.siblings('.em-reschedule-value').val(0);
206			trigger.addClass('reschedule-hidden').siblings('a').removeClass('reschedule-hidden');
207		});
208	//Tickets & Bookings
209	if( $("#em-tickets-form").length > 0 ){
210		//Enable/Disable Bookings
211		$('#event-rsvp').click( function(event){
212			if( !this.checked ){
213				confirmation = confirm(EM.disable_bookings_warning);
214				if( confirmation == false ){
215					event.preventDefault();
216				}else{
217					$('#event-rsvp-options').hide();
218				}
219			}else{
220				$('#event-rsvp-options').fadeIn();
221			}
222		});
223		if($('input#event-rsvp').is(":checked")) {
224			$("div#rsvp-data").fadeIn();
225		} else {
226			$("div#rsvp-data").hide();
227		}
228		//Ticket(s) UI
229		var reset_ticket_forms = function(){
230			$('#em-tickets-form table tbody tr.em-tickets-row').show();
231			$('#em-tickets-form table tbody tr.em-tickets-row-form').hide();
232		};
233		//recurrences and cut-off logic for ticket availability
234		if( $('#em-recurrence-checkbox').length > 0 ){
235			$('#em-recurrence-checkbox').change(function(){
236				if( $('#em-recurrence-checkbox').is(':checked') ){
237					$('#em-tickets-form .ticket-dates-from-recurring, #em-tickets-form .ticket-dates-to-recurring, #event-rsvp-options .em-booking-date-recurring').show();
238					$('#em-tickets-form .ticket-dates-from-normal, #em-tickets-form .ticket-dates-to-normal, #event-rsvp-options .em-booking-date-normal, #em-tickets-form .hidden').hide();
239				}else{
240					$('#em-tickets-form .ticket-dates-from-normal, #em-tickets-form .ticket-dates-to-normal, #event-rsvp-options .em-booking-date-normal').show();
241					$('#em-tickets-form .ticket-dates-from-recurring, #em-tickets-form .ticket-dates-to-recurring, #event-rsvp-options .em-booking-date-recurring, #em-tickets-form .hidden').hide();
242				}
243			}).trigger('change');
244		}else if( $('#em-form-recurrence').length > 0 ){
245			$('#em-tickets-form .ticket-dates-from-recurring, #em-tickets-form .ticket-dates-to-recurring, #event-rsvp-options .em-booking-date-recurring').show();
246			$('#em-tickets-form .ticket-dates-from-normal, #em-tickets-form .ticket-dates-to-normal, #event-rsvp-options .em-booking-date-normal, #em-tickets-form .hidden').hide();
247		}else{
248			$('#em-tickets-form .ticket-dates-from-recurring, #em-tickets-form .ticket-dates-to-recurring, #event-rsvp-options .em-booking-date-recurring, #em-tickets-form .hidden').hide();
249		}
250		//Add a new ticket
251		$("#em-tickets-add").click(function(e){ 
252			e.preventDefault();
253			reset_ticket_forms();
254			//create copy of template slot, insert so ready for population
255			var tickets = $('#em-tickets-form table tbody');
256			var rowNo = tickets.length+1;
257			var slot = tickets.first('.em-ticket-template').clone(true).attr('id','em-ticket-'+ rowNo).removeClass('em-ticket-template').addClass('em-ticket').appendTo($('#em-tickets-form table'));
258			//change the index of the form element names
259			slot.find('*[name]').each( function(index,el){
260				el = $(el);
261				el.attr('name', el.attr('name').replace('em_tickets[0]','em_tickets['+rowNo+']'));
262			});
263			//show ticket and switch to editor
264			slot.show().find('.ticket-actions-edit').trigger('click');
265			//refresh datepicker and values
266			slot.find('.em-date-input-loc').datepicker('destroy').removeAttr('id'); //clear all datepickers
267			slot.find('.em-time-input').unbind().each(function(index, el){ this.timePicker = false; }); //clear all timepickers - consequently, also other click/blur/change events, recreate the further down
268			em_setup_datepicker(slot);
269			em_setup_timepicker(slot);
270		    $('html, body').animate({ scrollTop: slot.offset().top - 30 }); //sends user to form
271			check_ticket_sortability();
272		});
273		//Edit a Ticket
274		$(document).on('click', '.ticket-actions-edit', function(e){
275			e.preventDefault();
276			reset_ticket_forms();
277			var tbody = $(this).closest('tbody');
278			tbody.find('tr.em-tickets-row').hide();
279			tbody.find('tr.em-tickets-row-form').fadeIn();
280			return false;
281		});
282		$(document).on('click', '.ticket-actions-edited', function(e){
283			e.preventDefault();
284			var tbody = $(this).closest('tbody');
285			var rowNo = tbody.attr('id').replace('em-ticket-','');
286			tbody.find('.em-tickets-row').fadeIn();
287			tbody.find('.em-tickets-row-form').hide();
288			tbody.find('*[name]').each(function(index,el){
289				el = $(el);
290				if( el.attr('name') == 'ticket_start_pub'){
291					tbody.find('span.ticket_start').text(el.attr('value'));
292				}else if( el.attr('name') == 'ticket_end_pub' ){
293					tbody.find('span.ticket_end').text(el.attr('value'));
294				}else if( el.attr('name') == 'em_tickets['+rowNo+'][ticket_type]' ){
295					if( el.find(':selected').val() == 'members' ){
296						tbody.find('span.ticket_name').prepend('* ');
297					}
298				}else if( el.attr('name') == 'em_tickets['+rowNo+'][ticket_start_recurring_days]' ){
299					var text = tbody.find('select.ticket-dates-from-recurring-when').val() == 'before' ? '-'+el.attr('value'):el.attr('value');
300					if( el.attr('value') != '' ){
301						tbody.find('span.ticket_start_recurring_days').text(text);
302						tbody.find('span.ticket_start_recurring_days_text, span.ticket_start_time').removeClass('hidden').show();
303					}else{
304						tbody.find('span.ticket_start_recurring_days').text(' - ');
305						tbody.find('span.ticket_start_recurring_days_text, span.ticket_start_time').removeClass('hidden').hide();
306					}
307				}else if( el.attr('name') == 'em_tickets['+rowNo+'][ticket_end_recurring_days]' ){
308					var text = tbody.find('select.ticket-dates-to-recurring-when').val() == 'before' ? '-'+el.attr('value'):el.attr('value');
309					if( el.attr('value') != '' ){
310						tbody.find('span.ticket_end_recurring_days').text(text);
311						tbody.find('span.ticket_end_recurring_days_text, span.ticket_end_time').removeClass('hidden').show();
312					}else{
313						tbody.find('span.ticket_end_recurring_days').text(' - ');
314						tbody.find('span.ticket_end_recurring_days_text, span.ticket_end_time').removeClass('hidden').hide();
315					}
316				}else{
317					tbody.find('.'+el.attr('name').replace('em_tickets['+rowNo+'][','').replace(']','').replace('[]','')).text(el.attr('value'));
318				}
319			});
320			//allow for others to hook into this
321			$(document).triggerHandler('em_maps_tickets_edit', [tbody, rowNo, true]);
322		    $('html, body').animate({ scrollTop: tbody.parent().offset().top - 30 }); //sends user back to top of form
323			return false;
324		});
325		$(document).on('change', '.em-ticket-form select.ticket_type', function(e){
326			//check if ticket is for all users or members, if members, show roles to limit the ticket to
327			var el = $(this);
328			if( el.find('option:selected').val() == 'members' ){
329				el.closest('.em-ticket-form').find('.ticket-roles').fadeIn();
330			}else{
331				el.closest('.em-ticket-form').find('.ticket-roles').hide();
332			}
333		});
334		$(document).on('click', '.em-ticket-form .ticket-options-advanced', function(e){
335			//show or hide advanced tickets, hidden by default
336			e.preventDefault();
337			var el = $(this);
338			if( el.hasClass('show') ){
339				el.closest('.em-ticket-form').find('.em-ticket-form-advanced').fadeIn();
340				el.find('.show,.show-advanced').hide();
341				el.find('.hide,.hide-advanced').show();
342			}else{
343				el.closest('.em-ticket-form').find('.em-ticket-form-advanced').hide();
344				el.find('.show,.show-advanced').show();
345				el.find('.hide,.hide-advanced').hide();
346			}
347			el.toggleClass('show');
348		});
349		$('.em-ticket-form').each( function(){
350			//check whether to show advanced options or not by default for each ticket
351			var show_advanced = false;
352			var el = $(this); 
353			el.find('.em-ticket-form-advanced input[type="text"]').each(function(){ if(this.value != '') show_advanced = true; });
354			if( el.find('.em-ticket-form-advanced input[type="checkbox"]:checked').length > 0 ){ show_advanced = true; }
355			el.find('.em-ticket-form-advanced option:selected').each(function(){ if(this.value != '') show_advanced = true; });
356			if( show_advanced ) el.find('.ticket-options-advanced').trigger('click');
357		});
358		//Delete a ticket
359		$(document).on('click', '.ticket-actions-delete', function(e){
360			e.preventDefault();
361			var el = $(this);
362			var tbody = el.closest('tbody');
363			if( tbody.find('input.ticket_id').val() > 0 ){
364				//only will happen if no bookings made
365				el.text('Deleting...');	
366				$.getJSON( $(this).attr('href'), {'em_ajax_action':'delete_ticket', 'id':tbody.find('input.ticket_id').val()}, function(data){
367					if(data.result){
368						tbody.remove();
369					}else{
370						el.text('Delete');
371						alert(data.error);
372					}
373				});
374			}else{
375				//not saved to db yet, so just remove
376				tbody.remove();
377			}
378			check_ticket_sortability();
379			return false;
380		});
381		//Sort Tickets
382		$('#em-tickets-form.em-tickets-sortable table').sortable({
383			items: '> tbody',
384			placeholder: "em-ticket-sortable-placeholder",
385			handle:'.ticket-status',
386			helper: function( event, el ){
387				var helper = $(el).clone().addClass('em-ticket-sortable-helper');
388				var tds = helper.find('.em-tickets-row td').length;
389				helper.children().remove();
390				helper.append('<tr class="em-tickets-row"><td colspan="'+tds+'" style="text-align:left; padding-left:15px;"><span class="dashicons dashicons-tickets-alt"></span></td></tr>');
391				return helper;
392			},
393		});
394		var check_ticket_sortability = function(){
395			var em_tickets = $('#em-tickets-form table tbody.em-ticket');
396			if( em_tickets.length == 1 ){
397				em_tickets.find('.ticket-status').addClass('single');
398				$('#em-tickets-form.em-tickets-sortable table').sortable( "option", "disabled", true );
399			}else{
400				em_tickets.find('.ticket-status').removeClass('single');
401				$('#em-tickets-form.em-tickets-sortable table').sortable( "option", "disabled", false );
402			}
403		};
404		check_ticket_sortability();
405	}
406	//Manageing Bookings
407	if( $('#em-bookings-table').length > 0 ){
408		//Pagination link clicks
409		$(document).on('click', '#em-bookings-table .tablenav-pages a', function(){
410			var el = $(this);
411			var form = el.parents('#em-bookings-table form.bookings-filter');
412			//get page no from url, change page, submit form
413			var match = el.attr('href').match(/#[0-9]+/);
414			if( match != null && match.length > 0){
415				var pno = match[0].replace('#','');
416				form.find('input[name=pno]').val(pno);
417			}else{
418				form.find('input[name=pno]').val(1);
419			}
420			form.trigger('submit');
421			return false;
422		});
423		//Overlay Options
424		var em_bookings_settings_dialog = {
425			modal : true,
426			autoOpen: false,
427			minWidth: 500,
428			height: 'auto',
429			buttons: [{
430				text: EM.bookings_settings_save,
431				click: function(e){
432					e.preventDefault();
433					//we know we'll deal with cols, so wipe hidden value from main
434					var match = $("#em-bookings-table form.bookings-filter [name=cols]").val('');
435					var booking_form_cols = $('form#em-bookings-table-settings-form input.em-bookings-col-item');
436					$.each( booking_form_cols, function(i,item_match){
437						//item_match = $(item_match);
438						if( item_match.value == 1 ){
439							if( match.val() != ''){
440								match.val(match.val()+','+item_match.name);
441							}else{
442								match.val(item_match.name);
443							}
444						}
445					});
446					//submit main form
447					$('#em-bookings-table-settings').trigger('submitted'); //hook into this with bind()
448					$('#em-bookings-table form.bookings-filter').trigger('submit');					
449					$(this).dialog('close');
450				}
451			}]
452		};
453		var em_bookings_export_dialog = {
454			modal : true,
455			autoOpen: false,
456			minWidth: 500,
457			height: 'auto',
458			buttons: [{
459				text: EM.bookings_export_save,
460				click: function(e){
461					$(this).children('form').submit();
462					$(this).dialog('close');
463				}
464			}]
465		};
466		if( $("#em-bookings-table-settings").length > 0 ){
467			//Settings Overlay
468			$("#em-bookings-table-settings").dialog(em_bookings_settings_dialog);
469			$(document).on('click', '#em-bookings-table-settings-trigger', function(e){ e.preventDefault(); $("#em-bookings-table-settings").dialog('open'); });
470			//Export Overlay
471			$("#em-bookings-table-export").dialog(em_bookings_export_dialog);
472			$(document).on('click', '#em-bookings-table-export-trigger', function(e){ e.preventDefault(); $("#em-bookings-table-export").dialog('open'); });
473			var export_overlay_show_tickets = function(){
474				if( $('#em-bookings-table-export-form input[name=show_tickets]').is(':checked') ){
475					$('#em-bookings-table-export-form .em-bookings-col-item-ticket').show();
476					$('#em-bookings-table-export-form #em-bookings-export-cols-active .em-bookings-col-item-ticket input').val(1);
477				}else{
478					$('#em-bookings-table-export-form .em-bookings-col-item-ticket').hide().find('input').val(0);					
479				}
480			};
481			//Sync export overlay with table search field changes
482			$('#em-bookings-table form select').each(function(i, el){
483				$(el).change(function(e){
484					var select_el = $(this);
485					var input_par = $('#em-bookings-table-export-form input[name='+select_el.attr('name')+']');
486					var input_par_selected = select_el.find('option:selected');
487					input_par.val(input_par_selected.val());
488				});
489			});
490			
491			export_overlay_show_tickets();
492			$('#em-bookings-table-export-form input[name=show_tickets]').click(export_overlay_show_tickets);
493			//Sortables
494			$( ".em-bookings-cols-sortable" ).sortable({
495				connectWith: ".em-bookings-cols-sortable",
496				update: function(event, ui) {
497					if( ui.item.parents('ul#em-bookings-cols-active, ul#em-bookings-export-cols-active').length > 0 ){							
498						ui.item.addClass('ui-state-highlight').removeClass('ui-state-default').children('input').val(1);
499					}else{
500						ui.item.addClass('ui-state-default').removeClass('ui-state-highlight').children('input').val(0);
501					}
502				}
503			}).disableSelection();
504			load_ui_css = true;
505		}
506		//Widgets and filter submissions
507		$(document).on('submit', '#em-bookings-table form.bookings-filter', function(e){
508			var el = $(this);			
509			//append loading spinner
510			el.parents('#em-bookings-table').find('.table-wrap').first().append('<div id="em-loading" />');
511			//ajax call
512			$.post( EM.ajaxurl, el.serializeArray(), function(data){
513				var root = el.parents('#em-bookings-table').first();
514				root.replaceWith(data);
515				//recreate overlays
516				$('#em-bookings-table-export input[name=scope]').val(root.find('select[name=scope]').val());
517				$('#em-bookings-table-export input[name=status]').val(root.find('select[name=status]').val());
518				jQuery(document).triggerHandler('em_bookings_filtered', [data, root, el]);
519			});
520			return false;
521		});
522		//Approve/Reject Links
523		$(document).on('click', '.em-bookings-approve,.em-bookings-reject,.em-bookings-unapprove,.em-bookings-delete', function(){
524			var el = $(this); 
525			if( el.hasClass('em-bookings-delete') ){
526				if( !confirm(EM.booking_delete) ){ return false; }
527			}
528			var url = em_ajaxify( el.attr('href'));		
529			var td = el.parents('td').first();
530			td.html(EM.txt_loading);
531			td.load( url );
532			return false;
533		});
534	}
535	//Old Bookings Table - depreciating soon
536	if( $('.em_bookings_events_table').length > 0 ){
537		//Widgets and filter submissions
538		$(document).on('submit', '.em_bookings_events_table form', function(e){
539			var el = $(this);
540			var url = em_ajaxify( el.attr('action') );		
541			el.parents('.em_bookings_events_table').find('.table-wrap').first().append('<div id="em-loading" />');
542			$.get( url, el.serializeArray(), function(data){
543				el.parents('.em_bookings_events_table').first().replaceWith(data);
544			});
545			return false;
546		});
547		//Pagination link clicks
548		$(document).on('click', '.em_bookings_events_table .tablenav-pages a', function(){
549			var el = $(this);
550			var url = em_ajaxify( el.attr('href') );	
551			el.parents('.em_bookings_events_table').find('.table-wrap').first().append('<div id="em-loading" />');
552			$.get( url, function(data){
553				el.parents('.em_bookings_events_table').first().replaceWith(data);
554			});
555			return false;
556		});
557	}
558	
559	//Manual Booking
560	$(document).on('click', 'a.em-booking-button', function(e){
561		e.preventDefault();
562		var button = $(this);
563		if( button.text() != EM.bb_booked && $(this).text() != EM.bb_booking){
564			button.text(EM.bb_booking);
565			var button_data = button.attr('id').split('_'); 
566			$.ajax({
567				url: EM.ajaxurl,
568				dataType: 'jsonp',
569				data: {
570					event_id : button_data[1],
571					_wpnonce : button_data[2],
572					action : 'booking_add_one'
573				},
574				success : function(response, statusText, xhr, $form) {
575					if(response.result){
576						button.text(EM.bb_booked);
577					}else{
578						button.text(EM.bb_error);					
579					}
580					if(response.message != '') alert(response.message);
581				},
582				error : function(){ button.text(EM.bb_error); }
583			});
584		}
585		return false;
586	});	
587	$(document).on('click', 'a.em-cancel-button', function(e){
588		e.preventDefault();
589		var button = $(this);
590		if( button.text() != EM.bb_cancelled && button.text() != EM.bb_canceling){
591			button.text(EM.bb_canceling);
592			var button_data = button.attr('id').split('_'); 
593			$.ajax({
594				url: EM.ajaxurl,
595				dataType: 'jsonp',
596				data: {
597					booking_id : button_data[1],
598					_wpnonce : button_data[2],
599					action : 'booking_cancel'
600				},
601				success : function(response, statusText, xhr, $form) {
602					if(response.result){
603						button.text(EM.bb_cancelled);
604					}else{
605						button.text(EM.bb_cancel_error);
606					}
607				},
608				error : function(){ button.text(EM.bb_cancel_error); }
609			});
610		}
611		return false;
612	});  
613
614	//Datepicker
615	if( $('.em-date-single, .em-date-range, #em-date-start').length > 0 ){
616		load_ui_css = true;
617		em_setup_datepicker('body');
618	}
619	if( load_ui_css ) em_load_jquery_css();
620	
621	//previously in em-admin.php
622	function updateIntervalDescriptor () { 
623		$(".interval-desc").hide();
624		var number = "-plural";
625		if ($('input#recurrence-interval').val() == 1 || $('input#recurrence-interval').val() == "")
626		number = "-singular";
627		var descriptor = "span#interval-"+$("select#recurrence-frequency").val()+number;
628		$(descriptor).show();
629	}
630	function updateIntervalSelectors () {
631		$('p.alternate-selector').hide();   
632		$('p#'+ $('select#recurrence-frequency').val() + "-selector").show();
633	}
634	function updateShowHideRecurrence () {
635		if( $('input#event-recurrence').is(":checked")) {
636			$("#event_recurrence_pattern").fadeIn();
637			$("#event-date-explanation").hide();
638			$("#recurrence-dates-explanation").show();
639			$("h3#recurrence-dates-title").show();
640			$("h3#event-date-title").hide();     
641		} else {
642			$("#event_recurrence_pattern").hide();
643			$("#recurrence-dates-explanation").hide();
644			$("#event-date-explanation").show();
645			$("h3#recurrence-dates-title").hide();
646			$("h3#event-date-title").show();   
647		}
648	}		 
649	$("#recurrence-dates-explanation").hide();
650	$("#date-to-submit").hide();
651	$("#end-date-to-submit").hide();
652	
653	$("#localised-date").show();
654	$("#localised-end-date").show();
655	
656	$('#em-wrapper input.select-all').change(function(){
657	 	if($(this).is(':checked')){
658			$('input.row-selector').prop('checked', true);
659			$('input.select-all').prop('checked', true);
660	 	}else{
661			$('input.row-selector').prop('checked', false);
662			$('input.select-all').prop('checked', false);
663		}
664	}); 
665	
666	updateIntervalDescriptor(); 
667	updateIntervalSelectors();
668	updateShowHideRecurrence();
669	$('input#event-recurrence').change(updateShowHideRecurrence);
670	   
671	// recurrency elements   
672	$('input#recurrence-interval').keyup(updateIntervalDescriptor);
673	$('select#recurrence-frequency').change(updateIntervalDescriptor);
674	$('select#recurrence-frequency').change(updateIntervalSelectors);
675
676	/* Load any maps */	
677	if( $('.em-location-map').length > 0 || $('.em-locations-map').length > 0 || $('#em-map').length > 0 || $('.em-search-geo').length > 0 ){
678		em_maps_load();
679	}
680	
681	//Finally, add autocomplete here
682	//Autocomplete
683	if( jQuery( "div.em-location-data input#location-name" ).length > 0 ){
684		jQuery( "div.em-location-data input#location-name" ).autocomplete({
685			source: EM.locationajaxurl,
686			minLength: 2,
687			focus: function( event, ui ){
688				jQuery("input#location-id" ).val( ui.item.value );
689				return false;
690			},			 
691			select: function( event, ui ){
692				jQuery("input#location-id" ).val(ui.item.id).trigger('change');
693				jQuery("input#location-name" ).val(ui.item.value);
694				jQuery('input#location-address').val(ui.item.address);
695				jQuery('input#location-town').val(ui.item.town);
696				jQuery('input#location-state').val(ui.item.state);
697				jQuery('input#location-region').val(ui.item.region);
698				jQuery('input#location-postcode').val(ui.item.postcode);
699				jQuery('input#location-latitude').val(ui.item.latitude);
700				jQuery('input#location-longitude').val(ui.item.longitude);
701				if( ui.item.country == '' ){
702					jQuery('select#location-country option:selected').removeAttr('selected');
703				}else{
704					jQuery('select#location-country option[value="'+ui.item.country+'"]').attr('selected', 'selected');
705				}
706				jQuery('div.em-location-data input').css('background-color','#ccc').prop('readonly', true);
707				jQuery('div.em-location-data select').css('background-color','#ccc').css('color', '#666666').prop('disabled', true);
708				jQuery('#em-location-reset').show();
709				jQuery('#em-location-search-tip').hide();
710				jQuery(document).triggerHandler('em_locations_autocomplete_selected', [event, ui]);
711				return false;
712			}
713		}).data( "ui-autocomplete" )._renderItem = function( ul, item ) {
714			html_val = "<a>" + em_esc_attr(item.label) + '<br><span style="font-size:11px"><em>'+ em_esc_attr(item.address) + ', ' + em_esc_attr(item.town)+"</em></span></a>";
715			return jQuery( "<li></li>" ).data( "item.autocomplete", item ).append(html_val).appendTo( ul );
716		};
717		jQuery('#em-location-reset a').click( function(){
718			jQuery('div.em-location-data input').css('background-color','#fff').val('').prop('readonly', false);
719			jQuery('div.em-location-data select').css('background-color','#fff').css('color', 'auto').prop('disabled', false);
720			jQuery('div.em-location-data option:selected').removeAttr('selected');
721			jQuery('input#location-id').val('');
722			jQuery('#em-location-reset').hide();
723			jQuery('#em-location-search-tip').show();
724			jQuery('#em-map').hide();
725			jQuery('#em-map-404').show();
726			if(typeof(marker) !== 'undefined'){
727				marker.setPosition(new google.maps.LatLng(0, 0));
728				infoWindow.close();
729				marker.setDraggable(true);
730			}
731			return false;
732		});
733		if( jQuery('input#location-id').val() != '0' && jQuery('input#location-id').val() != '' ){
734			jQuery('div.em-location-data input').css('background-color','#ccc').prop('readonly', true);
735			jQuery('div.em-location-data select').css('background-color','#ccc').css('color', '#666666').prop('disabled', true);
736			jQuery('#em-location-reset').show();
737			jQuery('#em-location-search-tip').hide();
738		}
739	}
740	jQuery(document).triggerHandler('em_javascript_loaded');
741});
742
743function em_load_jquery_css(){
744	if( EM.ui_css && jQuery('link#jquery-ui-css').length == 0 ){
745		var script = document.createElement("link");
746		script.id = 'jquery-ui-css';
747		script.rel = "stylesheet";
748		script.href = EM.ui_css;
749		document.body.appendChild(script);
750	}
751}
752
753function em_setup_datepicker(wrap){	
754	wrap = jQuery(wrap);
755	//default picker vals
756	var datepicker_vals = { altFormat: "yy-mm-dd", changeMonth: true, changeYear: true, firstDay : EM.firstDay, yearRange:'c-100:c+15' };
757	if( EM.dateFormat ) datepicker_vals.dateFormat = EM.dateFormat;
758	if( EM.yearRange ) datepicker_vals.yearRange = EM.yearRange;
759	jQuery(document).triggerHandler('em_datepicker', datepicker_vals);
760	
761	//apply datepickers
762	dateDivs = wrap.find('.em-date-single, .em-date-range');
763	if( dateDivs.length > 0 ){
764		//apply datepickers to elements
765		dateDivs.find('input.em-date-input-loc').each(function(i,dateInput){
766			//init the datepicker
767			var dateInput = jQuery(dateInput);
768			var dateValue = dateInput.nextAll('input.em-date-input').first();
769			var dateValue_value = dateValue.val();
770			dateInput.datepicker(datepicker_vals);
771			dateInput.datepicker('option', 'altField', dateValue);
772			//now set the value
773			if( dateValue_value ){
774				var this_date_formatted = jQuery.datepicker.formatDate( EM.dateFormat, jQuery.datepicker.parseDate('yy-mm-dd', dateValue_value) );
775				dateInput.val(this_date_formatted);
776				dateValue.val(dateValue_value);
777			}
778			//add logic for texts
779			dateInput.change(function(){
780				if( jQuery(this).val() == '' ){
781					jQuery(this).nextAll('.em-date-input').first().val('');
782				}
783			});
784		});
785		//deal with date ranges
786		dateDivs.filter('.em-date-range').find('input.em-date-input-loc').each(function(i,dateInput){
787			//finally, apply start/end logic to this field
788			dateInput = jQuery(dateInput);
789			if( dateInput.hasClass('em-date-start') ){
790				dateInput.datepicker('option','onSelect', function( selectedDate ) {
791					//get corresponding end date input, we expect ranges to be contained in .em-date-range with a start/end input element
792					var startDate = jQuery(this);
793					var endDate = startDate.parents('.em-date-range').find('.em-date-end').first();
794					var startValue = startDate.nextAll('input.em-date-input').first().val();
795					var endValue = endDate.nextAll('input.em-date-input').first().val();
796					if( startValue > endValue && endValue != '' ){
797						endDate.datepicker( "setDate" , selectedDate );
798						endDate.trigger('change');
799					}
800					endDate.datepicker( "option", 'minDate', selectedDate );
801				});
802			}else if( dateInput.hasClass('em-date-end') ){
803				var startInput = dateInput.parents('.em-date-range').find('.em-date-start').first();
804				if( startInput.val() != '' ){
805					dateInput.datepicker('option', 'minDate', startInput.val());
806				}
807			}
808		});
809	}
810}
811
812function em_setup_timepicker(wrap){
813	wrap = jQuery(wrap);
814	var timepicker_options = {
815		show24Hours: EM.show24hours == 1,
816		step:15
817	}
818	jQuery(document).triggerHandler('em_timepicker_options', timepicker_options);
819	wrap.find(".em-time-input").timePicker(timepicker_options);
820	
821	// Keep the duration between the two inputs.
822	wrap.find(".em-time-range input.em-time-start").each( function(i, el){
823		jQuery(el).data('oldTime', jQuery.timePicker(el).getTime());
824	}).change( function() {
825		var start = jQuery(this);
826		var end = start.nextAll('.em-time-end');
827		if (end.val()) { // Only update when second input has a value.
828		    // Calculate duration.
829			var oldTime = start.data('oldTime');
830		    var duration = (jQuery.timePicker(end).getTime() - oldTime);
831		    var time = jQuery.timePicker(start).getTime();
832		    if( jQuery.timePicker(end).getTime() >= oldTime ){
833			    // Calculate and update the time in the second input.
834			    jQuery.timePicker(end).setTime(new Date(new Date(time.getTime() + duration)));
835			}
836		    start.data('oldTime', time); 
837		}
838	});
839	// Validate.
840	wrap.find(".em-time-range input.em-time-end").change(function() {
841		var end = jQuery(this);
842		var start = end.prevAll('.em-time-start');
843		if( start.val() ){
844			if( jQuery.timePicker(start).getTime() > jQuery.timePicker(this).getTime() && ( jQuery('.em-date-end').val().length == 0 || jQuery('.em-date-start').val() == jQuery('.em-date-end').val() ) ) { end.addClass("error"); }
845			else { end.removeClass("error"); }
846		}
847	});
848	//Sort out all day checkbox
849	wrap.find('.em-time-range input.em-time-all-day').change(function(){
850		var allday = jQuery(this);
851		if( allday.is(':checked') ){
852			allday.siblings('.em-time-input').css('background-color','#ccc');
853		}else{
854			allday.siblings('.em-time-input').css('background-color','#fff');
855		}
856	}).trigger('change');
857}
858
859/* Useful function for adding the em_ajax flag to a url, regardless of querystring format */
860var em_ajaxify = function(url){
861	if ( url.search('em_ajax=0') != -1){
862		url = url.replace('em_ajax=0','em_ajax=1');
863	}else if( url.search(/\?/) != -1 ){
864		url = url + "&em_ajax=1";
865	}else{
866		url = url + "?em_ajax=1";
867	}
868	return url;
869};
870
871/*
872 * MAP FUNCTIONS
873 */
874var em_maps_loaded = false;
875var maps = {};
876var maps_markers = {};
877var infoWindow;
878//loads maps script if not already loaded and executes EM maps script
879function em_maps_load(){
880	if( !em_maps_loaded ){
881		if ( jQuery('script#google-maps').length == 0 && ( typeof google !== 'object' || typeof google.maps !== 'object' ) ){ 
882			var script = document.createElement("script");
883			script.type = "text/javascript";
884			script.id = "google-maps";
885			var proto = (EM.is_ssl) ? 'https:' : 'http:';
886			if( typeof EM.google_maps_api !== 'undefined' ){
887				script.src = proto + '//maps.google.com/maps/api/js?v=quarterly&libraries=places&callback=em_maps&key='+EM.google_maps_api;
888			}else{
889				script.src = proto + '//maps.google.com/maps/api/js?v=quarterly&libraries=places&callback=em_maps';
890			}
891			document.body.appendChild(script);
892		}else if( typeof google === 'object' && typeof google.maps === 'object' && !em_maps_loaded ){
893			em_maps();
894		}else if( jQuery('script#google-maps').length > 0 ){
895			jQuery(window).load(function(){ if( !em_maps_loaded ) em_maps(); }); //google isn't loaded so wait for page to load resources
896		}
897	}
898}
899//re-usable function to load global location maps
900function em_maps_load_locations(el){
901	var el = jQuery(el);
902	var map_id = el.attr('id').replace('em-locations-map-','');
903	var em_data = jQuery.parseJSON( el.nextAll('.em-locations-map-coords').first().text() );
904	if( em_data == null ){
905		var em_data = jQuery.parseJSON( jQuery('#em-locations-map-coords-'+map_id).text() );
906	}
907	jQuery.getJSON(document.URL, em_data , function(data){
908		if(data.length > 0){
909			//define default options and allow option for extension via event triggers
910			  var map_options = { mapTypeId: google.maps.MapTypeId.ROADMAP };
911			  if( typeof EM.google_map_id_styles == 'object' && typeof EM.google_map_id_styles[map_id] !== 'undefined' ){ console.log(EM.google_map_id_styles[map_id]); map_options.styles = EM.google_map_id_styles[map_id]; }
912			  else if( typeof EM.google_maps_styles !== 'undefined' ){ map_options.styles = EM.google_maps_styles; }
913			  jQuery(document).triggerHandler('em_maps_locations_map_options', map_options);
914			  var marker_options = {};
915			  jQuery(document).triggerHandler('em_maps_location_marker_options', marker_options);
916			  
917			  maps[map_id] = new google.maps.Map(el[0], map_options);
918			  maps_markers[map_id] = [];
919
920			  var bounds = new google.maps.LatLngBounds();
921			  
922			  jQuery.map( data, function( location, i ){
923				  if( !(location.location_latitude == 0 && location.location_longitude == 0) ){
924					var latitude = parseFloat( location.location_latitude );
925					var longitude = parseFloat( location.location_longitude );
926					var location_position = new google.maps.LatLng( latitude, longitude );
927					//extend the default marker options
928					jQuery.extend(marker_options, {
929					    position: location_position, 
930					    map: maps[map_id]
931					})
932					var marker = new google.maps.Marker(marker_options);
933					maps_markers[map_id].push(marker);
934					marker.setTitle(location.location_name);
935					var myContent = '<div class="em-map-balloon"><div id="em-map-balloon-'+map_id+'" class="em-map-balloon-content">'+ location.location_balloon +'</div></div>';
936					em_map_infobox(marker, myContent, maps[map_id]);
937					//extend bounds
938					bounds.extend(new google.maps.LatLng(latitude,longitude))
939				  }
940			  });
941			  // Zoom in to the bounds
942			  maps[map_id].fitBounds(bounds);
943			  
944			//Call a hook if exists
945			jQuery(document).triggerHandler('em_maps_locations_hook', [maps[map_id], data, map_id, maps_markers[map_id]]);
946		}else{
947			el.children().first().html('No locations found');
948			jQuery(document).triggerHandler('em_maps_locations_hook_not_found', [el]);
949		}
950	});
951}
952function em_maps_load_location(el){
953	el = jQuery(el);
954	var map_id = el.attr('id').replace('em-location-map-','');
955	em_LatLng = new google.maps.LatLng( jQuery('#em-location-map-coords-'+map_id+' .lat').text(), jQuery('#em-location-map-coords-'+map_id+' .lng').text());
956	//extend map and markers via event triggers
957	var map_options = {
958	    zoom: 14,
959	    center: em_LatLng,
960	    mapTypeId: google.maps.MapTypeId.ROADMAP,
961	    mapTypeControl: false,
962	    gestureHandling: 'cooperative'
963	};
964	if( typeof EM.google_map_id_styles == 'object' && typeof EM.google_map_id_styles[map_id] !== 'undefined' ){ console.log(EM.google_map_id_styles[map_id]); map_options.styles = EM.google_map_id_styles[map_id]; }
965	else if( typeof EM.google_maps_styles !== 'undefined' ){ map_options.styles = EM.google_maps_styles; }
966	jQuery(document).triggerHandler('em_maps_location_map_options', map_options);
967	maps[map_id] = new google.maps.Map( document.getElementById('em-location-map-'+map_id), map_options);
968	var marker_options = {
969	    position: em_LatLng,
970	    map: maps[map_id]
971	};
972	jQuery(document).triggerHandler('em_maps_location_marker_options', marker_options);
973	maps_markers[map_id] = new google.maps.Marker(marker_options);
974	infoWindow = new google.maps.InfoWindow({ content: jQuery('#em-location-map-info-'+map_id+' .em-map-balloon').get(0) });
975	infoWindow.open(maps[map_id],maps_markers[map_id]);
976	maps[map_id].panBy(40,-70);
977	
978	//JS Hook for handling map after instantiation
979	//Example hook, which you can add elsewhere in your theme's JS - jQuery(document).bind('em_maps_location_hook', function(){ alert('hi');} );
980	jQuery(document).triggerHandler('em_maps_location_hook', [maps[map_id], infoWindow, maps_markers[map_id], map_id]);
981	//map resize listener
982	jQuery(window).on('resize', function(e) {
983		google.maps.event.trigger(maps[map_id], "resize");
984		maps[map_id].setCenter(maps_markers[map_id].getPosition());
985		maps[map_id].panBy(40,-70);
986	});
987}
988jQuery(document).bind('em_search_ajax', function(e, vars, wrapper){
989	if( em_maps_loaded ){
990		wrapper.find('.em-location-map').each( function(index, el){ em_maps_load_location(el); } );
991		wrapper.find('.em-locations-map').each( function(index, el){ em_maps_load_locations(el); });
992	}
993});
994//Load single maps (each map is treated as a seperate map).
995function em_maps() {
996	//Find all the maps on this page and load them
997	jQuery('.em-location-map').each( function(index, el){ em_maps_load_location(el); } );	
998	jQuery('.em-locations-map').each( function(index, el){ em_maps_load_locations(el); } );
999	
1000	//Location stuff - only needed if inputs for location exist
1001	if( jQuery('select#location-select-id, input#location-address').length > 0 ){
1002		var map, marker;
1003		//load map info
1004		var refresh_map_location = function(){
1005			var location_latitude = jQuery('#location-latitude').val();
1006			var location_longitude = jQuery('#location-longitude').val();
1007			if( !(location_latitude == 0 && location_longitude == 0) ){
1008				var position = new google.maps.LatLng(location_latitude, location_longitude); //the location coords
1009				marker.setPosition(position);
1010				var mapTitle = (jQuery('input#location-name').length > 0) ? jQuery('input#location-name').val():jQuery('input#title').val();
1011				mapTitle = em_esc_attr(mapTitle);
1012				marker.setTitle( mapTitle );
1013				jQuery('#em-map').show();
1014				jQuery('#em-map-404').hide();
1015				google.maps.event.trigger(map, 'resize');
1016				map.setCenter(position);
1017				map.panBy(40,-55);
1018				infoWindow.setContent( 
1019					'<div id="location-balloon-content"><strong>' + mapTitle + '</strong><br>' + 
1020					em_esc_attr(jQuery('#location-address').val()) + 
1021					'<br>' + em_esc_attr(jQuery('#location-town').val()) + 
1022					'</div>'
1023				);
1024				infoWindow.open(map, marker);
1025				jQuery(document).triggerHandler('em_maps_location_hook', [map, infoWindow, marker, 0]);
1026			} else {
1027    			jQuery('#em-map').hide();
1028    			jQuery('#em-map-404').show();
1029			}
1030		};
1031		
1032		//Add listeners for changes to address
1033		var get_map_by_id = function(id){
1034			if(jQuery('#em-map').length > 0){
1035				jQuery.getJSON(document.URL,{ em_ajax_action:'get_location', id:id }, function(data){
1036					if( data.location_latitude!=0 && data.location_longitude!=0 ){
1037						loc_latlng = new google.maps.LatLng(data.location_latitude, data.location_longitude);
1038						marker.setPosition(loc_latlng);
1039						marker.setTitle( data.location_name );
1040						marker.setDraggable(false);
1041						jQuery('#em-map').show();
1042						jQuery('#em-map-404').hide();
1043						map.setCenter(loc_latlng);
1044						map.panBy(40,-55);
1045						infoWindow.setContent( '<div id="location-balloon-content">'+ data.location_balloon +'</div>');
1046						infoWindow.open(map, marker);
1047						google.maps.event.trigger(map, 'resize');
1048						jQuery(document).triggerHandler('em_maps_location_hook', [map, infoWindow, marker, 0]);
1049					}else{
1050						jQuery('#em-map').hide();
1051						jQuery('#em-map-404').show();
1052					}
1053				});
1054			}
1055		};
1056		jQuery('#location-select-id, input#location-id').change( function(){get_map_by_id(jQuery(this).val());} );
1057		jQuery('#location-name, #location-town, #location-address, #location-state, #location-postcode, #location-country').change( function(){
1058			//build address
1059			if( jQuery(this).prop('readonly') === true ) return;
1060			var addresses = [ jQuery('#location-address').val(), jQuery('#location-town').val(), jQuery('#location-state').val(), jQuery('#location-postcode').val() ];
1061			var address = '';
1062			jQuery.each( addresses, function(i, val){
1063				if( val != '' ){
1064					address = ( address == '' ) ? address+val:address+', '+val;
1065				}
1066			});
1067			if( address == '' ){ //in case only name is entered, no address
1068				jQuery('#em-map').hide();
1069				jQuery('#em-map-404').show();
1070				return false;
1071			}
1072			//do country last, as it's using the text version
1073			if( jQuery('#location-country option:selected').val() != 0 ){
1074				address = ( address == '' ) ? address+jQuery('#location-country option:selected').text():address+', '+jQuery('#location-country option:selected').text();
1075			}
1076			if( address != '' && jQuery('#em-map').length > 0 ){
1077				geocoder.geocode( { 'address': address }, function(results, status) {
1078				    if (status == google.maps.GeocoderStatus.OK) {
1079						jQuery('#location-latitude').val(results[0].geometry.location.lat());
1080						jQuery('#location-longitude').val(results[0].geometry.location.lng());
1081					}
1082				    refresh_map_location();
1083				});
1084			}
1085		});
1086		
1087		//Load map
1088		if(jQuery('#em-map').length > 0){
1089			var em_LatLng = new google.maps.LatLng(0, 0);
1090			var map_options = {
1091				    zoom: 14,
1092				    center: em_LatLng,
1093				    mapTypeId: google.maps.MapTypeId.ROADMAP,
1094				    mapTypeControl: false,
1095				    gestureHandling: 'cooperative'
1096			};
1097			if( typeof EM.google_maps_styles !== 'undefined' ){ map_options.styles = EM.google_maps_styles; }
1098			map = new google.maps.Map( document.getElementById('em-map'), map_options);
1099			var marker = new google.maps.Marker({
1100			    position: em_LatLng,
1101			    map: map,
1102			    draggable: true
1103			});
1104			infoWindow = new google.maps.InfoWindow({
1105			    content: ''
1106			});
1107			var geocoder = new google.maps.Geocoder();
1108			google.maps.event.addListener(infoWindow, 'domready', function() { 
1109				document.getElementById('location-balloon-content').parentNode.style.overflow=''; 
1110				document.getElementById('location-balloon-content').parentNode.parentNode.style.overflow=''; 
1111			});
1112			google.maps.event.addListener(marker, 'dragend', function() {
1113				var position = marker.getPosition();
1114				jQuery('#location-latitude').val(position.lat());
1115				jQuery('#location-longitude').val(position.lng());
1116				map.setCenter(position);
1117				map.panBy(40,-55);
1118			});
1119			if( jQuery('#location-select-id').length > 0 ){
1120				jQuery('#location-select-id').trigger('change');
1121			}else{
1122				refresh_map_location();
1123			}
1124			jQuery(document).triggerHandler('em_map_loaded', [map, infoWindow, marker]);
1125		}
1126		//map resize listener
1127		jQuery(window).on('resize', function(e) {
1128			google.maps.event.trigger(map, "resize");
1129			map.setCenter(marker.getPosition());
1130			map.panBy(40,-55);
1131		});
1132	}
1133	em_maps_loaded = true; //maps have been loaded
1134	jQuery(document).triggerHandler('em_maps_loaded');
1135}
1136  
1137function em_map_infobox(marker, message, map) {
1138  var iw = new google.maps.InfoWindow({ content: message });
1139  google.maps.event.addListener(marker, 'click', function() {
1140	if( infoWindow ) infoWindow.close();
1141	infoWindow = iw;
1142    iw.open(map,marker);
1143  });
1144}
1145
1146function em_esc_attr( str ){
1147	if( typeof str !== 'string' ) return '';
1148	return str.replace(/</gi,'&lt;').replace(/>/gi,'&gt;');
1149}
1150
1151/* jQuery timePicker - http://labs.perifer.se/timedatepicker/ @ http://github.com/perifer/timePicker commit 100644 */
1152(function(e){function t(t,n,r,i){t.value=e(n).text();e(t).change();if(!navigator.userAgent.match(/msie/i)){t.focus()}r.hide()}function n(e,t){var n=e.getHours();var i=t.show24Hours?n:(n+11)%12+1;var s=e.getMinutes();return r(i)+t.separator+r(s)+(t.show24Hours?"":n<12?" AM":" PM")}function r(e){return(e<10?"0":"")+e}function i(e,t){return typeof e=="object"?o(e):s(e,t)}function s(e,t){if(e){var n=e.split(t.separator);var r=parseFloat(n[0]);var i=parseFloat(n[1]);if(!t.show24Hours){if(r===12&&e.indexOf("AM")!==-1){r=0}else if(r!==12&&e.indexOf("PM")!==-1){r+=12}}var s=new Date(0,0,0,r,i,0);return o(s)}return null}function o(e){e.setFullYear(2001);e.setMonth(0);e.setDate(0);return e}e.fn.timePicker=function(t){var n=e.extend({},e.fn.timePicker.defaults,t);return this.each(function(){e.timePicker(this,n)})};e.timePicker=function(t,n){var r=e(t)[0];return r.timePicker||(r.timePicker=new jQuery._timePicker(r,n))};e.timePicker.version="0.3";e._timePicker=function(r,u){var a=false;var f=false;var l=i(u.startTime,u);var c=i(u.endTime,u);var h="selected";var p="li."+h;e(r).attr("autocomplete","OFF");var d=[];var v=new Date(l);while(v<=c){d[d.length]=n(v,u);v=new Date(v.setMinutes(v.getMinutes()+u.step))}var m=e('<div class="time-picker'+(u.show24Hours?"":" time-picker-12hours")+'"></div>');var g=e("<ul></ul>");for(var y=0;y<d.length;y++){g.append("<li>"+d[y]+"</li>")}m.append(g);m.appendTo("body").hide();m.mouseover(function(){a=true}).mouseout(function(){a=false});e("li",g).mouseover(function(){if(!f){e(p,m).removeClass(h);e(this).addClass(h)}}).mousedown(function(){a=true}).click(function(){t(r,this,m,u);a=false});var b=function(){if(m.is(":visible")){return false}e("li",m).removeClass(h);var t=e(r).offset();m.css({top:t.top+r.offsetHeight,left:t.left});m.show();var i=r.value?s(r.value,u):l;var a=l.getHours()*60+l.getMinutes();var f=i.getHours()*60+i.getMinutes()-a;var p=Math.round(f/u.step);var d=o(new Date(0,0,0,0,p*u.step+a,0));d=l<d&&d<=c?d:l;var v=e("li:contains("+n(d,u)+")",m);if(v.length){v.addClass(h);m[0].scrollTop=v[0].offsetTop}return true};e(r).focus(b).click(b);e(r).blur(function(){if(!a){m.hide()}});e(r)["keydown"](function(n){var i;f=true;var s=m[0].scrollTop;switch(n.keyCode){case 38:if(b()){return false}i=e(p,g);var o=i.prev().addClass(h)[0];if(o){i.removeClass(h);if(o.offsetTop<s){m[0].scrollTop=s-o.offsetHeight}}else{i.removeClass(h);o=e("li:last",g).addClass(h)[0];m[0].scrollTop=o.offsetTop-o.offsetHeight}return false;break;case 40:if(b()){return false}i=e(p,g);var a=i.next().addClass(h)[0];if(a){i.removeClass(h);if(a.offsetTop+a.offsetHeight>s+m[0].offsetHeight){m[0].scrollTop=s+a.offsetHeight}}else{i.removeClass(h);a=e("li:first",g).addClass(h)[0];m[0].scrollTop=0}return false;break;case 13:if(m.is(":visible")){var l=e(p,g)[0];t(r,l,m,u)}return false;break;case 27:m.hide();return false;break}return true});e(r).keyup(function(e){f=false});this.getTime=function(){return s(r.value,u)};this.setTime=function(t){r.value=n(i(t,u),u);e(r).change()}};e.fn.timePicker.defaults={step:30,startTime:new Date(0,0,0,0,0,0),endTime:new Date(0,0,0,23,30,0),separator:":",show24Hours:true}})(jQuery)

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.