Last couple of weeks I’ve been playing around with jQuery UI. As a framework it’s a pretty nice way to add a bit of structure to your code. At the heart of this framework is The Widget Factory, which is a sort of template for building your component (visual or not).
To give quick run through of how to build stuff using widgets, I’m going to build a Flashcard Widget. A flashcard is a simple learning aid to test your memory. One side of the card presents a question and the other has the answer to that question. This is what we are going to build:
Just click on the card to see the answer. I’ve used a definition list for html as shown below. Gave the the container (<dl>) a width and a height and made <dt> and <dd> 100% for both width and height and absolute positioned them on top of each other.
HTML
<dl id="myFlashcard">
<dt>Who ya gonna call?</dt>
<dd>GHOSTBUSTERS!</dd>
</dl>
CSS
/* a bit simplyfied */
.ui-flashcard {
height: 150px;
position: relative;
width: 350px;
}
.ui-flashcard dt,
.ui-flashcard dd {
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
.ui-flashcard dd {
z-index: -1;
}
Now let’s add some behavior to our widget! If you ever create class definition in a programming language (like PHP for example) a widget is a lot like that. To define a widget type you use the .widget method like: $.widget("ui.flashcard", { /* definition */ }). You’ve got a method _create which is called on creation and _destroy is called on destruction to cleanup. Just like the constructor and deconstructor.
Applying a widget (like creating an instance) is the same as using a plugin: $("#myFlashcard").flashcard({ /* options */ }).
Now lets add some classes to our html (using the widget) which can later be used to make it pretty for example:
JS
$.widget("ui.flashcard", {
_create: function() {
this.element
.addClass("ui-flashcard ui-widget")
.find("dt, dd")
.addClass("ui-widget-content ui-corner-all")
;
},
_destroy: function() {
this.element
.removeClass("ui-flashcard ui-widget ui-corner-all")
.find("dt, dd")
.addClass("ui-widget-content")
;
}
});
Now for letting it actually do something we create a method called show, as in “show me the answer please”. Here we simple fade out the <dt> so the answer (<dd>) becomes visible.
JS
show: function() {
this.element.find("dt").fadeOut("slow");
},
This can now be called with: $("#myFlashcard").flashcard("show"). We can also bind this to a custom event called “show” like:
JS _create: function() { var widget = this; this.element .bind(“show”, function() { widget.show(); }) ; },
Now to finish things we bind the “click” event on <dt> to our “show” event and we got a working flashcard widget!
JS
_create: function() {
var widget = this;
this.element
.find("dt")
.click(function() {
widget.element.trigger("show");
})
;
},
Here is the final widget code and I also created a gist of the full example. And the story continues at: It’s nice to have some options, in your custom UI Widget that is!