Lee Loftiss
Lee Loftiss

Reputation: 3195

Plugin being triggered by every instance of a class

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

Answers (2)

T.J. Crowder
T.J. Crowder

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

twain
twain

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

Related Questions