Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing Map Pin with Search

I'm trying to create a search bar that filters out items from a list if they do not match the search query. The additional functionality that I'm trying to add is that if it doesn't match the search query it removes the pins from the map as well.

This is what I have right now and it works for removing the names along the top of the page, but id like it to remove the pins also. I'm wondering how to go about this.

self.pins = ko.observableArray([
  new self.mapPin("Waterloo Station", 51.503035, -0.112326, "test3""),
  new self.mapPin("King's Cross Station", 51.530984, -0.122583, "test2"),
  new self.mapPin("Putney Bridge", 51.468050, -0.209081, "test1")
]);

self.query = ko.observable('');

self.filterPins = ko.computed(function () {
    var search = self.query().toLowerCase();
    return ko.utils.arrayFilter(self.pins(), function (pin) {
        return pin.name().toLowerCase().indexOf(search) >= 0;
    });
});

HTML:

<input data-bind="value: query, valueUpdate: 'keyup'" autocomplete="off" type="text" class="form-control" placeholder="Filter Locations">

        <ul data-bind="foreach: filterPins" class="nav navbar-nav" class=" nav navbar-nav">
            <li class="active">
                <a data-bind="text: name"></a>

Any help would be appreciated!

like image 809
hufflapuff Avatar asked Apr 10 '15 09:04

hufflapuff


1 Answers

I would encapsulate your markers into their own data model that takes care of the interaction with Google Maps behind the scenes:

// we have to give it access to the map object, so that
// it can register and de-register itself
var Pin = function Pin(map, name, lat, lon, text) {
  var marker;

  this.name = ko.observable(name);
  this.lat  = ko.observable(lat);
  this.lon  = ko.observable(lon);
  this.text = ko.observable(text);

  marker = new google.maps.Marker({
    position: new google.maps.LatLng(lat, lon),
    animation: google.maps.Animation.DROP
  });

  this.isVisible = ko.observable(false);

  this.isVisible.subscribe(function(currentState) {
    if (currentState) {
      marker.setMap(map);
    } else {
      marker.setMap(null);
    }
  });

  this.isVisible(true);
}

Now you can create your pins with pin = new Pin(map, 1, 2, 'text'), and when you toggle their visibility state with pin.isVisible(false), they automatically register or deregister with the map.

Your filter function thus becomes

self.filterPins = ko.computed(function () {
    var search  = self.query().toLowerCase();

    return ko.utils.arrayFilter(self.pins(), function (pin) {
        var doesMatch = pin.name().toLowerCase().indexOf(search) >= 0;

        pin.isVisible(doesMatch);

        return doesMatch;
    });
});
like image 92
janfoeh Avatar answered Sep 21 '22 20:09

janfoeh