Does my jQuery plugin have a weakness (pattern-wise)?
I found a plugin pattern on Internet. ( I will submit the link as soon as I find it back ) and I modified it a bit to create my own dialog plugin. I'm afraid even if the code is working, the way I made it doesn't make sense.
I must :
- Be able to assign my plugin to multiple element (more then one dialog) -Implemented
- I must be able to access it's method : openDialog, closeDialog, assignOptions from outside it's scope -Not yet implemented
- I would like to send a reference to
the current dialog when a button
click occurs - Partially implemented.
I'm using
$(this).getDialog()
method.this
refer to the clicked button
Here is the plugin :
(function($) {
var pluginName = "Dialog",
dialogContent = { "Title" : "h2", "SubTitle" : "p.sub-title", "Body" : "div.content" }
var infDialog = function( el, options ) {
var $el = $(el),
currentConfig = {
position : [100, 100],
autoOpen : true
};
$el.data( pluginName, $el);
if ( options ) {
currentConfig = $.extend( currentConfig, options );
}
$el.css({ "top" : currentConfig.position[1], "left" : currentConfig.position[0], "z-index" : 9999 });
if ( currentConfig.autoOpen ) {
$el.fadeIn( "slow" );
}
if ( currentConfig.buttons ) {
$.each(currentConfig.buttons, function(i, j) {
if ( $.isFunction( j ) && $(el).find("input[value='" + i + "']").length )
{
var $currentButton = $(el).find("input[value='" + i + "']");
$(el).find("input[value='" + i + "']").click(function() {
j.call( $currentButton );
});
}
});
}
if ( currentConfig.onOpen ) {
currentConfig.onOpen.call( $el );
}
if ( currentConfig.onClose ) {
$el.bind("onclose", function() {
currentConfig.onClose.call( $el );
});
}
$el.getDialog().bind("click", function( e ) {
var currentDialog = this.id,
currentPosition = $(this).css("z-index");
if ( currentPosition < 9999 || currentPosition == "auto" ) {
$(".dialog").each(function(i) {
if ( this.id == currentDialog ) {
$(this).css("z-index", 9999);
} else {
$(this).css("z-index", 9990);
}
});
$(this).css("z-index");
}
});
}
$.fn.infDialog = function( options ) {
return this.each(function() {
( new infDialog( this, options ) );
});
}
$.fn.closeDialog = function() {
return $(this).getDialog().fadeOut("slow", function() {
$(this).trigger("onclose");
});
}
$.开发者_运维问答fn.getDialog = function() {
return ( ! $(this).is(".dialog") ) ? $(this).closest(".dialog") : $(this);
}
$.fn.assignOption = function( options ) {
var $currentPlugin = $(this);
$.each( options, function(i, j) {
if ( dialogContent[ i ] ) {
$currentPlugin.find( dialogContent[ i ] ).empty().html( j );
}
});
}
})(jQuery);
and the HTML of a dialog :
<div id="dialogTest" class="dialog">
<div>
<h2>title</h2>
<p class="sub-title">
subtitle
</p>
<div class="content">
Content
</div>
<p class="buttons"><input type="button" value="Action" /> <input type="button" value="Close" class="normal" /></p>
</div>
</div>
and the jQuery code :
$("#dialogTest").infDialog({
position : [400, 190],
buttons : {
"Action" : function() {
var $dialog = $(this).getDialog(),
obj = $dialog.data("Dialog"),
$currentDialog = $(this).getDialog();
$currentDialog.assignOption({
"Title" : "New Title",
"SubTitle" : "Lorem ipsum",
"Bob" : "unknown body tag",
"Body" : "testbody"
});
$(this).attr("value", Math.random());
},
"Close" : function() {
$(this).closeDialog();
}
},
onOpen : function() {
},
onClose : function() {
var $currentDialog = $(this).getDialog();
$currentDialog.fadeIn("fast");
}
});
I am making something wrong or I'm actually heading the good way?
On a side note, I found that this code : $el.data( pluginName, $el);
suggested by the design pattern doesn't work. In fact, every time I tried to retreive the object using $("#dialogTest").data("Dialog")
, the returned object was empty.
Thank you
The jQuery Plugin Authoring tutorial gave me the jQuery plugin pattern I use.
Regarding your assignOptions
task...
if you have a private settings object and pass your plugin the options it works nicely (this is outlined in the tutorial of course).
Example of extending
(function( $ ){
$.fn.tooltip = function( options ) {
//private settings
var settings = {
'location' : 'top',
'background-color' : 'blue'
};
// returning this.each ensures your plugin works on multiple matched elements
return this.each(function() {
// If options exist, lets merge them
// with our default settings
if ( options ) {
$.extend( settings, options );
}
// Tooltip plugin code here
});
};
})( jQuery );
//initiate plugin with an options object
var options = { 'location' : 'left' };
$('div').tooltip( options );
A couple of quick tips for you:
In a function expression that is assigned to the
jquery.fn
(The jQuery Prototype),this
is already a jQuery object.$.fn.method = function( options ) { return this.each(function() { //do something }); }
It's not usually a good idea for one plugin to use 4 method names on the
jquery.fn
namespace. Using the jQuery UI Widget framework, you would only use one method name$.widget("cybrix.coolDialog", { ... close: function() { ... }, open: function() { ... }, assign: function() { ... } }
Then
$("#dialogTest").coolDialog('close'); $("#dialogTest").coolDialog('open'); $("#dialogTest").coolDialog('assign');
You'd could do this or something similar with out the dependency on jquery.ui.widget.js
The
on
prefix is unusual for most jQuery events
精彩评论