Last Updated: February 25, 2016
·
1.845K
· ArondeParon

Dynamically toggling page elements without writing repetitive code

In a lot of web projects, I need to toggle the state of an element by clicking another. Instead of writing handlers for each of these triggers, I prefer using this re-usable piece of code that allows me to attach such behavior using the HTML data attribute.

Enjoy!

/**
 * Toggle everything!
 * 
 * Options:
 * ----------------------
 * data-toggle="<selector>"                           The element that should be toggled.
 * data-toggle-class="<classname>"    [optional]      The classname that should be toggled on the target. If empty, display will be toggled
 * data-toggle-alt-html="<content>"   [optional]      Alternate content that should be displayed in the toggling element
 * data-toggle-duration="<duration>"  [optional]      Duration of the effect. Instant if empty.
 *
 * Example:
 * ----------------------
 * <a href="#" data-toggle="#some-form" data-toggle-alt-html="Hide form">Show form</a>
 * <form action="" id="some-form"><button type="submit">Submit it!</button></form>
 * 
 */

$('[data-toggle]').click(function() {
    var $this = $(this);
    var ref = $(this).data('toggle');
    if ($(this).data('toggle-alt-html')) {
         if ($(this).data('toggle-alt-html') == $(this).html()) {
             $(this).html($(this).data('original-html'));
         } else {
            $(this).data('original-html', $(this).html());
            $(this).html($(this).data('toggle-alt-html'));
        }
    }

    var duration = $(this).data('toggle-duration') || 0;

    if ($(this).data('toggle-class')) {
        $(ref).toggleClass($(this).data('toggle-class'));
    } else {
        $(ref).toggle(duration);
    }

    $(this).toggleClass('active');
    // trigger a custom event to allow for additional event handlers
    $(this).trigger('afterToggle');

    // generally, you'd want anchors to do nothing when toggling behavior
    if ($(this).is('a')) {
        return false;
    }
});

2 Responses
Add your response

Never thought about doing it this way, but it makes perfect sense ! Thanks :)

over 1 year ago ·

You started by storing $(this) in a variable called "$this" but then referenced $(this) throughout the rest of your code; I would use the variable you created.

For example:

var ref = $this.data('toggle');

over 1 year ago ·