mckeegan375 mckeegan375 - 1 month ago 7
HTML Question

Making JavaScript items independent

I'm using a jQuery script to expand/collapse a div on a page an it works perfectly. I'm now trying to replicate the code so there are two divs which do the same but I want them to be independent however when I click one, both open/close. Just wondering what i'm doing wrong?

So far, I have the following HTML:

<div class="infoToggle1">
<div class="panel-controller">
<div class="tab-controller1">
<span class="close">CLOSE</span>
<span class="show">MORE INFO</span>
</div>
</div>
<div class="panel-content1">
Content goes here
</div>
</div>

<div class="infoToggle2">
<div class="panel-controller">
<div class="tab-controller2">
<span class="close">CLOSE</span>
<span class="show">MORE INFO</span>
</div>
</div>
<div class="panel-content2">
Content goes here
</div>
</div>


and the following jQuery code:

(function($) {

jQuery(document).ready(function() {

Panel.init();


$(document).on('click', '.tab-controller1, .tab-controller2', function() {
Panel.togglePanel();
});

});

var Panel = {

isVisible : false,
showMessage : null,
hideMessage : null,
animationDuration : 300,
animationEasing : 'linear',

init: function() {
Panel.hidePanel();
},

hidePanel : function() {
$('.infoToggle1, .infoToggle2').animate({
bottom : -(Panel.getAnimationOffset())
}, Panel.animationDuration, Panel.animationEasing, function() {
Panel.isVisible = false;
Panel.updateTabMessage();
});
},

showPanel : function() {
$('.infoToggle1, .infoToggle2').animate({
bottom : 0
}, Panel.animationDuration, Panel.animationEasing, function() {
Panel.isVisible = true;
Panel.updateTabMessage();
});
},

togglePanel : function() {
((this.isVisible) ? this.hidePanel : this.showPanel)();
},

updateTabMessage : function() {
if (this.isVisible) {
$('.tab-controller1 .close, .tab-controller2 .close').show();
$('.tab-controller1 .show, .tab-controller2 .show').hide();
} else {
$('.tab-controller1 .close, .tab-controller2 .close').hide();
$('.tab-controller1 .show, .tab-controller2 .show').show();
}
},

getAnimationOffset : function() {
return $('.panel-content1, .panel-content2').height();
}

}

})(jQuery);


Thanks in advance!

Answer

You would need two Panel objects as each needs its own settings for isVisible and several class names. For that you could turn the Panel object to a constructor, which you pass a number (1 or 2). That constructor would return the object as you had it, but with the particularities that apply only to the first element structure. If you call that constructor again with the other number, you would get the object you will need to manipulate (and keep state of) the second structure.

Your code could then look like this (not tested):

(function($) {

    jQuery(document).ready(function() {
        var panel1 = new Panel(1),
            panel2 = new Panel(2);

        $(document).on('click', '.tab-controller1', function() {
             panel1.togglePanel();
        });
        $(document).on('click', '.tab-controller2', function() {
             panel2.togglePanel();
        });
    });

    // Constructor. Needs to get the number 1 or 2
    function Panel(num) {
        var that = this; // Remember the object that is created here
        Object.assign(that, {
            isVisible : false,
            showMessage : null,
            hideMessage : null,
            animationDuration : 300,
            animationEasing : 'linear',

            init: function() {
                that.hidePanel();
            },

            hidePanel : function() {
                // Use number to address the correct class, here and below.
                $('.infoToggle' + num).animate({
                    bottom : -(that.getAnimationOffset())
                }, that.animationDuration, that.animationEasing, function() {
                    that.isVisible = false;
                    that.updateTabMessage();
                });
            },

            showPanel : function() {
                $('.infoToggle' + num).animate({
                    bottom : 0
                }, that.animationDuration, that.animationEasing, function() {
                    that.isVisible = true;
                    that.updateTabMessage();
                });
            },

            togglePanel : function() {
                (that.isVisible ? that.hidePanel : that.showPanel)();
            },

            updateTabMessage : function() {
                if (that.isVisible) {
                    $('.tab-controller' + num + ' .close').show();
                    $('.tab-controller' + num + ' .show').hide();
                } else {
                    $('.tab-controller' + num + ' .close').hide();
                    $('.tab-controller' + num + ' .show').show();
                }
            },

            getAnimationOffset : function() {
                return $('.panel-content' + num).height();
            }
        });
        // call init here, which will execute when you do `new Panel`:
        that.init();
    }
})(jQuery);