Contents |
Please try to indent code using tabs only. It makes work much easier, because you can change your own tab size in your own editor if the indenting is too large for your view. But it's not so easy to change whitespace indents.
ui.core.js provides a factory method to create widget classes. The signature is $.widget(name, Options prototype).
Calling the factory creates a plugin method used to create and interact with an instance of that widget class.
Available methods for each instance, in addition to those provided by the prototype argument:
Available properties for each instance:
Usage:
$.widget("ui.mywidget", {
init: function() {
// init code for mywidget
// can use this.options
if (this.options.hidden) {
// and this.element
this.element.hide();
}
},
doSomething: function() {
// manipulate the widget
},
value: function() {
// calculate some value and return it
return calculate();
},
length: function() {
return someOtherValue();
}
});
$.ui.mywidget.getter = "value length";
$.ui.mywidget.defaults = {
option1: "defaultValue",
option2: 123
};
Every UI plugin uses the widget factory, so for full references, check out any code from UI, eg. ui.sortable.js
Please think about possible callbacks wherever possible. They should be named closer to jQuery-style, instead of DOM like, draggable for instance has the following callbacks:
and would be bound to like so:
{
start: function(){},
drag: function(){},
stop: function(){}
}
Rather than using your own functions to call these callbacks, jQuery's trigger method was updated for UI to makes life easier and should be used all over the place:
$(this.element).triggerHandler(longname, [e, obj], this.options[name])
where longname is the callback's name together with a prefix (action of your plugin) (i.e. "dragstart"), this.element is the current element, e is the browser event, and obj should be an object holding your own key/value pairs that you want to pass to the callback. this.options[name] is the user's callback function (so this would be without prefix).
In case of resizables, this would be:
$(this.element).triggerHandler('resizestop', [e,that.prepareCallbackObj(this)], o.stop);
that.prepareCallbackObj is only a convenience method that prepares the object. The user's function supplied with the callback now gets unified arguments: the first argument is the browser event (e), the second argument is the object.
Please look at one of the mouse interaction implementations (Resizables for example) to get a direct view how to implement this stuff.
All plugins related to mouse interaction make use of another class, the mouse interaction class. It basically handles all events (mousedown,mouseup,mousemove) and bindings, and you can use private callbacks to then do something with the new mouse position (move the element for example).
Look at the implementation of draggables/resizables for a self-explanatory view.
Coming soon!
Coming soon!
Please try to use a object oriented structure wherever it makes sense. Look at drag & drop for how it's made - without using prototypes in Draggables, I would have had the need to attach properties to every DOM node. It makes much more sense this way.
Please do not generate javadoc blocks for your functions and classes anymore, but write the real documentation into our wiki at UI.
Put inline comments before the line they comment and a space between the doubleslash and the comment text.
Comment the "why" things are done, not "how". The "how" is provided by the code. Document things that aren't obvious from the code.
// only left click starts dragging if (e.which != 1) return true;
In this example, it's hard to guess what this prevention is for (until you know how the e.which property works), so an explanation doesn't hurt here.