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!

Answers:

Answer

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;
    });
});
Answer

You can use a Google map plug-in such as Maplace. it will reduce the complexity. it makes easy to add/remove locations on map, trigger new locations on some event. it has easy to use built-in methods.

Check this Demo on how to add/remove new locations in Google map dynamically.

Here is the code.

HTML

<div id="gmap"></div>

<div id="menu">
  <a href="javascript:void(0);" class="loc_link" data-lat="12.58" data-long="77.38" data-title="Bangalore" data-html="Bangalore, Karnataka, India">A</a>

  <a href="javascript:void(0);" class="loc_link" data-lat="31.2" data-long="121.5" data-title="Shanghai" data-html="Shanghai, China">B</a>

  <a href="javascript:void(0);" class="loc_link" data-lat="35.6895" data-long="139.6917" data-title="Tokyo" data-html="Tokyo, Japan">C</a>

  <a href="javascript:void(0);" class="loc_link" data-lat="28.6139" data-long="77.2089" data-title="New Delhi" data-html="New Delhi, India">D</a>

  <a href="javascript:void(0);" class="loc_link" data-lat="40.7127" data-long="74.0059" data-title="New York" data-html="New York City">E</a>

 <br/>
  <span id="tool_tip">Click links to see effect!</span>
</div>

CSS

#gmap{
width: 70%;
height: 350px;
margin: 0 auto;
}

#menu {
 width: 300px;
 margin: 15px auto;
 text-align:center;
}
#menu a.loc_link {
 background: #0f89cf;
 color: #fff;
 margin-right: 10px;
 display: inline-block;
 margin-bottom:10px;
 padding: 5px;
 border-radius: 3px;
 text-decoration: none;
}
#menu span#tool_tip {
  display: inline-block;
  margin-top: 10px;
}

JQuery

$(function(){
var map;
var LocA = [{
    lat: 12.58,
    lon: 77.38,
    title: 'Bangalore',
    html: 'Bangalore, Karnataka, India',
    zoom: 4,
    icon: 'http://maps.google.com/mapfiles/markerA.png',
    animation: google.maps.Animation.DROP
 }];

map = new Maplace({
  locations: LocA,
  map_div: '#gmap',
  generate_controls: false,
  start: 0   
}).Load();


$(".loc_link").click(function(){
  var newLoc = [{
      lat: $(this).data('lat'),
      lon: $(this).data('long'),
      title: $(this).data('title'),
      html: $(this).data('html'),
      zoom: 4,
      icon: 'http://maps.google.com/mapfiles/marker'+$(this).text()+'.png',
    animation:google.maps.Animation.DROP
  }];
 map.AddLocations(newLoc).Load();
 map.ViewOnMap($(this).index()+1);
});
});

You need to add these two js libraries to make it work

http://maps.google.com/maps/api/js?sensor=false&libraries=geometry&v=3.13 http://maplacejs.com/src/maplace-0.1.3.min.js

Hope this helps.

Answer

I can't simulate this, but after read your code I assume this code will work.. First add marker as your pin property:

self.mapPin = function (name, lat, lon, text) {
    this.name = ko.observable(name);
    this.lat = ko.observable(lat);
    this.lon = ko.observable(lon);
    this.text = ko.observable(text);
    this.marker = new google.maps.Marker({
        position: new google.maps.LatLng(lat, lon),
        map: map,
        animation: google.maps.Animation.DROP
    });

    // removed for clarity
};

then set pin marker visibility while filtering your pins

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

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

        pin.marker.setVisible(match); // maps API hide call
        return match;
    });
});

Google Maps Marker Documentation

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us Javascript

©2020 All rights reserved.