Skip to content

Instantly share code, notes, and snippets.

@kirikintha
Created January 17, 2014 17:30
Show Gist options
  • Save kirikintha/8477629 to your computer and use it in GitHub Desktop.
Save kirikintha/8477629 to your computer and use it in GitHub Desktop.
This is a quick example of implementing a very generic Drupal behavior. They key here is to use attach. Drupal behaviors can be a tad maddening, but because it is in a closure, you don't have to use $(document).ready(); Instead of using the location or mapping modules for maps, we output the markers through our module, based on the Geo Field API.
/*
* My Module Api JS.
*/
(function ($) {
//Property Api Behavior
Drupal.behaviors.myModuleApi = {
attach: function (context, settings) {
//Check for Geo Location.
context = $('body.page-search-properties');
if (context.length > 0) {
//Get Geolocation.
if (settings.geoCode != undefined) {
if (settings.geoCode == true) {
Drupal.behaviors.myModuleApi._getGeoLocation(context);
}
}
//Attach GeoLocation to use an address.
var container = $('button#geo-coder', context);
if (container.length > 0) {
container.on('click', function () {
var target = $('#edit-field-geo-codelatlon-location', context);
var args = {
'@address' : target.val()
};
Drupal.behaviors.myModuleApi._geoCoderAddress(target, args);
});
}
//If we have markers, then make a map.
var resultsMap = $('div#gmap', context);
if (resultsMap.length > 0
&& settings.markers != undefined) {
google.maps.event.addDomListener(window, 'load', Drupal.behaviors.propertyApi._map(settings));
}
}
},
//Geo Location, for browsers that support geolocation
_getGeoLocation : function (context) {
var target = $('#edit-field-geo-codelatlon-location', context);
if (target.length > 0
&& target.val() == '') {
//If we can geolocate.
if (navigator.geolocation != undefined) {
navigator.geolocation.getCurrentPosition(function (position) {
var location = position.coords;
var args = {
'@lat' : location.latitude.toFixed(4),
'@long' : location.longitude.toFixed(4)
};
//Geocoder.
Drupal.behaviors.myModuleApi._geoCoderLatLon(target, args);
}, function (error) {
var MSG = '';
switch(error.code) {
case error.PERMISSION_DENIED:
MSG = 'User denied the request for Geolocation.';
break;
case error.POSITION_UNAVAILABLE:
MSG = 'Location information is unavailable.';
break;
case error.TIMEOUT:
MSG = 'The request to get user location timed out.';
break;
case error.UNKNOWN_ERROR:
MSG = 'An unknown error occurred, please try again.';
break;
default:
MSG = 'An unknown error occurred, please try again.';
break;
}
//Set error message.
target.closest('div.form-item').append(Drupal.t('<span id="loc-info" class="text-danger">@msg</span>', {
'@msg' : MSG
}));
});
} else {
target.closest('div.form-item').append(Drupal.t('<span id="loc-info" class="text-muted">Please enter your location to continue.</span>'));
}
}
},
//GeoCoder.
_geoCoderLatLon : function (context, args) {
//Call out to google geocoder, if we do not have a value entered.
var geoCoder = 'http://maps.googleapis.com/maps/api/geocode/json?latlng='+Drupal.t('@lat,@long', args)+'&sensor=false';
Drupal.behaviors.myModuleApi._geoCoder(context, geoCoder);
},
//Geocoder by Address.
_geoCoderAddress : function (context, args) {
var geoCoder = 'http://maps.googleapis.com/maps/api/geocode/json?address='+Drupal.t('@address', args)+'&sensor=false';
Drupal.behaviors.myModuleApi._geoCoder(context, geoCoder);
},
_geoCoder : function (context, uri) {
//Append your lcoation.
var target = context.closest('div.form-item').removeClass('error');
$('span#loc-info', target).remove();
target.append('<span id="loc-info" class="text-info">Geocoding started.</span>');
//Run our get.
$.get(uri, function(data, status) {
if (status == 'success') {
if (data.results != undefined
&& data.status != undefined) {
if (data.status == 'OK') {
for (key in data.results) {
var result = data.results[key];
if (result.types[0] == 'locality') {
context.val(result.formatted_address);
$('span#loc-info', target).text('Geocode finished.')
.removeClass('text-info')
.addClass('text-success');
}
}
} else {
//If we have an error, flag it
$('span#loc-info', target).text('Geocode finished, could not find your location.')
.removeClass('text-info')
.addClass('text-danger');
context.val('');
target.addClass('error');
}
}
}
});
},
//Create A map. This is nice an re-usable.
//Settings is an object that contains markers.
_map : function (settings) {
var iconBase = 'https://maps.google.com/mapfiles/kml/pal3/';
var markers = [];
//Create map options.
var myLocation = new google.maps.LatLng(settings.markers[0].lat, settings.markers[0].lon);
var mapOptions = {
center: myLocation,
mapTypeId : google.maps.MapTypeId.ROADMAP,
maxZoom: 14
};
var map = new google.maps.Map(document.getElementById("gmap"),
mapOptions);
// Create a new viewpoint bound
var bounds = new google.maps.LatLngBounds();
//Create inforbox values.
var ibOptions = {
content: '',
disableAutoPan: false,
maxWidth: 0,
pixelOffset: new google.maps.Size(-140, 0),
zIndex: null,
boxStyle: {
background: "url('tipbox.gif') no-repeat",
opacity: 1,
width: "280px"
},
closeBoxMargin: "5px",
closeBoxURL: "http://www.google.com/intl/en_us/mapfiles/close.gif",
infoBoxClearance: new google.maps.Size(1, 1),
isHidden: false,
pane: "floatPane",
enableEventPropagation: false
};
var ib = new InfoBox(ibOptions);
//Add markers.
$.each(settings.markers, function (index, value) {
//switch between types of icons.
var markerIcon = null;
switch (index) {
//Zero is always your location.
case 0:
markerIcon = iconBase + 'icon28.png';
break;
default:
//This is a transparent icon
markerIcon = {
path: '',
strokeColor: '#FF0000',
strokeOpacity: 0.25,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.1
};
break;
}
var latlon = new google.maps.LatLng(value.lat,value.lon);
//Extend Bounds.
bounds.extend(latlon);
//Create Marker.
var marker = new google.maps.Marker({
icon : markerIcon,
position: latlon,
map: map,
title: Drupal.t('@title', {'@title' : value.title}),
zIndex: index
});
//push marker to markers.
markers.push(marker);
//Info box.
var boxContent = document.createElement("div");
boxContent.className = 'well';
boxContent.innerHTML = '<address>'+value.address+'</address>';
if (value.link != undefined) {
boxContent.innerHTML += value.link;
}
//Add click listener
google.maps.event.addListener(marker, "click", function (e) {
ib.close();
ib.setContent(boxContent);
ib.open(map, this);
});
});
//When we click the map, we close all infoboxes.
google.maps.event.addListener(map, "click", function (e) {
ib.close();
});
//Change paths for each circle, depending on zoom.
google.maps.event.addListener(map, 'zoom_changed', function() {
var zoom = map.getZoom();
$.each(markers, function (index, marker) {
//First index is always our current location.
if (index > 0) {
//Get marker icon.
var icon = marker.getIcon();
//Switch between zoom levels.
if (zoom >= 0 && zoom <= 5) {
icon.path = 'M 0,0 m -5, 0 a 5,5 0 1,0 10,0 a 5,5 0 1,0 -10,0';
} else if (zoom >= 6 && zoom <= 10) {
icon.path = 'M 0,0 m -9, 0 a 9,9 0 1,0 18,0 a 9,9 0 1,0 -18,0';
} else if (zoom >= 11 && zoom <= 15) {
icon.path = 'M 0,0 m -13, 0 a 13,13 0 1,0 26,0 a 13,13 0 1,0 -26,0';
} else if (zoom >= 15 && zoom < 20) {
icon.path = 'M 0,0 m -17, 0 a 17,17 0 1,0 34,0 a 17,17 0 1,0 -34,0';
}
//Set new marker.
marker.setIcon(icon);
}
});
});
//Add a radius circle if we are 5 kilomters or over.
if (settings.radius > 0) {
var radiusOptions = {
strokeColor: '#000000',
strokeOpacity: 0.25,
strokeWeight: 2,
fillColor: '#000000',
fillOpacity: 0.1,
map: map,
center: myLocation,
radius: (settings.radius * 1000) // 1 Kilometer == 1000 meters
};
// Add the circle for this city to the map.
var locationCircle = new google.maps.Circle(radiusOptions);
var circleBounds = locationCircle.getBounds();
var ne = circleBounds.getNorthEast();
bounds.extend(ne);
var sw = circleBounds.getSouthWest();
bounds.extend(sw);
}
//Fit these bounds to the map
map.fitBounds(bounds);
}
};
//End.
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment