Combining multiple jQuery functions
Is there a way to combine all of this to reduce the amount of js? This is just an example of some jquery dialogs I have on my site, there are a few more. Thanks.
//initiate Search refinement dialog here
$("#chooseMoreCnt, #chooseMoreCat, #chooseMorePr").dialog({
bgiframe: true,
autoOpen: false,
width: 500,
modal: true,
open: function(type, data) {
$(this).parent().appendTo(jQuery("form:first"));
}
});
//trigger country dialog
$('a.chooseMoreCnt').click(function() {
$('#chooseMoreCnt').dialog('open');
return false;
});
//trigger category dialog
$('a.chooseMoreCat').click(function() {
$('#chooseMoreCat').dialog('open');
return false;
});
//trigger price dialog
$('a.chooseMorePr').click(function() {
$('#chooseMorePr').dialog('open');
return false;
});
a source to share
If your links point to the IDs of the dialog elements, and if you add a meta-class choose
to each of them, you can combine the last three calls with:
$('a.choose').click(function() {
$(this.hash).dialog('open');
return false;
});
The HTML for one of these links is the most semantically correct and even works with JS disabled (assuming there are dialogs):
<a href="#chooseMoreCat" class="choose">Choose more categories</a>
Explanation of the part this.hash
:
-
this
in the context of an event handling function, jQuery is always the element on which the event occurred. In our case, this is a clicked link. Note that this is a DOM node and not a jQuery element. -
this.hash
: DOM nodes corresponding to HTML elements<a/>
have certain special properties that allow you to access the target they are bound to. The propertyhash
is everything after the character#
(and including) in the URL. In our case, if the link points to elements that should become dialog boxes, it looks like a string"#chooseMoreCnt"
. -
$(this.hash)
is a jQuery function called, for example"#chooseMoreCnt"
, that will pick the appropriate onediv
.
To initialize the dialog, I would go for classes too:
$(".choose_dialog").dialog({
bgiframe: true,
autoOpen: false,
width: 500,
modal: true,
open: function(type, data) {
$(this).parent().appendTo(jQuery("form:first"));
}
});
Yes, it means changing the markup, but it also gives you freedom
-
add any number of dialog boxes
-
add any number of openers to any dialog
-
style all dialogs and dialog links consistently with minimal CSS
without touching Javascript anymore.
If dialogs are triggered differently (as pointed out in the comments), you can go to that part using the CuSS approach $.each()
and read the corresponding width inside the function from an object defined elsewhere:
var dialog_widths = {'chooseMoreCat': 400, 'chooseMorePr': 300, /*...*/ };
a source to share
Here's what I would like to suggest. Provide a common DialogContent (say) class for all sections and initialize them using:
$(".dialogContent").dialog({
bgiframe: true,
autoOpen: false,
width: 500,
modal: true,
open: function(type, data) {
$(this).parent().appendTo(jQuery("form:first"));
}
});
And of course use Boldewyn's solution for the click event (better to use live () IMHO if the situation is dynamically generated). This way you take care of all initializations and click events with less code.
NTN
a source to share
To optimize performance, you should use live when connecting to multiple items. Below is my approach to the problem. The solution is dynamic (add as many dialogs as you want) and very fast.
Remember to change #anyParentOfTheLinks to the parent div, or in the worst case, remove it, and jQuery will use the document instead.
var dialogues = ['#chooseMoreCnt', '#chooseMoreCat', '#chooseMorePr'];
$(dialogues.toString()).dialog({
// ...
});
$('a', '#anyParentOfTheLinks').live('click', function(){
// Cache for performance
var $this = $(this), len = dialogues.length;
for(var i = 0; i < len; i++)
if($this.is('.' + dialogues[i].substr(1))) {
$this.dialog('open');
break;
}
return false;
});
a source to share