| // Copyright 2015 The Vanadium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| var $ = require('../util/jquery'); |
| var defineClass = require('../util/define-class'); |
| |
| var DestinationSearch = defineClass({ |
| publics: { |
| clear: function() { |
| this.setPlace(null); |
| this.$searchBox.prop('value', ''); |
| }, |
| |
| enable: function() { |
| this.$searchBox.removeAttr('disabled'); |
| }, |
| |
| disable: function() { |
| this.$searchBox.attr('disabled', 'disabled'); |
| }, |
| |
| focus: function() { |
| this.$.find('input:visible').focus(); |
| }, |
| |
| hasFocus: function() { |
| return this.$.find(':focus').length > 0; |
| }, |
| |
| setSearchBounds: function(bounds) { |
| this.searchBox.setBounds(bounds); |
| }, |
| |
| select: function() { |
| this.$.addClass('selected'); |
| }, |
| |
| deselect: function() { |
| if (this.isSelected()) { |
| this.$.removeClass('selected'); |
| this.onDeselect(); |
| } |
| }, |
| |
| isSelected: function() { |
| return this.$.hasClass('selected'); |
| }, |
| |
| getPlace: function() { |
| return this.place; |
| }, |
| |
| setPlace: function(place) { |
| var prev = this.place; |
| if (prev !== place) { |
| this.place = place; |
| this.setAutocomplete(!place); |
| |
| var newValue; |
| if (place) { |
| newValue = place.getSingleLine(); |
| } else if (!this.hasFocus()) { |
| newValue = ''; |
| } |
| if (newValue !== undefined) { |
| this.$searchBox.prop('value', newValue); |
| } |
| |
| this.onPlaceChange(place, prev); |
| } |
| }, |
| |
| setPlaceholder: function(placeholder) { |
| this.$searchBox.attr('placeholder', placeholder); |
| }, |
| |
| getValue: function() { |
| return this.$searchBox.prop('value'); |
| } |
| }, |
| |
| privates: { |
| /** |
| * This is a bit of a hack; Maps API does not include functionality to |
| * disable autocomplete. |
| */ |
| setAutocomplete: function(autocomplete) { |
| /* True boolean comparison. We could coerce the input to boolean, but |
| * this is less impactful. */ |
| /* jshint eqeqeq: false */ |
| if (this.autocomplete != autocomplete) { |
| /* jshint eqeqeq: true */ |
| this.autocomplete = autocomplete; |
| |
| var oldBox = this.$searchBox[autocomplete? 1 : 0]; |
| var newBox = this.$searchBox[autocomplete? 0 : 1]; |
| |
| newBox.value = oldBox.value; |
| var active = global.document && |
| global.document.activeElement === oldBox; |
| |
| /* Restrict selection restoration to active elements because |
| * setSelectionRange apparently takes keyboard focus away from the |
| * currently focused element without actually setting it to anything, |
| * and trying to restore focus afterwards doesn't work. */ |
| if (active && newBox.setSelectionRange) { |
| //non-universal browser support |
| newBox.setSelectionRange(oldBox.selectionStart, oldBox.selectionEnd); |
| } |
| |
| if (autocomplete) { |
| this.$.addClass('autocomplete'); |
| } else { |
| this.$.removeClass('autocomplete'); |
| } |
| |
| if (active) { |
| $(newBox).focus(); |
| } |
| } |
| }, |
| |
| inputKey: function(e) { |
| if (e.which === 13) { |
| this.onSubmit(this.getValue()); |
| } |
| e.stopPropagation(); |
| } |
| }, |
| |
| events: [ |
| /** |
| * @param event jQuery Event object for text box focus event. |
| */ |
| 'onFocus', |
| |
| /** |
| * @param place |
| * @param previous |
| */ |
| 'onPlaceChange', |
| |
| /** |
| * @param places (array of places) |
| */ |
| 'onSearch', |
| |
| 'onDeselect', |
| |
| /** |
| * Event fired when the enter key is pressed. This is distinct from the |
| * onSearch event, which is fired when valid location properties are chosen, |
| * which can happen without onSubmit in the case of an autocomplete. |
| * |
| * @param value the current control text. |
| */ |
| 'onSubmit' |
| ], |
| |
| constants: ['$'], |
| |
| init: function(maps) { |
| var self = this; |
| |
| var $searchBox = $.merge($('<input>'), $('<input>')) |
| .attr('type', 'text') |
| //to make dummy box consistent with search |
| .attr('autocomplete', 'off'); |
| this.$searchBox = $searchBox; |
| |
| $searchBox[0].className = 'autocomplete'; |
| |
| $searchBox.focus(this.onFocus); |
| $searchBox.on('input', function() { |
| self.setPlace(null); |
| }).keypress(this.inputKey); |
| |
| this.$ = $('<div>') |
| .addClass('destination autocomplete') |
| .append($searchBox); |
| |
| this.searchBox = new maps.places.SearchBox($searchBox[0]); |
| |
| this.autocomplete = true; |
| |
| maps.event.addListener(this.searchBox, 'places_changed', function() { |
| self.onSearch(self.searchBox.getPlaces()); |
| }); |
| } |
| }); |
| |
| module.exports = DestinationSearch; |