From f528ff13cc1fb1bb71c0c9aaa0ffd8340a129679 Mon Sep 17 00:00:00 2001 From: Greg Allensworth Date: Tue, 5 Sep 2017 09:35:59 -0700 Subject: [PATCH] Mobile experience improvements (#169) * Mobile experience improvements * PR 169 indentation via tabs instead of spaces * PR 169 'expand' default + added documentation --- README.md | 1 + src/control.js | 56 +++++++++++++++++++++++++++++++------------------- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 27c5b164..a119ba9d 100755 --- a/README.md +++ b/README.md @@ -94,6 +94,7 @@ L.Control.Geocoder(options) | Option | Type | Default | Description | | --------------- | ---------------- | ----------------- | ----------- | | collapsed | Boolean | true | Collapse control unless hovered/clicked | +| expand | String | "touch" | How to expand a collapsed control: `touch` `click` `hover` | | position | String | "topright" | Control [position](http://leafletjs.com/reference.html#control-positions) | | placeholder | String | "Search..." | Placeholder text for text input | errorMessage | String | "Nothing found." | Message when no result found / geocoding error occurs | diff --git a/src/control.js b/src/control.js index 833f6277..da6474d1 100644 --- a/src/control.js +++ b/src/control.js @@ -6,7 +6,7 @@ module.exports = { options: { showResultIcons: false, collapsed: true, - expand: 'click', + expand: 'touch', // options: touch, click, anythingelse position: 'topright', placeholder: 'Search...', errorMessage: 'Nothing found.', @@ -63,21 +63,35 @@ module.exports = { if (this.options.collapsed) { if (this.options.expand === 'click') { L.DomEvent.addListener(icon, 'click', function(e) { - // TODO: touch if (e.button === 0 && e.detail !== 2) { this._toggle(); } }, this); - } else { + } + else if (L.Browser.touch && this.options.expand === 'touch') { + L.DomEvent.addListener(icon, 'touchstart', function(e) { + this._toggle(); + e.preventDefault(); // mobile: clicking focuses the icon, so UI expands and immediately collapses + e.stopPropagation(); + }, this); + } + else { L.DomEvent.addListener(icon, 'mouseover', this._expand, this); L.DomEvent.addListener(icon, 'mouseout', this._collapse, this); this._map.on('movestart', this._collapse, this); } } else { - L.DomEvent.addListener(icon, 'click', function(e) { - this._geocode(e); - }, this); this._expand(); + if (L.Browser.touch) { + L.DomEvent.addListener(icon, 'touchstart', function(e) { + this._geocode(e); + }, this); + } + else { + L.DomEvent.addListener(icon, 'click', function(e) { + this._geocode(e); + }, this); + } } if (this.options.defaultMarkGeocode) { @@ -152,12 +166,11 @@ module.exports = { if (!this.options.collapsed) { this._clearResults(); } - this.fire('markgeocode', {geocode: result}); }, _toggle: function() { - if (this._container.className.indexOf('leaflet-control-geocoder-expanded') >= 0) { + if (L.DomUtil.hasClass(this._container, 'leaflet-control-geocoder-expanded')) { this._collapse(); } else { this._expand(); @@ -171,9 +184,10 @@ module.exports = { }, _collapse: function () { - this._container.className = this._container.className.replace(' leaflet-control-geocoder-expanded', ''); + L.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-expanded'); L.DomUtil.addClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized'); L.DomUtil.removeClass(this._errorElement, 'leaflet-control-geocoder-error'); + this._input.blur(); // mobile: keyboard shouldn't stay expanded this.fire('collapse'); }, @@ -186,21 +200,21 @@ module.exports = { _createAlt: function(result, index) { var li = L.DomUtil.create('li', ''), a = L.DomUtil.create('a', '', li), - icon = this.options.showResultIcons && result.icon ? L.DomUtil.create('img', '', a) : null, - text = result.html ? undefined : document.createTextNode(result.name), - mouseDownHandler = function mouseDownHandler(e) { - // In some browsers, a click will fire on the map if the control is - // collapsed directly after mousedown. To work around this, we - // wait until the click is completed, and _then_ collapse the - // control. Messy, but this is the workaround I could come up with - // for #142. - this._preventBlurCollapse = true; + icon = this.options.showResultIcons && result.icon ? L.DomUtil.create('img', '', a) : null, + text = result.html ? undefined : document.createTextNode(result.name), + mouseDownHandler = function mouseDownHandler(e) { + // In some browsers, a click will fire on the map if the control is + // collapsed directly after mousedown. To work around this, we + // wait until the click is completed, and _then_ collapse the + // control. Messy, but this is the workaround I could come up with + // for #142. + this._preventBlurCollapse = true; L.DomEvent.stop(e); this._geocodeResultSelected(result); L.DomEvent.on(li, 'click', function() { - if (this.options.collapsed) { - this._collapse(); - } + if (this.options.collapsed) { + this._collapse(); + } }, this); };