Adding custom method calls to the jQuery Rambling Slider
November 12, 2011
This post was originally published in the Rambling Labs Blog on November 12, 2011.
The jQuery Rambling Slider v0.1.2 was released a couple of days ago. One of the features added was the ability to start and stop the slider like this:
$('#slider').ramblingSlider('stop');
$('#slider').ramblingSlider('start');
Every serious jQuery plugin has some way to change it’s behaviour or query some data after initialized and the general approach for this is calling the custom methods as showed above.
It is well known that in order to do this, you have to perform some dynamic method calling magic. This is what you find in the jQuery documentation:
(function($){
var methods = {
init : function(options) { /*...*/ },
show : function() { /*...*/ },
hide : function( ) { /*...*/ },
update : function(content) { /*...*/ },
};
$.fn.tooltip = function(method) {
// Method calling logic
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call( arguments, 1 ));
} else if (typeof method === 'object' || !method) {
return methods.init.apply(this, arguments);
} else {
$.error('Method ' + method + ' does not exist on jQuery.tooltip');
}
};
})(jQuery);
And this is the way I implemented it:
(($) ->
publicMethods = ['stop', 'start', 'option', 'effect']
$.fn.ramblingSlider = (options, others...) ->
methodExists = options in publicMethods
optionsIsString = (typeof options) is 'string'
ramblingSlider = @data 'rambling:slider'
isCallingGetter = (others) -> not others.length or (others.length is 1 and typeof(others[0]) is 'string')
if ramblingSlider
return if methodExists
value = ramblingSlider[options](others...)
if isCallingGetter others
value
else
@
else
if optionsIsString
$.error "Method '#{options}' not found."
else
$.error "Slider already initialized." if options
else
return $.error "Tried to call method '#{options}' on element without slider." if methodExists or optionsIsString
@each (key, value) ->
element = $ @
return if element.data 'rambling:slider'
ramblingSlider = new RamblingSlider @, options
element.data 'rambling:slider', ramblingSlider
ramblingSlider.initialize()
ramblingSlider.run()
RamblingSlider = (element, options) ->
###
# Method definitions
###
)(jQuery)
Kind of cumbersome if you ask me, but hey, it works :P. The cool stuff is that I added the option
and effect
methods, as well as identifying if it’s a setting or getting the value. This is great because I can have kind of private setters and public getters:
//Stop and start are really setters
$('#slider').ramblingSlider('stop'); // => [div#slider] for method chaining
$('#slider').ramblingSlider('start'); // => [div#slider] for method chaining
$('#slider').ramblingSlider('effect'); // => 'random'
$('#slider').ramblingSlider('option'); // => Object with all options
$('#slider').ramblingSlider('option', 'speed'); // => 400
$('#slider').ramblingSlider('effect', 'boxRain'); // => [div#slider] for method chaining
$('#slider').ramblingSlider('option', 'speed', 600); // => [div#slider] for method chaining
$('#slider').ramblingSlider('option', 'startSlide'); // => 0
$('#slider').ramblingSlider('option', 'startSlide', 2); // => throws error "Slider already running. Option 'startSlide' cannot be changed."
Note that the option slideStart
can only be passed when initializing, so it becomes a readonly option after initialized.
Cool huh?