2015-08-05 3 views
1

Я не совсем уверен, как сказать то, что я пытаюсь сделать.JS Как я могу вызвать функцию в рамках другой функции?

Я использую листовку и Геопоиск плагин (https://github.com/smeijer/L.GeoSearch/tree/master/src/js)

окно поиска наблюдает за ключ ввода, чтобы нажать внутри него, прежде чем он выстреливает функцию Геопоиска.

Я хочу, чтобы функция geosearch могла быть вызвана из другого элемента (например, событие onClick() где-то на странице).

Но я не знаю, как целевой geosearch: function (qry), так как это внутри другой функции - L.Control.GeoSearch = L.Control.extend({})

/* 
* L.Control.GeoSearch - search for an address and zoom to its location 
* https://github.com/smeijer/L.GeoSearch 
*/ 

L.GeoSearch = {}; 
L.GeoSearch.Provider = {}; 

L.GeoSearch.Result = function (x, y, label, bounds) { 
    this.X = x; 
    this.Y = y; 
    this.Label = label; 
    this.bounds = bounds; 
}; 

L.Control.GeoSearch = L.Control.extend({ 
    options: { 
     position: 'topcenter', 
     showMarker: true, 
     retainZoomLevel: false, 
     draggable: false 
    }, 

    _config: { 
     country: 'nz', 
     searchLabel: 'search for address ...', 
     notFoundMessage: 'Sorry, that address could not be found.', 
     messageHideDelay: 3000, 
     zoomLevel: 13 
    }, 

    initialize: function (options) { 
     L.Util.extend(this.options, options); 
     L.Util.extend(this._config, options); 
    }, 

    onAdd: function (map) { 
     var $controlContainer = map._controlContainer, 
      nodes = $controlContainer.childNodes, 
      topCenter = false; 

     for (var i = 0, len = nodes.length; i < len; i++) { 
      var klass = nodes[i].className; 
      if (/leaflet-top/.test(klass) && /leaflet-center/.test(klass)) { 
       topCenter = true; 
       break; 
      } 
     } 

     if (!topCenter) { 
      var tc = document.createElement('div'); 
      tc.className += 'leaflet-top leaflet-center'; 
      $controlContainer.appendChild(tc); 
      map._controlCorners.topcenter = tc; 
     } 

     this._map = map; 
     this._container = L.DomUtil.create('div', 'leaflet-control-geosearch'); 

     var searchbox = document.createElement('input'); 
     searchbox.id = 'leaflet_control_geosearch_qry'; 
     searchbox.type = 'text'; 
     searchbox.placeholder = this._config.searchLabel; 
     this._searchbox = searchbox; 

     var msgbox = document.createElement('div'); 
     msgbox.id = 'leaflet-control-geosearch-msg'; 
     msgbox.className = 'leaflet-control-geosearch-msg'; 
     this._msgbox = msgbox; 

     var resultslist = document.createElement('ul'); 
     resultslist.id = 'leaflet-control-geosearch-results'; 
     this._resultslist = resultslist; 

     this._msgbox.appendChild(this._resultslist); 
     this._container.appendChild(this._searchbox); 
     this._container.appendChild(this._msgbox); 

     L.DomEvent 
      .addListener(this._container, 'click', L.DomEvent.stop) 
      .addListener(this._searchbox, 'keypress', this._onKeyUp, this); 

     L.DomEvent.disableClickPropagation(this._container); 

     return this._container; 
    }, 

    geosearch: function (qry) { 
     var that = this; 
     try { 
      var provider = this._config.provider; 

      if(typeof provider.GetLocations == 'function') { 
       var results = provider.GetLocations(qry, function(results) { 
        that._processResults(results); 
       }); 
      } 
      else { 
       var url = provider.GetServiceUrl(qry); 
       this.sendRequest(provider, url); 
      } 
     } 
     catch (error) { 
      this._printError(error); 
     } 
    }, 

    sendRequest: function (provider, url) { 
     var that = this; 

     window.parseLocation = function (response) { 
      var results = provider.ParseJSON(response); 
      that._processResults(results); 

      document.body.removeChild(document.getElementById('getJsonP')); 
      delete window.parseLocation; 
     }; 

     function getJsonP (url) { 
      url = url + '&callback=parseLocation'; 
      var script = document.createElement('script'); 
      script.id = 'getJsonP'; 
      script.src = url; 
      script.async = true; 
      document.body.appendChild(script); 
     } 

     if (XMLHttpRequest) { 
      var xhr = new XMLHttpRequest(); 

      if ('withCredentials' in xhr) { 
       var xhr = new XMLHttpRequest(); 

       xhr.onreadystatechange = function() { 
        if (xhr.readyState == 4) { 
         if (xhr.status == 200) { 
          var response = JSON.parse(xhr.responseText), 
           results = provider.ParseJSON(response); 

          that._processResults(results); 
         } else if (xhr.status == 0 || xhr.status == 400) { 
          getJsonP(url); 
         } else { 
          that._printError(xhr.responseText); 
         } 
        } 
       }; 

       xhr.open('GET', url, true); 
       xhr.send(); 
      } else if (XDomainRequest) { 
       var xdr = new XDomainRequest(); 

       xdr.onerror = function (err) { 
        that._printError(err); 
       }; 

       xdr.onload = function() { 
        var response = JSON.parse(xdr.responseText), 
         results = provider.ParseJSON(response); 

        that._processResults(results); 
       }; 

       xdr.open('GET', url); 
       xdr.send(); 
      } else { 
       getJsonP(url); 
      } 
     } 
    }, 

    _processResults: function(results) { 
     if (results.length > 0) { 
      this._map.fireEvent('geosearch_foundlocations', {Locations: results}); 
      this._showLocation(results[0]); 
     } else { 
      this._printError(this._config.notFoundMessage); 
     } 
    }, 

    _showLocation: function (location) { 
     if (this.options.showMarker == true) { 
      if (typeof this._positionMarker === 'undefined') { 
       this._positionMarker = L.marker(
        [location.Y, location.X], 
        {draggable: this.options.draggable} 
       ).addTo(this._map); 
      } 
      else { 
       this._positionMarker.setLatLng([location.Y, location.X]); 
      } 
     } 
     if (!this.options.retainZoomLevel && location.bounds && location.bounds.isValid()) { 
      this._map.fitBounds(location.bounds); 
     } 
     else { 
      this._map.setView([location.Y, location.X], this._getZoomLevel(), false); 
     } 

     this._map.fireEvent('geosearch_showlocation', { 
      Location: location, 
      Marker : this._positionMarker 
     }); 
    }, 

    _printError: function(message) { 
     var elem = this._resultslist; 
     elem.innerHTML = '<li>' + message + '</li>'; 
     elem.style.display = 'block'; 

     this._map.fireEvent('geosearch_error', {message: message}); 

     setTimeout(function() { 
      elem.style.display = 'none'; 
     }, 3000); 
    }, 

    _onKeyUp: function (e) { 
     var esc = 27, 
      enter = 13; 

     if (e.keyCode === esc) { // escape key detection is unreliable 
      this._searchbox.value = ''; 
      this._map._container.focus(); 
     } else if (e.keyCode === enter) { 
      e.preventDefault(); 
      e.stopPropagation(); 

      this.geosearch(this._searchbox.value); 
     } 
    }, 

    _getZoomLevel: function() { 
     if (! this.options.retainZoomLevel) { 
      return this._config.zoomLevel; 
     } 
     return this._map.zoom; 
    } 

}); 

Я посмотрел везде, но я предполагаю, что я не знаю, как назвать то, что я я делаю. Я даже попробовал установить focus() в поисковый запрос и отправить ключ ввода, но это тоже не сработало (без плагина sendkey).

ответ

0

Вы могли бы сделать так, чтобы прикрепить событие щелчка на кнопке. При нажатии кнопки geoSearchController будет запрашивать после «Нью-Йорка», но вы можете изменить это, чтобы работать с любым значением, которое вы хотите.

// Create the map 
var map = L.map('map').setView([39.5, -0.5], 5); 

// Set up tiles 
L.tileLayer(
    'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', 
    {maxZoom: 18}).addTo(map); 

//Create and add the geoSearchController 
var geoSearchController = new L.Control.GeoSearch({ 
    provider: new L.GeoSearch.Provider.Google() 
}).addTo(map); 

//Add a click handler to a button with the id myButton 
document.getElementById("myButton").addEventListener("click", function(){  
    geoSearchController.geosearch('New York'); 
}); 

Пример: jsfiddle

+0

Спасибо! Это работало как прелесть. Я присоединяю это к списку автозаполнения адресов, поэтому, когда пользователь выбирает адрес из автозаполнения, он запускает поиск. – edenLOL

1

Никогда не использовал плагин, но похоже, что оператор L.Control.extend ({...}) добавляет все эти свойства к L.Control, что означает, что вы можете просто позвонить L.Control.geosearch() напрямую (с помощью qry, конечно).

Что-то вдоль линий:

<button onclick="L.Control.geosearch('myquery')">Button</button>

+0

я мог бы сделать что-то неправильно, но с использованием L.Control.geosearch ('myquery'), возвращается с TypeError: L.Control.geosearch не является функцией – edenLOL

+0

Нет, похоже, я слегка вас обманываю. Оператор 'extend ({})' создает _new_ расширенную копию 'L.Control' как' L.Control.GeoSearch'. Поэтому попробуйте вызвать 'L.Control.GeoSearch.geosearch ('myquery')'. Вы хотите убедиться, что вы не вызываете его до тех пор, пока он не будет определен (что не должно быть проблемой, если вы вызываете его с помощью кнопки). Если это работает, я обновлю свой ответ. –

Смежные вопросы