Show:

File: platform/plugins/Places/web/js/tools/areas.js

(function (Q, $, window, document, undefined) {

	/**
	 * Places Tools
	 * @module Places-tools
	 */

	var Users = Q.Users;
	var Streams = Q.Streams;
	var Places = Q.Places;

	/**
	 * Allows the logged-in user to select/add areas to locations.
	 * Pass either (publisherId,streamName) or (location) options.
	 * @class Places areas
	 * @constructor
	 * @param {Object} options used to pass options
	 * @param {String} options.publisherId Location stream publisher id
	 * @param {String} options.streamName Places/location stream name
	 * @param {Places.Coordinates} options.location To relate the areas to
	 */
	Q.Tool.define("Places/areas", function (options) {
			var tool = this;
			var state = this.state;
			var $te = $(tool.element);

			var pipe = new Q.Pipe(['style', 'text'], function (params) {
				tool.refresh();
			});

			Q.addStylesheet('Q/plugins/Places/css/areas.css', function(){
				pipe.fill('style')();
			});

			Q.Text.get('Places/content', function (err, text) {
				state.text = text;

				pipe.fill('text')();
			});

			$te.on(Q.Pointer.click, function () {
				// $te.find('.Places_areas_filter').addClass("Q_selected");
			});
		},

		{ // default options here
			publisherId: null,
			streamName: null,
			location: null,
			stream: null,
			areaSelected: null
		},

		{ // methods go here
			/**
			 * Refresh the display
			 * @method refresh
			 */
			refresh: function () {
				var tool = this;
				var state = tool.state;
				var $te = $(tool.element);

				// if Q/filter didn't created - create one
				if (!tool.filterTool) {
					var $container = $('<div class="Places_areas_container" />').appendTo(tool.element);
					$("<div class='Places_areas_filter'>").tool('Q/filter', {
						placeholder: state.text.areas.filterPlaceholder
					}, 'Q_filter')
						.appendTo($container)
						.activate(function(){
							tool.filterTool = Q.Tool.from(this.element, "Q/filter");

							// filtering Streams/related tool results
							tool.filterTool.state.onFilter.set(function (query, element) {
								var titles = tool.filterTool.$(".Streams_related_tool .Streams_preview_tool").not(".Streams_preview_composer");

								titles.each(function(){
									var $this = $(this);

									// if title start with query string - show Streams/preview tool element, and hide otherwise
									if ($(".Streams_preview_title", $this).text().toUpperCase().startsWith(query.toUpperCase())) {
										$this.show();
									} else {
										$this.hide();
									}
								});
							}, tool);

							// set selected Places/area stream
							tool.filterTool.state.onChoose.set(function (element, details) {
								var previewTool = Q.Tool.from($(element).closest(".Streams_preview_tool"), "Streams/preview");

								if (!previewTool) {
									return false;
								}

								state.areaSelected = {
									publisherId: previewTool.state.publisherId,
									streamName: previewTool.state.streamName,
									text: details.text
								};
							}, tool);

							// clear selected Places/area stream
							tool.filterTool.state.onClear.set(function () {
								state.areaSelected = null;
							}, tool);
						});
				} else {
					// clear Q/filter input
					tool.filterTool.setText('');
				}

				tool.getStream(function(stream){
					// if related tool already exist - set new stream and refresh
					if (tool.relatedTool) {
						tool.relatedTool.state.publisherId = stream.fields.publisherId;
						tool.relatedTool.state.streamName = stream.fields.name;
						tool.relatedTool.refresh();

						return;
					}

					// apply Streams/related tool exactly to Q/filter results element
					tool.$(".Q_filter_results").tool("Streams/related", {
						publisherId: stream.fields.publisherId,
						streamName: stream.fields.name,
						relationType: 'area',
						isCategory: true,
						editable: false,
						onRefresh: function(){
							// add Q_filter_result class to each preview tool except composer
							$(".Streams_preview_container", $(".Streams_preview_tool", this.element).not(".Streams_preview_composer")).addClass("Q_filter_result");
						},
						creatable: {
							"Places/area": {
								'title': state.text.areas.newArea,
								'preprocess': function(_proceed){
									var previewTool = this;

									tool.prompt(_proceed);
								}
							}
						}
					}).activate(function(){
						tool.relatedTool = this;
					});
				});
			},
			/**
			 * Show Q.prompt to add new area
			 * @method prompt
			 * @param {function} _proceed Callback from Streams/related tool to create new stream
			 */
			prompt: function(_proceed){
				var tool = this;
				var state = this.state;

				var title = tool.filterTool.$input.val() || "";

				var $prompt = Q.prompt(state.text.areas.promptTitle, function (title, dialog) {
						// user click cancel button
						if (title === null) {
							return false;
						}

						// title required
						if (!title) {
							Q.alert(state.text.areas.absent, {
								title: state.text.areas.error,
								onClose: function(){
									tool.prompt(_proceed);
								}
							});
							return false;
						}

						// get array of areas exist
						var areasExist = tool.relatedTool.$(".Streams_preview_title").map(function(){
							return $.trim($(this).text());
						}).get();

						// if title already exist
						if ($.inArray(title, areasExist) >= 0) {
							Q.alert(state.text.areas.exist, {
								title: state.text.areas.error,
								onClose: function(){
									tool.prompt(_proceed);
								}
							});
							return false;
						}

						Q.handle(_proceed, this, [{title: title}]);

						// wait when new preview tool created with this title and add class Q_filter_result
						var timerId = setInterval(function(){
							var container = tool.relatedTool.$(".Streams_preview_container .Streams_preview_title:contains('"+title+"')");

							if(!container.length){
								return;
							}

							clearInterval(timerId);

							// set Q_filter_result class to just created area
							var $result = container.closest(".Streams_preview_container").addClass("Q_filter_result");

							// select just created area
							tool.filterTool.choose($result[0])
						}, 500);
					},
					{
						title: state.text.areas.addNewArea,
						ok: state.text.areas.add
					});

				// set default value
				$("input[type=text]", $prompt).val(title);
			},
			/**
			 * Get location stream and launch callback with this stream as argument
			 * @method getStream
			 * @param {Function} [callback] callback
			 */
			getStream: function(callback){
				var state = this.state;
				var location = state.location;

				// default publisherId to communityId
				if (state.streamName && !state.publisherId) {
					state.publisherId = state.publisherId || Q.info.appId;
				}

				if (state.publisherId && state.streamName) { // stripped stream means that it have only publisherId and name
					Q.Streams.get(state.stream.publisherId, state.stream.name, function () {
						Q.handle(callback, this, [this]);
					});
				} else if(location) {
					// we have just location object and need to check whether stream exist
					// check if we already have location with lat, lng and use one
					// if no - create Places/location stream
					Q.req("Places/areas", 'data', function (err, response) {
						var msg;
						if (msg = Q.firstErrorMessage(err, response && response.errors)) {
							console.warn("Places/areas: " + msg);
							return false;
						}
						var data = response.slots.data;
						Q.Streams.get(data.publisherId, data.streamName, function () {
							Q.handle(callback, this, [this]);
						});
					}, {
						method: 'POST',
						fields: {
							location: {
								latitude: location.latitude,
								longitude: location.longitude,
								venue: location.venue,
								placeId: location.placeId
							}
						}
					});
				} else {
					throw new Exception("Places/areas: required publisherId and streamName, or location");
				}
			}
		});

})(Q, jQuery, window, document);