Skip to content

Instantly share code, notes, and snippets.

@nathansh
Last active Jun 20, 2016
Embed
What would you like to do?
JavaScript module for a generic toggler

JavaScript module for a generic toggler. Main element is '.js-toggler, clicking child element .js-toggler__header adds and .is-open class to open the content (control this with CSS). Escape key and outside clicks close the most recently opened item.

app.toggler = (function($){
'use strict';
var toggler = {
openItems: [],
init: function() {
var togglers = $('.js-toggler');
// Loop through each item
togglers.each(function() {
var thisToggler = $(this);
// Open toggler
thisToggler.find('.js-toggler__header').on('click.pp.toggler', function(event) {
if ( thisToggler.data('pp.toggler.open') ) {
toggler.closeToggler(thisToggler);
} else {
toggler.openToggler(thisToggler);
}
event.preventDefault();
});
}); // each
},
openToggler: function(thisToggler) {
// If the open items array is currently empty, bind the escape key and watch for outside clicks
if ( ! toggler.openItems.length ) {
toggler.bindEventHandlers();
}
// Set data attribute
thisToggler.data('pp.toggler.open', true);
// Open toggler
thisToggler.addClass('is-open');
// Add to our open itmes array
toggler.openItems.push(thisToggler);
},
closeToggler: function(thisToggler) {
// Set data attribute
thisToggler.data('pp.toggler.open', false);
// Close toggler
thisToggler.removeClass('is-open');
// // Remove from our open itmes array
// toggler.openItems.push(toggler);
var indexToRemove = toggler.openItems.indexOf(thisToggler);
if ( indexToRemove > -1 ) {
toggler.openItems.splice(indexToRemove, 1);
}
// If all items are closed, unbind the event handler
if ( ! toggler.openItems.length ) {
toggler.unbindEventHandlers();
}
},
bindEventHandlers: function() {
toggler.watchEscapeKey();
toggler.watchForOutsideClicks();
},
unbindEventHandlers: function() {
$(document).off('keyup.pp.toggler');
$(document).off('click.pp.toggler');
},
watchEscapeKey: function() {
$(document).on('keyup.pp.toggler', function(event) {
if ( event.keyCode === 27 && toggler.openItems.length > 0 ) {
// Close the appropriate item
toggler.closeToggler(toggler.openItems[toggler.openItems.length - 1]);
}
}); // escape
},
watchForOutsideClicks: function() {
$(document).on('click.pp.toggler', function(event) {
// If the click is outside the most recently opened item, close it
if ( ! $(event.target).closest(toggler.openItems[toggler.openItems.length - 1]).length && toggler.openItems.length ) {
toggler.closeToggler(toggler.openItems[toggler.openItems.length - 1]);
}
});
}
};
/* Document ready
/* + + + + + + + + + + + + + + + + + + + + + + + + + + + */
$(document).on('ready', toggler.init);
return toggler;
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment