UNPKG

leaflet-search

Version:

Leaflet Control for searching markers/features by attribute on map or remote searching in jsonp/ajax

17 lines 16.3 kB
/* * Leaflet Control Search v3.0.5 - 2022-11-24 * * Copyright 2022 Stefano Cudini * stefano.cudini@gmail.com * https://opengeo.tech/ * * Licensed under the MIT license. * * Demo: * https://opengeo.tech/maps/leaflet-search/ * * Source: * git@github.com:stefanocudini/leaflet-search.git * */ !function(t){if("function"==typeof define&&define.amd)define(["leaflet"],t);else if("undefined"!=typeof module)module.exports=t(require("leaflet"));else{if(void 0===window.L)throw"Leaflet must be loaded first";t(window.L)}}(function(a){return a.Control.Search=a.Control.extend({includes:"1"===a.version[0]?a.Evented.prototype:a.Mixin.Events,options:{url:"",layer:null,sourceData:null,jsonpParam:null,propertyLoc:"loc",propertyName:"title",formatData:null,filterData:null,moveToLocation:null,buildTip:null,container:"",zoom:null,minLength:1,initial:!0,casesensitive:!1,autoType:!0,delayType:400,tooltipLimit:-1,tipAutoSubmit:!0,firstTipSubmit:!1,autoResize:!0,collapsed:!0,autoCollapse:!1,autoCollapseTime:1200,textErr:"Location not found",textCancel:"Cancel",textPlaceholder:"Search...",hideMarkerOnCollapse:!1,position:"topleft",marker:{icon:!1,animate:!0,circle:{radius:10,weight:3,color:"#e03",stroke:!0,fill:!1}}},_getPath:function(t,e){var i=e.split("."),e=i.pop(),o=i.length,s=i[0],n=1;if(0<o)for(;(t=t[s])&&n<o;)s=i[n++];if(t)return t[e]},_isObject:function(t){return"[object Object]"===Object.prototype.toString.call(t)},initialize:function(t){a.Util.setOptions(this,t||{}),this._inputMinSize=this.options.textPlaceholder?this.options.textPlaceholder.length:10,this._layer=this.options.layer||new a.LayerGroup,this._filterData=this.options.filterData||this._defaultFilterData,this._formatData=this.options.formatData||this._defaultFormatData,this._moveToLocation=this.options.moveToLocation||this._defaultMoveToLocation,this._autoTypeTmp=this.options.autoType,this._countertips=0,this._recordsCache={},this._curReq=null},onAdd:function(t){return this._map=t,this._container=a.DomUtil.create("div","leaflet-control-search"),this._input=this._createInput(this.options.textPlaceholder,"search-input"),this._tooltip=this._createTooltip("search-tooltip"),this._cancel=this._createCancel(this.options.textCancel,"search-cancel"),this._button=this._createButton(this.options.textPlaceholder,"search-button"),this._alert=this._createAlert("search-alert"),!1===this.options.collapsed&&this.expand(this.options.collapsed),this.options.marker&&(this.options.marker instanceof a.Marker||this.options.marker instanceof a.CircleMarker?this._markerSearch=this.options.marker:this._isObject(this.options.marker)&&(this._markerSearch=new a.Control.Search.Marker([0,0],this.options.marker)),this._markerSearch._isMarkerSearch=!0),this.setLayer(this._layer),t.on({resize:this._handleAutoresize},this),this._container},addTo:function(t){return this.options.container?(this._container=this.onAdd(t),this._wrapper=a.DomUtil.get(this.options.container),this._wrapper.style.position="relative",this._wrapper.appendChild(this._container)):a.Control.prototype.addTo.call(this,t),this},onRemove:function(t){this._recordsCache={},t.off({resize:this._handleAutoresize},this)},setLayer:function(t){return this._layer=t,this._layer.addTo(this._map),this},showAlert:function(t){var e=this;return t=t||this.options.textErr,this._alert.style.display="block",this._alert.innerHTML=t,clearTimeout(this.timerAlert),this.timerAlert=setTimeout(function(){e.hideAlert()},this.options.autoCollapseTime),this},hideAlert:function(){return this._alert.style.display="none",this},cancel:function(){return this._input.value="",this._handleKeypress({keyCode:8}),this._input.size=this._inputMinSize,this._input.focus(),this._cancel.style.display="none",this._hideTooltip(),this.fire("search:cancel"),this},expand:function(t){return t="boolean"!=typeof t||t,this._input.style.display="block",a.DomUtil.addClass(this._container,"search-exp"),!1!==t&&(this._input.focus(),this._map.on("dragstart click",this.collapse,this)),this.fire("search:expanded"),this},collapse:function(){return this._hideTooltip(),this.cancel(),this._alert.style.display="none",this._input.blur(),this.options.collapsed&&(this._input.style.display="none",this._cancel.style.display="none",a.DomUtil.removeClass(this._container,"search-exp"),this.options.hideMarkerOnCollapse&&this._map.removeLayer(this._markerSearch),this._map.off("dragstart click",this.collapse,this)),this.fire("search:collapsed"),this},collapseDelayed:function(){var t=this;return this.options.autoCollapse&&(clearTimeout(this.timerCollapse),this.timerCollapse=setTimeout(function(){t.collapse()},this.options.autoCollapseTime)),this},collapseDelayedStop:function(){return clearTimeout(this.timerCollapse),this},_createAlert:function(t){t=a.DomUtil.create("div",t,this._container);return t.style.display="none",a.DomEvent.on(t,"click",a.DomEvent.stop,this).on(t,"click",this.hideAlert,this),t},_createInput:function(t,e){var i=this,o=a.DomUtil.create("label",e,this._container),e=a.DomUtil.create("input",e,this._container);return e.type="text",e.size=this._inputMinSize,e.value="",e.autocomplete="off",e.autocorrect="off",e.autocapitalize="off",e.placeholder=t,e.style.display="none",e.role="search",e.id=e.role+e.type+e.size,o.htmlFor=e.id,o.style.display="none",o.value=t,a.DomEvent.disableClickPropagation(e).on(e,"keyup",this._handleKeypress,this).on(e,"paste",function(t){setTimeout(function(t){i._handleKeypress(t)},10,t)},this).on(e,"blur",this.collapseDelayed,this).on(e,"focus",this.collapseDelayedStop,this),e},_createCancel:function(t,e){e=a.DomUtil.create("a",e,this._container);return e.href="#",e.title=t,e.style.display="none",e.innerHTML="<span>&otimes;</span>",a.DomEvent.on(e,"click",a.DomEvent.stop,this).on(e,"click",this.cancel,this),e},_createButton:function(t,e){e=a.DomUtil.create("a",e,this._container);return e.href="#",e.title=t,a.DomEvent.on(e,"click",a.DomEvent.stop,this).on(e,"click",this._handleSubmit,this).on(e,"focus",this.collapseDelayedStop,this).on(e,"blur",this.collapseDelayed,this),e},_createTooltip:function(t){var e=this,t=a.DomUtil.create("ul",t,this._container);return t.style.display="none",a.DomEvent.disableClickPropagation(t).on(t,"blur",this.collapseDelayed,this).on(t,"wheel",function(t){e.collapseDelayedStop(),a.DomEvent.stopPropagation(t)},this).on(t,"mouseover",function(t){e.collapseDelayedStop()},this),t},_createTip:function(e,t){var i;return this.options.buildTip?"string"==typeof(i=this.options.buildTip.call(this,e,t))&&((t=a.DomUtil.create("div")).innerHTML=i,i=t.firstChild):(i=a.DomUtil.create("li","")).innerHTML=e,a.DomUtil.addClass(i,"search-tip"),i._text=e,this.options.tipAutoSubmit&&a.DomEvent.disableClickPropagation(i).on(i,"click",a.DomEvent.stop,this).on(i,"click",function(t){this._input.value=e,this._handleAutoresize(),this._input.focus(),this._hideTooltip(),this._handleSubmit()},this),i},_getUrl:function(t){return"function"==typeof this.options.url?this.options.url(t):this.options.url},_defaultFilterData:function(t,e){var i,o,s,n,r={};if(""===(t=t.replace(/[.*+?^${}()|[\]\\]/g,"")))return[];for(n in i=this.options.initial?"^":"",o=this.options.casesensitive?void 0:"i",s=new RegExp(i+t,o),e)s.test(n)&&(r[n]=e[n]);return r},showTooltip:function(t){if(this._countertips=0,this._tooltip.innerHTML="",this._tooltip.currentSelection=-1,this.options.tooltipLimit)for(var e in t){if(this._countertips===this.options.tooltipLimit)break;this._countertips++,this._tooltip.appendChild(this._createTip(e,t[e]))}return 0<this._countertips?(this._tooltip.style.display="block",this._autoTypeTmp&&this._autoType(),this._autoTypeTmp=this.options.autoType):this._hideTooltip(),this._tooltip.scrollTop=0,this._countertips},_hideTooltip:function(){return this._tooltip.style.display="none",this._tooltip.innerHTML="",0},_defaultFormatData:function(t){var e=this,i=this.options.propertyName,o=this.options.propertyLoc,s={};if(a.Util.isArray(o))for(var n in t)s[e._getPath(t[n],i)]=a.latLng(e._getPath(t[n],o[0]),e._getPath(t[n],o[1]));else for(var r in t)s[e._getPath(t[r],i)]=a.latLng(e._getPath(t[r],o));return s},_recordsFromJsonp:function(t,e){a.Control.Search.callJsonp=e;var i=a.DomUtil.create("script","leaflet-search-jsonp",document.getElementsByTagName("body")[0]),e=a.Util.template(this._getUrl(t)+"&"+this.options.jsonpParam+"=L.Control.Search.callJsonp",{s:t});return i.type="text/javascript",i.src=e,{abort:function(){i.parentNode.removeChild(i)}}},_recordsFromAjax:function(t,e){void 0===window.XMLHttpRequest&&(window.XMLHttpRequest=function(){try{return new ActiveXObject("Microsoft.XMLHTTP.6.0")}catch(t){try{return new ActiveXObject("Microsoft.XMLHTTP.3.0")}catch(t){throw new Error("XMLHttpRequest is not supported")}}});var i=new(a.Browser.ie&&!window.atob&&document.querySelector?XDomainRequest:XMLHttpRequest),t=a.Util.template(this._getUrl(t),{s:t});return i.open("GET",t),i.onload=function(){e(JSON.parse(i.responseText))},i.onreadystatechange=function(){4===i.readyState&&200===i.status&&this.onload()},i.send(),i},_searchInLayer:function(t,e,i){var o,s=this;t instanceof a.Control.Search.Marker||(t instanceof a.Marker||t instanceof a.CircleMarker?s._getPath(t.options,i)?((o=t.getLatLng()).layer=t,e[s._getPath(t.options,i)]=o):s._getPath(t.feature.properties,i)&&((o=t.getLatLng()).layer=t,e[s._getPath(t.feature.properties,i)]=o):t instanceof a.Path||t instanceof a.Polyline||t instanceof a.Polygon?s._getPath(t.options,i)?((o=t.getBounds().getCenter()).layer=t,e[s._getPath(t.options,i)]=o):s._getPath(t.feature.properties,i)&&((o=t.getBounds().getCenter()).layer=t,e[s._getPath(t.feature.properties,i)]=o):t.hasOwnProperty("feature")?t.feature.properties.hasOwnProperty(i)&&(t.getLatLng&&"function"==typeof t.getLatLng?((o=t.getLatLng()).layer=t,e[t.feature.properties[i]]=o):t.getBounds&&"function"==typeof t.getBounds&&((o=t.getBounds().getCenter()).layer=t,e[t.feature.properties[i]]=o)):t instanceof a.LayerGroup&&t.eachLayer(function(t){s._searchInLayer(t,e,i)}))},_recordsFromLayer:function(){var e=this,i={},o=this.options.propertyName;return this._layer.eachLayer(function(t){e._searchInLayer(t,i,o)}),i},_autoType:function(){var t=this._input.value.length,e=this._tooltip.firstChild?this._tooltip.firstChild._text:"",i=e.length;0===e.indexOf(this._input.value)&&(this._input.value=e,this._handleAutoresize(),this._input.createTextRange?((e=this._input.createTextRange()).collapse(!0),e.moveStart("character",t),e.moveEnd("character",i),e.select()):this._input.setSelectionRange?this._input.setSelectionRange(t,i):this._input.selectionStart&&(this._input.selectionStart=t,this._input.selectionEnd=i))},_hideAutoType:function(){var t,e;(t=this._input.selection)&&t.empty?t.empty():this._input.createTextRange?((t=this._input.createTextRange()).collapse(!0),e=this._input.value.length,t.moveStart("character",e),t.moveEnd("character",e),t.select()):(this._input.getSelection&&this._input.getSelection().removeAllRanges(),this._input.selectionStart=this._input.selectionEnd)},_handleKeypress:function(t){var e=this;switch(t.keyCode){case 27:this.collapse();break;case 13:(1==this._countertips||this.options.firstTipSubmit&&0<this._countertips)&&-1==this._tooltip.currentSelection&&this._handleArrowSelect(1),this._handleSubmit();break;case 38:this._handleArrowSelect(-1);break;case 40:this._handleArrowSelect(1);break;case 8:case 45:case 46:this._autoTypeTmp=!1;break;case 37:case 39:case 16:case 17:case 35:case 36:break;default:this._input.value.length?this._cancel.style.display="block":this._cancel.style.display="none",this._input.value.length>=this.options.minLength?(clearTimeout(this.timerKeypress),this.timerKeypress=setTimeout(function(){e._fillRecordsCache()},this.options.delayType)):this._hideTooltip()}this._handleAutoresize()},searchText:function(t){var e=t.charCodeAt(t.length);this._input.value=t,this._input.style.display="block",a.DomUtil.addClass(this._container,"search-exp"),this._autoTypeTmp=!1,this._handleKeypress({keyCode:e})},_fillRecordsCache:function(){var e,i=this,t=this._input.value;this._curReq&&this._curReq.abort&&this._curReq.abort(),a.DomUtil.addClass(this._container,"search-load"),this.options.layer?(this._recordsCache=this._recordsFromLayer(),e=this._filterData(this._input.value,this._recordsCache),this.showTooltip(e),a.DomUtil.removeClass(this._container,"search-load")):(this.options.sourceData?this._retrieveData=this.options.sourceData:this.options.url&&(this._retrieveData=this.options.jsonpParam?this._recordsFromJsonp:this._recordsFromAjax),this._curReq=this._retrieveData.call(this,t,function(t){i._recordsCache=i._formatData.call(i,t),e=i.options.sourceData?i._filterData(i._input.value,i._recordsCache):i._recordsCache,i.showTooltip(e),a.DomUtil.removeClass(i._container,"search-load")}))},_handleAutoresize:function(){var t;this._input.style.maxWidth!==this._map._container.offsetWidth&&(t=this._map._container.clientWidth,this._input.style.maxWidth=(t-=83).toString()+"px"),this.options.autoResize&&this._container.offsetWidth+20<this._map._container.offsetWidth&&(this._input.size=this._input.value.length<this._inputMinSize?this._inputMinSize:this._input.value.length)},_handleArrowSelect:function(t){var e=this._tooltip.hasChildNodes()?this._tooltip.childNodes:[];for(let t=0;t<e.length;t++)a.DomUtil.removeClass(e[t],"search-tip-select");1==t&&this._tooltip.currentSelection>=e.length-1?a.DomUtil.addClass(e[this._tooltip.currentSelection],"search-tip-select"):-1==t&&this._tooltip.currentSelection<=0?this._tooltip.currentSelection=-1:"none"!=this._tooltip.style.display&&(this._tooltip.currentSelection+=t,a.DomUtil.addClass(e[this._tooltip.currentSelection],"search-tip-select"),this._input.value=e[this._tooltip.currentSelection]._text,(t=e[this._tooltip.currentSelection].offsetTop)+e[this._tooltip.currentSelection].clientHeight>=this._tooltip.scrollTop+this._tooltip.clientHeight?this._tooltip.scrollTop=t-this._tooltip.clientHeight+e[this._tooltip.currentSelection].clientHeight:t<=this._tooltip.scrollTop&&(this._tooltip.scrollTop=t))},_handleSubmit:function(){var t;this._hideAutoType(),this.hideAlert(),this._hideTooltip(),"none"==this._input.style.display?this.expand():""===this._input.value?this.collapse():(t=this._getLocation(this._input.value))?(this.showLocation(t,this._input.value),this.fire("search:locationfound",{latlng:t,text:this._input.value,layer:t.layer||null})):this.showAlert()},_getLocation:function(t){return!!this._recordsCache.hasOwnProperty(t)&&this._recordsCache[t]},_defaultMoveToLocation:function(t,e,i){this.options.zoom?this._map.setView(t,this.options.zoom):this._map.panTo(t)},showLocation:function(e,t){var i=this;return i._map.once("moveend zoomend",function(t){i._markerSearch&&i._markerSearch.addTo(i._map).setLatLng(e)}),i._moveToLocation(e,t,i._map),i.options.autoCollapse&&i.collapse(),i}}),a.Control.Search.Marker=a.Marker.extend({includes:"1"===a.version[0]?a.Evented.prototype:a.Mixin.Events,options:{icon:new a.Icon.Default,animate:!0,circle:{radius:10,weight:3,color:"#e03",stroke:!0,fill:!1}},initialize:function(t,e){a.setOptions(this,e),!0===e.icon&&(e.icon=new a.Icon.Default),a.Marker.prototype.initialize.call(this,t,e),a.Control.Search.prototype._isObject(this.options.circle)&&(this._circleLoc=new a.CircleMarker(t,this.options.circle))},onAdd:function(t){a.Marker.prototype.onAdd.call(this,t),this._circleLoc&&(t.addLayer(this._circleLoc),this.options.animate)&&this.animate()},onRemove:function(t){a.Marker.prototype.onRemove.call(this,t),this._circleLoc&&t.removeLayer(this._circleLoc)},setLatLng:function(t){return a.Marker.prototype.setLatLng.call(this,t),this._circleLoc&&this._circleLoc.setLatLng(t),this},_initIcon:function(){this.options.icon&&a.Marker.prototype._initIcon.call(this)},_removeIcon:function(){this.options.icon&&a.Marker.prototype._removeIcon.call(this)},animate:function(){var t,e,i,o,s;return this._circleLoc&&(t=this._circleLoc,e=parseInt(t._radius/5),i=this.options.circle.radius,o=2*t._radius,s=0,t._timerAnimLoc=setInterval(function(){o-=e+=s+=.5,t.setRadius(o),o<i&&(clearInterval(t._timerAnimLoc),t.setRadius(i))},200)),this}}),a.Map.addInitHook(function(){this.options.searchControl&&(this.searchControl=a.control.search(this.options.searchControl),this.addControl(this.searchControl))}),a.control.search=function(t){return new a.Control.Search(t)},a.Control.Search});