Created
September 17, 2010 17:36
-
-
Save cschneid/584609 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Widget that tracks the state of a togglable item. To toggle, click on the | |
* item. No visible action is taken directly, but events and callbacks are | |
* fired (via _trigger()) so that callbacks may change state | |
*/ | |
$.widget("ui.toggle", { | |
/* | |
* Constructor -- attach a click handler which calls the toggle() function. | |
*/ | |
_init: function(){ | |
/* Helpful variables to get scope correct in callbacks */ | |
var toggle = this; | |
var $toggle = this.element; | |
/* | |
* We need to default the state. As an enhancement to this widget, I'd | |
* allow the user to pass in an option defining the initial state this | |
* widget is in. | |
*/ | |
toggle._setState(true); | |
/* | |
* The click handler is very simple. I use an anonymous function here | |
* so that the scope inside toggle() is correct. | |
* | |
* As a (WRONG / NOT WORKING) example, if you did this: | |
* $toggle.click(this.toggle); | |
* | |
* Then, when the toggle function gets run, the definition of the `this` | |
* variable will not be this widget, but instead will be the click event | |
* context. Which is rarely what you want. | |
* | |
* An alternate way of doing this correctly is to use jQuery's proxy function. | |
* $toggle.click($.proxy(this, "toggle")); | |
* | |
* I prefer the way that is uncommented, because I dislike defining | |
* function names via strings, and the anonymous function is going to get | |
* created either way (it's how $.proxy() works internally). | |
*/ | |
$toggle.click(function(e) { | |
toggle.toggle(e); | |
}); | |
}, | |
/* | |
* Turn this on or off, run callbacks, and fire events. | |
* | |
* The _trigger() function is builtin to jQuery widgets. It does a few things. | |
* First it attempts to call a callback with the name provided. (change, on, | |
* off). If the function doesn't exist, nothing happens. | |
* | |
* Then it fires an event, combining the name of the widget with the passed | |
* argument. So "toggle" + "change" becomes an event named "togglechange". | |
* This event is triggered on the element itself, and bubbles as per normal | |
* javascript behaviors. So in this case, you could attach a listener to | |
* $(body) to listen for ANY toggle widget. | |
* | |
*/ | |
toggle: function(e){ | |
this._trigger("change"); | |
if (this.state() == true) | |
{ | |
this._setState(false); | |
this._trigger("off"); | |
} | |
else | |
{ | |
this._setState(true); | |
this._trigger("on"); | |
} | |
}, | |
/* Get the current state of this widget */ | |
state: function() { | |
return this.options.state; | |
}, | |
/* | |
* Set state. This is private due to the leading underscore, so the outside | |
* world can only interact with this widget via the public toggle() function. | |
*/ | |
_setState: function(state) { | |
this.options.state = state; | |
} | |
}); | |
/* | |
* A simple widget that uses the toggle functionality to change it's own color. | |
* This is a good example of how widgets can start building on each other to build out | |
*/ | |
$.widget("ui.textcolor", { | |
/* | |
* Default options. See the .ready() function for an example of how to | |
* override the defaults with your own. | |
*/ | |
options: { | |
on: "#f00", | |
off: "#0f0" | |
}, | |
/* The constructor for this widget. */ | |
_init: function(){ | |
/* Helpful variables to get scope correct in callbacks */ | |
var textcolor = this; | |
var $textcolor = this.element; | |
/* | |
* Init the toggle widget on the element that this widget is attached to | |
* (the $textcolor variable). In addition, define some callbacks so that | |
* we can take action when it gets toggled. | |
* | |
* Also note that we don't define a callback for the `toggle` action. The | |
* _trigger call in the toggle widget is smart enough to not call it if it | |
* doesn't exist. It does however still raise the event. | |
*/ | |
$textcolor.toggle({ | |
on: function(){ | |
$textcolor.css({color: textcolor.options.on}); | |
}, | |
off: function(){ | |
$textcolor.css({color: textcolor.options.off}); | |
} | |
}); | |
} | |
}); | |
/* | |
* None of the code above actually does anything to the page. The .ready() | |
* function here ties the widgets defined above onto actual DOM elements in the | |
* HTML page. | |
*/ | |
$(document).ready(function() { | |
// Init the textcolor widget on the paragraph. Note that in turn, the | |
// textcolor widget will init the toggle widget. | |
$("#color").textcolor({on: "#00f"}); | |
// We can bind to the toggle events so other items on the page can react to | |
// the toggle status | |
$("#color").bind('togglechange', function() { /* ... */ }); | |
$("#color").bind('toggleon', function() { /* ... */ }); | |
$("#color").bind('toggleoff', function() { /* ... */ }); | |
// We can find out what the current status is by asking. | |
// This will return true/false | |
$("#color").toggle("state"); | |
}); | |
/* | |
* The HTML for this example is super simple: | |
* | |
* <html> | |
* <head> | |
* <script type="text/javascript" src="jquery.js"></script> | |
* <script type="text/javascript" src="jquery-ui.js"></script> | |
* </head> | |
* <body> | |
* <p id="#color">Toggle Me!</p> | |
* </body> | |
* </html> | |
* | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment