Pooper Lube Day March 6, 2012
jQuery Events Expanded March 5, 2012
Typically, when writing Javascript, you'll want to handle the click event for a certain element, or set of elements, so you can do this:
jQuery(".my-class").click(function(ev){
alert(jQuery(this).attr(id) + " was clicked");
});
What is less realized and utilized, is that you can use jQuery to add custom events to any Javascript object! This is pretty awesome. This is how it is done, in the most simple sense.
var MyObject = {
makeCall: function(){ $.ajax("http://example.com/x", { method: "GET", success: this.completed }); },
completed: function(data, status, xhr){ $(this).trigger("complete", data); }
};
In the most simple case, this can be used as follows:
$(MyObject).on("complete", function(e, data){
alert(JSON.stringify(data));
});
However, I would typically add convenience methods to the object, as follows:
var MyObject = {
... // other stuff.
onComplete: function(fn){ $(this).on("complete", fn); }
}
So now your code looks like this: MyObject.onComplete(function(e, data){ alert(JSON.stringify(data)); });
Of course, that is simply a global object. We would want to be able to allocate many instances of this, so then you change your code to this:
function MyObject(){
}
MyObject.prototype.onComplete = function(fn) { $(this).on("complete", fn); };
MyObject.prototype.makeCall = function(){ $.ajax("http://example.com/x", { method: "GET", success: this.completed } ); };
MyObject.prototype.completed = function(data, status, xhr){ $(this).trigger("complete", data); };
Or any number of ways to skin that cat.
Where I used this was in a Javascript geolocator object. So, browsers now offer an ability to geolocate the user. This is more helpful on mobile browsers, but it's also available, albeit less accurately, on desktop browsers (although, to be fair, sometimes it's dead on!). The browser may not have this ability, however, so we should offer a fallback, like enter in a zip code or address, and allow Google's Maps API to geocode it. Like so:
;(function(window){
var GeoLocation = {
locationRegex: /^[0-9\.\-,]+$/,
parse: function(str){
var coords = { latitude: 0, longitude: 0 };
// parse "y,x", return { longitude: y, latitude: x }
},
init: function(cookieName){
var self = this;
this.cookieName = cookieName;
this.on("located", function(e, coords){ self.updateLocation(coords); });
var stored = this.getStoredLocation();
if (this.checkLocation(stored))
$(self).trigger("located", stored);
},
hasStoredLocation: function(){
// check cookie
},
getStoredLocation: function(){
// get cookie as y,x call parse, return { longitude: y, latitude: x }
},
clearStoredLocation: function(){
// erase cookie
},
canGeocode: function(){
return navigator.geolocation != null && typeof (navigator.geolocation.getCurrentPosition) == "function";
},
getLocation: function(input){
var self = this;
var defaultLocation = { longitude: 0, latitude: 0 };
if (typeof(input) == "string" && input != null && input.length > 0){
var geocoder = new google.maps.Geocoder();
geocoder.geocode({address: input}, function(result, status){
if (status == google.maps.GeocoderStatus.OK){
var res = result[0];
var loc = {latitude: res.geometry.location.lat(), longitude: res.geometry.location.lng()};
$(self).trigger("located", loc);
}
else $(self).trigger("failure", defaultLocation);
});
}
else if (self.canGeocode()){
navigator.geolocation.getCurrentPosition(function(position){
$(self).trigger("located", position.coords);
}, function(error){
$(self).trigger("failure", defaultLocation);
});
}
else {
$(self).trigger("failure", defaultLocation);
}
},
checkLocation: function(coords){
return !(coords.longitude == 0 && coords.latitude == 0);
},
updateLocation: function(coords){
// store cookie
},
// use: GeoLocation.on('located', function(coords){ alert(JSON.stringify(coords)); });
on: function(ev, cb){
$(this).on(ev, cb);
}
};
window.GeoLocation = GeoLocation;
})(window);
So you can add a listener for any time that the user's location is determined, pretty much anywhere, thanks to jQuery, even without interacting with the DOM or DOM elements.
$(document).ready(function(){
GeoLocation.on("located", function(coords){
$("body").append($("<div>Located you at " + JSON.stringify(coords) + "</div>"));
});
GeoLocation.on("failure", function(coords){
$("body").append($("<div>Couldn't locate you</div>"));
});
GeoLocation.init("mysite-location-cookie");
GeoLocation.getLocation("Philadelphia, PA"); // a string parameter will cause it to invoke Google's Geocoding service.
});
Javascript is a neat, capable little language. I hope this helps display that a little bit.