igmoweb
2/26/2015 - 1:32 PM

locations.js

locations.js

jQuery(document).ready(function($) {

	window.CalendarPlusAdmin = {
		
		models: {},
 		views: {},
		collections: {}, 

		/*****************************************************************/
		/**                        HELPERS 								**/
		/*****************************************************************/
		helpers: {
			/**
			 * Load a Backbone template from the HTML code
			 * @param  string id HTML ID attribute
			 * @return object    Underscore Template object
			 */
			template: function( id ) {
				return _.template( document.getElementById(id).innerHTML );
			},

			/**
			 * Set a new selected location in Location Meta box
			 * @param object model CalendarPlusAdmin.models.EventLocation Model
			 */
			setSelectedLocation: function( model ) {
				if ( ! model.toJSON().id )
					return;

				var selectedLocationView = new CalendarPlusAdmin.views.SelectedLocation({ model: model });
				$('#selected-location')
					.html('')
					.hide()
					.append( selectedLocationView.render().el )
					.fadeIn();

			}
		}// End helpers
	};

	/*****************************************************************/
	/**                SINGLE LOCATION 	 							**/
	/*****************************************************************/
	/**
	 * The model of a single Location
	 */
	CalendarPlusAdmin.models.EventLocation = Backbone.Model.extend({
		defaults: {
			id: 0,
			excerpt: '',
			thumbnail: '',
			title: ''
		}
	});

	/*****************************************************************/
	/**                LOCATION SEARCHER 							**/
	/*****************************************************************/

	//---- MODELS
	/**
	 * The model for the search box
	 */
	CalendarPlusAdmin.models.LocationSearcher = Backbone.Model.extend({
		defaults: {
			searchString: ''
		}
	});

	//---- COLLECTIONS
	/**
	 * Collection for the Search Results
	 */
	CalendarPlusAdmin.collections.searchResults = Backbone.Collection.extend({
		model: CalendarPlusAdmin.models.EventLocation
	});

	//---- VIEWS
	/**
	 * View for CalendarPlusAdmin.models.LocationSearcher Model
	 */
	CalendarPlusAdmin.views.LocationSearcher = Backbone.View.extend({
		searching:false,
		xhr: false,
		searchTimer: false,
		selectedView:false,
		$spinner: false,
		$locationResultsWrapper: false,
		$searchInput: false,

		events: {
			'keyup #location-search-string': 'preSearchLocation',
			'click #location-search-close': 'cleanSearchBox'
		},

		template: CalendarPlusAdmin.helpers.template( 'location-search-template' ),

		render: function() {
			this.$el.html( this.template( this.model.toJSON() ) );

			// Cache the spinner element
			var spinner = this.$el.find( '.spinner' );
			this.$spinner = spinner.length ? spinner : false;

			// Cache the results container element
			var resultsWrapper = this.$el.find( '#location-results' );
			this.$resultsWrapper = resultsWrapper.length ? resultsWrapper : false;

			// Cache the search input element
			var searchInput = this.$el.find( '#location-search-string' );
			this.$searchInput = searchInput.length ? searchInput : false;

			return this;
		},
		preSearchLocation: function() {
			this.initTimer();
		},
		searchLocation: function() {
			var model = this.model;
			var self = this;

			model.set( 'searchString', this.$searchInput.val() );

			// Abort the previous ajax call if is still in process
			if ( typeof self.xhr.abort === 'function' )
				self.xhr.abort();

			// Do not seach if we are currently searching.
			// The search needs to be more than 2 characters
			if ( ! self.searching && model.get( 'searchString' ).length > 2 ) {
				
				// Show the spinner gif
				if ( this.$spinner )
					this.$spinner.show();

				// We are now searching
				self.searching = true;

				// AJAX Call!
				self.xhr = $.ajax({
					url: CalendarPlusi18n.ajaxurl,
					data: {
						action: 'search_event_location',
						s: model.get( 'searchString' )
					},
				})
				.done(function( results) {
					// Create the new collection and view
					var searchResultsCollection = new CalendarPlusAdmin.collections.searchResults( results );
					var searchResults = new CalendarPlusAdmin.views.searchResults({collection: searchResultsCollection});

					self.displayResults( searchResults );				
				})
				.always(function() {
					if ( self.$spinner )
						self.$spinner.hide();
					self.searching = false;
				});
			}
		},
		initTimer: function() {
			var self = this;
			window.clearTimeout( this.searchTimer );
			this.searchTimer = window.setTimeout( function() { self.searchLocation() }, 1000 );
		},
		cleanSearchBox: function() {
			this.$searchInput.val( '' );
			this.model.set( 'searchString', '' );
			this.$resultsWrapper.slideUp();
			this.$resultsWrapper.html( '' );
		},
		cleanSearch: function() {
			this.$resultsWrapper.fadeOut();
			this.$resultsWrapper.html( '' );
		},
		/**
		 * Display the search results
		 * 
		 * @param  Collection results searchResults Collection
		 */
		displayResults: function( results ) {
			this.cleanSearch();			
			this.$resultsWrapper.append( results.render().el );
			this.$resultsWrapper.slideDown();
		}
	});
	
	/**
	 * View for CalendarPlusAdmin.models.EventLocation Model
	 */
	CalendarPlusAdmin.views.SearchResult = Backbone.View.extend({
		tagName: 'li',
		events: {
			'click .location-result': 'selectLocation'
		},
		template: CalendarPlusAdmin.helpers.template( 'location-search-result-template' ),
		render: function() {
			this.$el.html( this.template( this.model.toJSON() ) );
			return this;
		},
		selectLocation: function( e ) {
			var location_id = this.model.get('id');
			$('#event-location-hidden').val(location_id);
			$('#location-results').slideUp();

			CalendarPlusAdmin.helpers.setSelectedLocation( this.model );
			
		}
	});

	/**
	 * View for CalendarPlusAdmin.collections.searchResults Collection
	 */
	CalendarPlusAdmin.views.searchResults = Backbone.View.extend({
		tagName: 'ul',
		selectedView: false,
		render: function() {
			this.collection.each( this.addOne, this );
			console.log(this.selectedView);
			return this;
		},
		addOne: function( searchResult ) {
			var searchResultView = new CalendarPlusAdmin.views.SearchResult({ model: searchResult });
			this.$el.append( searchResultView.render().el );
		}
	});

	/**=============================================================**/
	/**                END LOCATION SEARCHER						**/
	/**=============================================================**/

	

	/*****************************************************************/
	/**                    SELECTED LOCATION 						**/
	/*****************************************************************/
	CalendarPlusAdmin.views.SelectedLocation = Backbone.View.extend({
		tagName: 'div',
		className: 'location-selected',
		template: CalendarPlusAdmin.helpers.template( 'location-selected-template' ),
		events: {
			'click #remove-location': 'removeSelectedLocation'
		},
		initialize: function() {
			this.listenTo( this.model, "change", this.render );
		},
		render: function() {
			this.$el.html( this.template( this.model.toJSON() ) );
			return this;
		},
		removeSelectedLocation: function( e ) {
			e.preventDefault();
			$('#event-location-hidden').val( '' );
			var self = this;
			this.$el.slideUp( 400, function() {
				for ( var attr in self.model.attributes ) {
					self.model.set( attr, self.model.defaults[ attr ] );
				}	
			});
			


		}
	});

	/**=============================================================**/
	/**                END SELECTED LOCATION						**/
	/**=============================================================**/


	
	
});