Reputation: 3195
I am working with jQuery and have built a small plugin.
jQuery(document).ready(function(){
jQuery('.section').Section();
});
jQuery.fn.Section = function(func, options){
if(typeof(func)==='undefined') func = 'new';
if(typeof(options)==='undefined') options = new Object();
//var settings = $.extend({}, options);
var DOM = jQuery(this);
var p = DOM.parent();
var collapsed = false;
var slide_area = DOM.find('.slide_area');
var toggle_btn = DOM.find('.toggle_btn');
return this.each( function() {
switch(func){
case 'new':
toggle_btn.on('click', function(){console.log('click');
if (collapsed){
slide_area.slideDown();
toggle_btn.text('-');
collapsed = false;
}else{
slide_area.slideUp();
toggle_btn.text('+');
collapsed = true;
}
});
break;
}
});
}
You can see, I am using a class selector to attach the Section plugin to all DIV's with the class 'section'.
In the Section plugin, there is a listener for a toggle button in the section.
The problem is that when I click on the toggle button, the event is fired 4 times.(There are 4 DIV's with a 'section' class.
I thought I had this plugin set-up correctly so it plays well with jQuery. I have looked around, but could not find what I've done incorrectly.
How can I change this so it does not trigger the click function once for each instance of a 'section' DIV?
Here is the HTML to help understand the structure:
<div class="section"><!-- paypal settings -->
<h3>Paypal Settings</h3>
<div class="section_controls">
<div class="toggle_btn">-</div>
<div class="hr" style="background-color: <?php echo $settings->secondary_color; ?>;"></div>
</div>
</div>
Upvotes: 0
Views: 48
Reputation: 1074276
You're doing work outside your this.each(...)
that should be inside it. For instance, your lines:
var slide_area = DOM.find('.slide_area');
var toggle_btn = DOM.find('.toggle_btn');
Those are outside the this.each(...)
part of your plugin, and you've set DOM
to (effectively) the set of elements your plugin was called on. That means that slide_area
refers to all .slide_area
elements in all of the sections you were called with, and that toggle_btn
refers to all .toggle_btn
elements in all of the sections you were called with. Later in your this.each(...)
, you hook up a handler using toggle_btn.on(...)
, and so you hook it up to all four toggle buttons four separate times.
At first glance, everything you're doing outside your this.each(...)
should be inside it.
Upvotes: 1
Reputation: 1325
Just put your variables in the return this.each
like this:
return this.each( function() {
var DOM = jQuery(this);
var p = DOM.parent();
var collapsed = false;
var slide_area = DOM.find('.slide_area');
var toggle_btn = DOM.find('.toggle_btn');
switch(func){
case 'new':
toggle_btn.on('click', function(){
console.log('click');
if (collapsed){
slide_area.slideDown();
toggle_btn.text('-');
collapsed = false;
}else{
slide_area.slideUp();
toggle_btn.text('+');
collapsed = true;
}
});
break;
}
});
}
Upvotes: 0