Brainstorm's snippets (1/282)

  html_element_toggle: toggle visibility of any HTML fragment

Purpose: toggle visibility of one or more HTML fragments in a page

First, in the HTML page we need to sorround the fragment with a few tags; we do this with a Python helper:

from django.utils.translation import gettext_lazy as _
from django.utils.safestring import mark_safe

@register.filter
def html_element_toggle(html_fragment, start_hidden=True):
    if start_hidden:
        html = """
<div class="html_element_toggler">
    <a class="show" href="#"><i class="fa fa-eye"></i>&nbsp;%s</a>
    <a class="hide" href="#" style="display: none;"><i class="fa fa-eye-slash"></i>&nbsp;%s</a>
    <div class="data" style="display: none;">
        %s
    </div>
</div>
""" % (_('Show'), _('Hide'), html_fragment)
    else:
        html = """
<div class="html_element_toggler">
    <a class="show" href="#" style="display: none;"><i class="fa fa-eye"></i>&nbsp;%s</a>
    <a class="hide" href="#"><i class="fa fa-eye-slash"></i>&nbsp;%s</a>
    <div class="data">
        %s
    </div>
</div>
""" % (_('Show'), _('Hide'), html_fragment)

return mark_safe(html)

Then, after page loading is completed, we schedule toggling;

with either jQuery:

$(document).ready(function() {

    $('.html_element_toggler .show,.html_element_toggler .hide').on('click', function(event) {
        event.preventDefault();
        var target = $(event.target);
        target.parent().find('.show,.hide,.data').toggle();
    });

});

or vanilla Javascript:

function ready(fn) {
    if (document.readyState !== 'loading') {
        fn();
    } else {
        document.addEventListener('DOMContentLoaded', fn);
    }
}

function toggle(el) {
    if (el.style.display == 'none') {
        el.style.display = '';
    } else {
        el.style.display = 'none';
    }
}

function register_html_element_togglers() {
    let links = document.querySelectorAll('.html_element_toggler .show,.html_element_toggler .hide');
    for (let i = 0; i < links.length; ++i) {
        links[i].addEventListener('click', function(event) {
            event.preventDefault();
            let parent = event.target.parentNode;
            var children = parent.querySelectorAll('.show,.hide,.data');
            for (let j = 0; j < children.length; ++j) {
                toggle(children[j]);
            }
        });
    }
}

ready(register_html_element_togglers);