Skip to content

Instantly share code, notes, and snippets.

@hamannjames
Created July 26, 2017 06:44
Show Gist options
  • Save hamannjames/e9343a185a3604f3ab1a3f572b94eaaa to your computer and use it in GitHub Desktop.
Save hamannjames/e9343a185a3604f3ab1a3f572b94eaaa to your computer and use it in GitHub Desktop.
A simple jQuery map locator. It was tailored for a specific company so some parts of it are very imperative.
// This store locator makes use the moment.js plugin to help deal with timezones.
/*
Location objects are tailored to a specific model and expected to have a title, address, open and close time, as well as
an array of specific features used for filtering
*/
/*
The initial locator object. Consolidating all the markers, stores, infowindows,
and neighborhoods into a single object makes for cleaner code.
*/
const rootProtocol = location.protocol;
const rootHost = location.host;
const apiURL;
const googleAPIKey;
const locator = {
locations: [], // An empty array that will be populated with location objects
markers: [], // An empty array that will be populated with google marker objects
bounds: new google.maps.LatLngBounds(), // This is a dynamic object that will be used to resize the map
center: new google.maps.LatLng(47.6062, -122.3321), // The center of the map (set to Seattle in this case)
zoom: 16, // A comfortable zoom level for the greater seattle areaneighborhoods: null, // This will be populated with an array of neighborhoods with the buildNeighborhood function
theNeighborhood: new google.maps.LatLngBounds(), // The neighborhood currently in use (if any)
isNeighborhood: false, // Tells if the locator object is currently a neighborhood state.
prepended: false,
formVal: null, // Used to alter the filters array as necessary
filters: [], // An empty dynamic array that will be constantly repopulated with filters
time: moment.tz('America/Los_angeles').format('kk:mm'), // The current pacific time used to tell if locations are open or closed
day: moment.tz('America/Los_angeles').format('d'), // Get day in pacific time zone number format(0 - 6)
date: moment.tz('America/Los_angeles').format('MM/DD'), // Get date
WABounds: new google.maps.LatLngBounds(new google.maps.LatLng(45.543541, -124.848974), new google.maps.LatLng(49.0024305, -116.91558)),
holidayHours: null,
// This build function will be called to perform a rest call and populate all the properties
build: function() {
var locatorInfo = $.Deferred();
$.ajax(location.protocol + '//' + location.host + apiURL, {
type: 'GET',
success: function(result) {
locatorInfo.resolve(result);
}
});
return locatorInfo;
},
isHoliday: function() {
let holidayInfo = $.Deferred();
$.ajax(location.protocol + '//' + location.host + apiURL, {
type: 'GET',
success: function(result) {
holidayInfo.resolve(result);
}
});
return holidayInfo;
},
/*
Using the google Geocoding API, a call is made to google maps using the term entered into the search box if it doesn't match any esisting stores.
The returned object is then assesed inside the caller function.
*/
getNeighborhood: function(name) {
let term = name;
if (term.indexOf(' ') > -1) { // To make the term more url API friendly we replace any spaces with '+' symbols.
term = term.replace(' ', '+');
}
// The bounds of a large portion of washington state covering all bartells stores are sent to google as well, to make sure washington neighbrohoods are returned first.
return $.ajax('https://maps.googleapis.com/maps/api/geocode/json?address=' + term + '&bounds=46.994187,-122.920532|48.377119,-121.854858&key=googleAPIKey', {
type: 'GET'
});
},
/*
This function is called once getNeighbrohood is passed back to its caller. If the area is within Washington state then we can use that
to either build out a neighborhood or find the closest store.
*/
buildNeighborhood: function(object) {
let point = new google.maps.LatLng(object.geometry.location.lat, object.geometry.location.lng);
let boundsNE;
let boundsSW;
let newNE;
let newSW;
if (object.geometry.bounds) {
boundsNE = new google.maps.LatLng(object.geometry.bounds.northeast.lat, object.geometry.bounds.northeast.lng);
boundsSW = new google.maps.LatLng(object.geometry.bounds.southwest.lat, object.geometry.bounds.southwest.lng);
// Here we extend the bounds of the neighborhood returned by google by a quarter of a mile, and it becomes our bounds object
newNE = google.maps.geometry.spherical.computeOffsetOrigin(boundsNE, -804, 45); // The arguments passed are a point of origin, distance to travel, and a direction in degrees.
newSW = google.maps.geometry.spherical.computeOffsetOrigin(boundsSW, -804, 225);
}
else {
newNE = google.maps.geometry.spherical.computeOffsetOrigin(point, -804, 45); // The arguments passed are a point of origin, distance to travel, and a direction in degrees.
newSW = google.maps.geometry.spherical.computeOffsetOrigin(point, -804, 225);
}
// Here we extend the bounds of the neighborhood returned by google by a quarter of a mile, and it becomes our bounds object
let searchBounds = new google.maps.LatLngBounds(newSW, newNE);
let items = 0;
let length = locator.markers.length;
for (let i = 0; i < length; i++) {
if (searchBounds.contains(locator.markers[i].position)) { // If a marker falls within our bounds we can use it.
$('#no-stores').fadeOut('fast');
locator.markers[i].setMap(map);
$(".store").eq(i + 1).fadeIn('fast'); // fades in the correct store by index (plus one because of the prepended div to the store container)
// uncomment if .eq is not working. Slower but more reliable. $("#store-" + i).fadeIn('fast');
items++;
}
else {
locator.markers[i].setMap(null);
$(".store").eq(i + 1).fadeOut('fast'); // Fade out store by index
// uncomment if .eq is not working. Slower but more reliable. $("#store-" + i).fadeOut('fast');
}
}
if (items === 0) { // If nothing fell within our bounds we want to find the closest store
this.closestStore(point);
}
else { // Otherwise we can reset all our filters and inputs and put the locator in a neighborhood state
$('#closest-store').fadeOut('fast');
$('#store-closest').fadeOut('fast');
this.filters = [];
$("#map-filters input").prop('checked', false); // resets the filter checkboxes
this.isNeighborhood = true;
this.theNeighborhood = searchBounds;
map.fitBounds(this.theNeighborhood);
}
},
runNeighborhood: function() {
map.fitBounds(this.theNeighborhood);
for (let i = 0; i < locator.markers.length; i++) {
if (checkDistance(i)) {
$('#no-stores').fadeOut('fast');
$('#closest-store').fadeOut('fast');
locator.markers[i].setMap(map);
$(".store").eq(i + 1).fadeIn('fast');
// uncomment if .eq is not working. Slower but more reliable. $("#store-" + i).fadeIn('fast');
}
}
},
/*
This function is used if we searched a valid neighbrohood but nothing came up. We want the user to know what the closest store is.
This acts like allMarkers except it sets the map in the spot over the closest store, and prepends that data to the stores container
so it shows up first.
*/
closestStore: function(point) {
$("#map-error").fadeOut('fast');
$('#no-stores').fadeOut('fast');
$("#map-filters input").prop('checked', false); // Make sure filters are unchecked.
$('#closest-store').fadeIn('fast');
this.filters = [];
this.isNeighborhood = false;
this.bounds = new google.maps.LatLngBounds()
let length = locator.markers.length;
let i;
let dist = 1000000000000000000000;
let marker = null;
let lastMarker = null;
let content;
for (i = 0; i < length; i++) {
thisDist = google.maps.geometry.spherical.computeDistanceBetween(point, this.markers[i].position);
if (thisDist < dist) {
dist = thisDist;
if (marker === null) {
marker = i;
}
else {
lastMarker = marker;
marker = i;
}
}
this.markers[i].setMap(null);
$(".store").eq(i + 1).fadeOut('fast');
// uncomment if .eq is not working. Slower but more reliable. $("#store-" + i).fadeOut('fast');
}
content = $('.store').eq(marker + 1).html();
$('#store-closest').html(content);
$('#store-closest').fadeIn('fast');
this.markers[marker].setMap(map);
this.bounds.extend(this.markers[marker].position);
for (i = 0; i < length; i++) {
if (lastMarker != null && i === lastMarker) { // Do not fade in the store in the regular index, it has been prepended
this.markers[i].setMap(map);
$(".store").eq(i + 1).fadeIn('fast');
// uncomment if .eq is not working. Slower but more reliable. $("#store-" + i).fadeIn('fast');
this.bounds.extend(this.markers[i].position);
}
}
map.fitBounds(this.bounds);
}
}
// AJAX builder functions
// getAtts basically cleans up the data returned from the api
function getAtts(location) {
return [
location.title.toLowerCase(),
location.address.toLowerCase(),
location.city.toLowerCase(),
location.state.toLowerCase(),
location.zip,
location.services
];
}
// buildMarker is called with two parameters, the origin and a google latlng object.
// It builds the google marker objects
function buildMarker(location, position) {
return new google.maps.Marker({
position: position, // The position is a google maps latlng object
title: location.title,
animation: google.maps.Animation.DROP,
infowindow: buildInfo(location),
icon: iconSRC
});
}
// buildInfo is called with just an origin
// It builds the infowindows
function buildInfo(location) {
return new google.maps.InfoWindow({
content: '<div class = info-window-content><h3>' + location.title + '</h3><p>' + location.address + '<br>' + location.city + ', ' + location.state + ' ' + location.zip + '</p></div>'
});
}
// buildDiv is passed an origin and a number to set the id
// It builds the divs for the stores
function buildDiv(location, number) {
let div = ('<div class="store" id = "store-' + (number) + '">'); // Id for reference starts at 0
div += ('<div class = "store-wrapper">');
div += ('<a href = "#" class = "icon-link" alt = "' + location.title + '" title = "Map Info"><img src = "//www.bartelldrugs.com/content/themes/btd/images/btd-marker.png"></a>');
div += ('<h2 class = "store-title"><a href = "' + location.link + '">' + location.title + '</a></h2>');
div += ('<address class = "store-data">' + location.address + ', ' + location.city + ', ' + location.state + ' ' + location.zip + '</address>');
div += ('<p class = "store-data">' + phone + '</p>');
if (location.services.length != 0) { // Only add this if the store has services
div += ('<span class = "services-list">');
for (let i = 0; i < location.services.length; i++) {
if (i != location.services.length - 1) {
div += (location.services[i] + ' | ');
}
else {
div += location.services[i];
}
}
div += ('</span>');
}
else {
div += ('<div style = "height:10px;"></div>'); // Needed to keep spacing if the store has no services
}
div += ('<a class = "store-button" href = "' + location.link + '" title = "' + location.title + '">Store Details</a>');
div += ('</div></div>');
return div;
}
// This function will be called once to check if the user entered the page with a search term
var getQueryVariable = function() {
let query = window.location.search.substring(1);
if (query != '') {
if (query.indexOf('=') == -1) {
return false;
}
else {
let vars = query.split("&"); // Pull the query
let queryTerms = {};
let numFilters = 1;
for (let i = 0; i < vars.length; i++) {
let term = vars[i].split('=');
if (term[0] == 'filter') {
term[0] = term[0] + numFilters;
numFilters++;
}
if (term[1].indexOf('%20') > -1) { // If there are multiple words in the query replace the % symbol with a space
term[1] = term[1].replace('%20', ' ');
}
queryTerms[term[0]] = term[1];
}
return queryTerms;
}
}
return false;
}
// Input checks
function checkInput(value) {
if (value.length < 3) { // We don't want to search if there are less than four characters
return false;
}
let length = locator.stores.length;
/*
The following code is merely checking all the stores in
the locator.stores array to see if the search term matches any store. The first condition
checks to see if any store name contains the term. The second condition checks if any store
city contains the term. The third checks if any store states contains the term, which is a
little unecessary but better to account for it. The fourth checks if any store zip code
matches the term exactly.
*/
for (let i = 0; i < length; i++) {
if (locator.stores[i][0].indexOf(value) > -1 || locator.stores[i][1].indexOf(value) > -1 || locator.stores[i][2].indexOf(value) > -1 || locator.stores[i][4] == value) {
locator.isNeighborhood = false;
return true;
}
}
return false;
}
/*
This is the crux of the filtering process. This function is passed an index because it is run on every store.
The store at the index is run through much the same filtering process as the search check. This time though each
store goes through every item in the filters array.
1. Does the store name contain the filter?
2. Does the store city contain the filter?
3. Does the store state contain the filter?
4. Does the store zip match the filter?
5. Does the store have a servce (in the services array) that matches the filter?
*/
function checkFilters(index) {
for (let count = 0; count < locator.filters.length; count++) {
if (!(locator.stores[index][0].indexOf(locator.filters[count]) > -1 || locator.stores[index][1].indexOf(locator.filters[count]) > -1 || locator.stores[index][2].indexOf(locator.filters[count]) > -1 || locator.stores[index][4] == locator.filters[count] || locator.stores[index][5].indexOf(locator.filters[count]) > -1)) {
return false;
}
}
return true;
}
// Used in a neighborhood state, this is run alongside checkFilters to ensure the store
// being checked is also within the boundaries of the neighborhood
function checkDistance(index) {
if (locator.theNeighborhood.contains(locator.markers[index].position)) { // The bounds are set by the neighborhood returned by google
return true;
}
return false;
}
/*
Radius is used when the filtering only returns one result. A point is given which is the latlng position
of the marker filtered and then miles are given depending on the size of the radius desiren. The index of the
marker filtered is given so as not filter it again, and items returned are added to.
*/
// allMarkers is a simple function to reset the map and locator object
function allMarkers(){
$('#store-closest').fadeOut('fast');
$("#map-error").fadeOut('fast');
$('#closest-store').fadeOut('fast');
$('#no-stores').fadeOut('fast');
$("#map-filters input").prop('checked', false); // Make sure filters are unchecked.
locator.filters = [];
locator.isNeighborhood = false;
let length = locator.markers.length;
let i;
for (i = 0; i < length; i++) {
locator.markers[i].setMap(map);
$(".store").eq(i + 1).fadeIn('fast');
// uncomment if .eq is not working. Slower but more reliable. $("#store-" + i).fadeIn('fast');
locator.bounds.extend(locator.markers[i].position);
}
map.fitBounds(locator.bounds);
}
/*
newFilter is called every time a search term matches a store or a new filter is checked.
It is also called if a filter is unchecked. It runs every store against the new set
of filters array.
*/
function newFilter() {
$('#store-closest').fadeOut('fast');
$('#map-error').fadeOut('fast'); // We can fade out the error since newFilter is only called if there is something to show
locator.bounds = new google.maps.LatLngBounds(); // reset bounds
let items = 0; // Keep a tally of items in case we need to run radius
let lastIndex; // Keep track of last index used for radius
function radius(point, miles, index) {
for (let i = 0; i < locator.stores.length; i++) {
if (i != index) { // Don't want to refilter the previous marker
var distance = google.maps.geometry.spherical.computeDistanceBetween(locator.markers[i].position, point); // Google maps function to calcualte distance
if (distance <= miles) {
items++;
$('#store-closest').fadeOut('fast');
$('#closest-store').fadeOut('fast');
$('#no-stores').fadeOut('fast');
locator.markers[i].setMap(map);
$(".store").eq(i + 1).fadeIn('fast');
locator.bounds.extend(locator.markers[i].position);
}
}
}
}
if (locator.isNeighborhood) { // If the locator is in a neighborhood state then we much check filters and distance to neighborhood
for (let i = 0; i < locator.markers.length; i++) {
if (checkFilters(i) && checkDistance(i)) {
$('#no-stores').fadeOut('fast');
$('#closest-store').fadeOut('fast');
locator.markers[i].setMap(map);
$(".store").eq(i + 1).fadeIn('fast');
// uncomment if .eq is not working. Slower but more reliable. $("#store-" + i).fadeIn('fast');
locator.bounds.extend(locator.markers[i].position);
items++;
lastIndex = i;
}
else {
locator.markers[i].setMap(null);
$(".store").eq(i + 1).fadeOut('fast');
// uncomment if .eq is not working. Slower but more reliable. $("#store-" + i).fadeOut('fast');
}
map.fitBounds(locator.bounds);
}
}
else { // We only need to check filters if in a regular state
for (let i = 0; i < locator.markers.length; i++) {
if (checkFilters(i)) {
$('#no-stores').fadeOut('fast'); // We can fade this out since we'll have something to show
$('#closest-store').fadeOut('fast');
$(".store").eq(i + 1).fadeIn('fast');
// uncomment if .eq is not working. Slower but more reliable. $("#store-" + i).fadeIn('fast');
locator.markers[i].setMap(map);
locator.bounds.extend(locator.markers[i].position);
items++;
lastIndex = i;
}
else {
locator.markers[i].setMap(null);
$(".store").eq(i + 1).fadeOut('fast');
// uncomment if .eq is not working. Slower but more reliable. $("#store-" + i).fadeOut('fast');
}
map.fitBounds(locator.bounds);
}
}
if (items === 0) { // If no items we want to center the map and zoom out with the error messages
map.setCenter(locator.center);
map.setZoom(8);
$('#map-error').fadeIn('fast');
$('#no-stores').fadeIn('fast');
}
else if (items === 1) {
if (!locator.isNeighborhood) { // If only one item returned and not in neighborhood state we run radius
radius(locator.markers[lastIndex].position, 3220, lastIndex); // 3220 yards is used for 2 miles
if (items === 1) { // If nothing is within the radius then center on the one store
//map.setCenter(locator.bounds);
map.setZoom(15);
}
else { // If other stars are within the radius we can resize the map
map.fitBounds(locator.bounds);
}
}
else { // Do not run radius if in neighborhood state
map.setZoom(14);
}
}
else { // If many items are returned then simply resize the map
map.fitBounds(locator.bounds);
}
}
// Call locator build and run marker init
$.when(locator.build(), locator.isHoliday()).then(function(buildResult, holidayResult) {
if (typeof(holidayResult) === 'object') {
for (let i = 0; i < holidayResult.length; i ++) {
if (locator.date == holidayResult[i].date) {
locator.holidayHours = holidayResult[i];
}
}
}
else {
}
var length = buildResult.length;
var stores = '';
var latlng;
for (let i = 0; i < length; i++) {
latlng = new google.maps.LatLng(buildResult[i].latitude, buildResult[i].longitude); // create a new latlng object with each store
locator.stores.push(getAtts(buildResult[i])); // Create a new store array with the meta and push it
locator.markers.push(buildMarker(buildResult[i], latlng)); // create a new marker and push it
locator.markers[i].addListener('click', function() { // Add an event listener that opens the store's infowindow on click
this.infowindow.open(map, this);
});
locator.bounds.extend(latlng); // Extend the map boundaries
stores += buildDiv(buildResult[i], i); // Add a new store div
}
// Append the stores to the parent store div, remove the spinner background, and fade in the map.
$('#store-locations').append(stores + '<div id = "no-stores" class = "store"><p>Sorry, no stores match that criteria. Try entering a new search term or reducing your filters.</p></div>').css('background-image', 'none');
$('#map-wrapper').css('background-image', 'none');
$('#map').fadeTo('.3', 1);
// check for a query
let query = getQueryVariable();
if (query) {
if (query['storesearch']) {
$('#map-search-input').val(query.storesearch); // Give the user feedback
if (checkInput(query.storesearch)) { // Here we basically run newFilters without the need to fade anything out
locator.formVal = query.storesearch;
let items = 0; // Keep a tally of items in case we need to run radius
let lastIndex; // Keep track of last index used for radius
locator.bounds = new google.maps.LatLngBounds();
locator.filters.push(query.storesearch);
for (let i = 0; i < locator.stores.length; i++) {
if (checkFilters(i)) {
$('#no-stores').fadeOut('fast');
$(".store").eq(i + 1).fadeIn('fast');
// uncomment if .eq is not working. Slower but more reliable. $("#store-" + i).fadeIn('fast');
locator.markers[i].setMap(map);
locator.bounds.extend(locator.markers[i].position);
items++;
lastIndex = i;
}
}
if (items === 1) {
radius(locator.markers[lastIndex].position, 3220, lastIndex); // 3220 yards is used for 2 miles
if (items === 1) { // If nothing is within the radius then center on the one store
//map.setCenter(locator.bounds);
map.setZoom(15);
}
else { // If other stars are within the radius we can resize the map
map.fitBounds(locator.bounds);
}
}
else {
map.fitBounds(locator.bounds);
}
if (query['filter1']) {
for (var prop in query) {
if (prop.indexOf('filter') > -1) {
let filter = query[prop];
if ($('input#' + filter).length > 0) {
let filterValue = filter.split('-');
let newValue = '';
for (let i = 0; i < filterValue.length; i++) {
if (filterValue[0] == 'care') {
newValue = 'CareClinic';
}
else if (filterValue[0] == 'drive') {
newValue = 'Drive-Thru Pharmacy';
}
else {
newValue += filterValue[i].charAt(0).toUpperCase() + filterValue[i].slice(1);
if (i != filterValue.length - 1) {
newValue += ' ';
}
}
}
$('input#' + filter).prop('checked', true);
locator.filters.push(newValue);
}
}
}
setTimeout(function(){
newFilter();
}, 500);
}
}
else {
$.when(locator.getNeighborhood(query.storesearch)).then(function(theResult) {
if (theResult.status === 'ZERO_RESULTS' || theResult.results[0].types[0] === 'premise' || theResult.results[0].types[0] === 'subpremise') {
allMarkers();
error.fadeIn('fast');
}
else if (theResult.results[0].address_components[0].short_name === 'WA') {
allMarkers();
}
else {
let point = new google.maps.LatLng(theResult.results[0].geometry.location.lat, theResult.results[0].geometry.location.lng);
if (!locator.WABounds.contains(point)) {
allMarkers();
error.fadeIn('fast');
}
else {
error.fadeOut('fast');
locator.buildNeighborhood(theResult.results[0]);
}
}
if (query['filter1']) {
for (var prop in query) {
if (prop.indexOf('filter') > -1) {
let filter = query[prop];
if ($('input#' + filter).length > 0) {
let filterValue = filter.split('-');
let newValue = '';
for (let i = 0; i < filterValue.length; i++) {
if (filterValue[0] == 'care') {
newValue = 'CareClinic';
}
else if (filterValue[0] == 'drive') {
newValue = 'Drive-Thru Pharmacy';
}
else {
newValue += filterValue[i].charAt(0).toUpperCase() + filterValue[i].slice(1);
if (i != filterValue.length - 1) {
newValue += ' ';
}
}
}
$('input#' + filter).prop('checked', true);
locator.filters.push(newValue);
}
}
}
setTimeout(function(){
newFilter();
}, 500);
}
});
} // If checkInput(query)
}
else {
allMarkers();
if (query['filter1']) {
for (var prop in query) {
if (prop.indexOf('filter') > -1) {
let filter = query[prop];
if ($('input#' + filter).length > 0) {
let filterValue = filter.split('-');
let newValue = '';
for (let i = 0; i < filterValue.length; i++) {
if (filterValue[0] == 'care') {
newValue = 'CareClinic';
}
else if (filterValue[0] == 'drive') {
newValue = 'Drive-Thru Pharmacy';
}
else {
newValue += filterValue[i].charAt(0).toUpperCase() + filterValue[i].slice(1);
if (i != filterValue.length - 1) {
newValue += ' ';
}
}
}
$('input#' + filter).prop('checked', true);
locator.filters.push(newValue);
}
}
}
setTimeout(function(){
newFilter();
}, 500);
}
}
} // If query
else {
allMarkers();
}
let search = $('#map-search'); // search input
let error = $('#map-error');
let inputs = $('#map-filters input'); // filters checkboxes
// here we add an event lisenter on the search input
search.on('submit', function(e) {
e.preventDefault();
let val = $('#map-search-input').val().toLowerCase(); // User feedback
if (val == '') { // We want to reset the locator and filters if the user enters a blank search
allMarkers();
}
else if (!checkInput(val)) { // If search term doesn't match any stores
$.when(locator.getNeighborhood(val)).then(function(theResult) {
if (theResult.status === 'ZERO_RESULTS' || theResult.results[0].types[0] === 'premise' || theResult.results[0].types[0] === 'subpremise') {
allMarkers();
error.fadeIn('fast');
}
else {
let point = new google.maps.LatLng(theResult.results[0].geometry.location.lat, theResult.results[0].geometry.location.lng);
if (!locator.WABounds.contains(point)) {
allMarkers();
error.fadeIn('fast');
}
else {
error.fadeOut('fast');
locator.buildNeighborhood(theResult.results[0]);
}
}
});
}
else { // If the search term matches a store
if (!locator.formVal) { // If there hasn't been a search before
locator.filters.push(val);
newFilter(val);
locator.formVal = val; // Store the search term for later use
}
else { // If there has been a previous search, we want to overwrite it be removing the previous filter and adding a new one. Only one search filter at a time.
let valIndex = locator.filters.indexOf(locator.formVal);
locator.filters.splice(valIndex, 1); // Remove the search term stored in locator.formVal.
locator.filters.push(val);
newFilter();
locator.formVal = val; // Reset formVal to new term.
}
}
});
//here we add an event listener to the filters
inputs.on('change', function(){
let val = $(this).val();
if (this.checked) { // If the filter has been checked
locator.filters.push(val);
newFilter(val);
}
else { // If the filter has been unchecked remove the filter from locator.filters
let index = locator.filters.indexOf(val);
locator.filters.splice(index, 1);
if (locator.filters.length == 0) { // If the filters array becomes empty we want to reset the map
if (!locator.isNeighborhood) {
allMarkers();
}
else {
locator.runNeighborhood();
}
}
else {
newFilter();
}
}
});
// Here we add an event listener inside the icon in each store div that opens the corresponding markers infowindow.
$(".icon-link").on('click', function(e){
e.preventDefault();
var number = $(this).closest('.store').index();
new google.maps.event.trigger(locator.markers[number], 'click');
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment