Beaniie Beaniie - 1 year ago 109
Javascript Question

Using checkboxes to update UI in realtime

I'm currently in the process of trying to develop a smarter UI for one of my clients. However the only code I can use to develop this 'feature', is pure JS. I have no access to the source HTML or CSS files the only access I have is the ability to inject JavaScript through an external .js file.
I'm not too familiar with JS, but I can work my way around a basic script or two.


What we're doing is allowing users to edit PDF Templates online using a software called Core Create. The UI accessed through the browser is quite cluttered and I would like to provide an option to hide and show UI elements

through the use of checkboxes.

Here is a very basic JS Fiddle that I have built with the
intention of hiding and displaying UI.

The page in question

enter image description here

Above is a screen grab of the page I am working with, on the left you can see the UI and its composition on the right within the 'Inspect Element' tool.

I have come to the conclusion that I need to iterate through the highlighted selection and link them accordingly with seven checkboxes. The result would then be a selection of checkboxes that would hide / display the correct UI element.

The Caveat

In realizing I cannot edit or introduce new HTML I noticed the lack of on-click attributes. So I'm a bit lost on how to invoke the JavaScript I will eventually build.

My Question

With my limited knowledge of JS I don't know how I would iterate though div elements
editoraccvar - editoraccvar6
picking out the ones I need to manipulate.

Due to the lack of ID's / Names (I assume it would have to be done using Parent/Child rules somehow, as the classes are widley used by the rest of the UI. I would appreciate a small example demonstrating how I could achieve this, so I can learn from it.

I should clarify, I have already added the checkboxes to the page, I just need to build the JS link between the Checkbox and the UI element I'm attempting to target. You can find all attributes linking to these checkboxes included in the JS Fiddle.

EDIT // A Working Simplified Example;

Due to some confusion I have 'frankensteined' some code together to show the final result I am after. A working example of sorts. The actual result needs to target 7 Checkboxes and 7 Divisions. I'll list thier common properties below.

// This script is already in place and constructed by the system.
// Written inside script tags and located straight after 'editopt1'.
// $(document).ready(function() {
// $('#checkboxopt1').click(function() {
// if ($('#checkboxopt1').val() == 'true') {
// $('#opt1').val('false');
// $('#checkboxopt1').val('false');
// $('#checkboxopt1').prop('checked', false);
// $('#previewrefresh').trigger('click');
// } else {
// $('#opt1').val('true');
// $('#checkboxopt1').val('true');
// $('#checkboxopt1').prop('checked', true);
// $('#previewrefresh').trigger('click');
// };
// });
// });

function exFunction() {

// Check the function is called
console.log("200 : OK");

// grab all elements with the class, .field-summernote
var uiblocks = document.querySelectorAll('.field-summernote');

for (var i = 0; i < uiblocks.length; i++) {

var current = uiblocks[i];
if (current.className.indexOf('editoraccvar') < 0) //not found: -1

// check elements in the array

// control the elemets in the array.
if (document.getElementById('checkboxopt1').checked) {
uiblocks[0].style.display = 'block'; // display the element
} else {
uiblocks[0].style.display = 'none'; // hide the element

// Trigger the collection the check, and the control.
var x = document.getElementById("checkboxopt1");
x.addEventListener("click", function() {

.editoraccvar1 {
width: 300px;
background: #0ff;
padding: .5em;
.editoropt1 {
width: 300px;
background: #ff0;
padding: .5em;
textarea {
display: block;
width: 95%;
resize: none;
padding: .5em;

<!-- I'm trying to hide & show this entire division... -->
<div class="seq-box-form-field field-summernote editoraccvar1 ">
<label for="accvar1">Ground Floor Info</label>
<div class="clearfix"></div>
<textarea id="richaccvar1" name="richaccvar1" class="summernote"></textarea>
<input type="hidden" name="accvar1" id="accvar1" value="" />

<!-- Using only what the system has supplied. -->
<div class="seq-box-form-field editoropt1 ">
<label for="opt1"><span style="padding-right: 10px; vertical-align: 1px;">Ground Floor </span>
<input type="checkbox" name="checkboxopt1" id="checkboxopt1" value="true" checked="true" />
<input type="hidden" name="opt1" id="opt1" value="true" />

<div class=""></div>

* editoraccvar,

<input id=""></input>

* checkboxopt,

Answer Source

As far as I can see, your problem boils down to link checkboxes (that seem to have been generated in some way) to "division" parts of your html that you want to hide. Plus, you have to inject javascript code in the page (so I guess the less code the better).

One approach could be as follows:

// Wrap the code in an anonymus function, to avoid clustering the global space.
(function (domElements) {
    // This is the callback that will fire when a checkbox is clicked.
    function clickCallback() {
        // the context of this callback is the DOM element thus we can access its attributes through this.
        // extract the checkNumber of the class of the element. This number is the link to the division that we want to hide/show.
        var checkNumber = ((/ editoropt(\d*) /).exec(this.className))[1],
            checkBox = document.getElementById('checkboxopt' + checkNumber),
            division = document.querySelectorAll('.editoraccvar' + checkNumber)[0];

        // Hide/show division, update checkBox state.
        toggleElements(division, checkBox, window.getComputedStyle(division).display === 'none');

    function toggleElements(division, checkBox, isShown) {
        // Toggle the division (show/hide) accordingly. = isShown ? 'block' : 'none';
        // Due to the fact that the event listener is attached to the parent of the checkBox, we need to maintain consistency manually.
        checkBox.checked = isShown;

    // Remove from the array of DOMElements those that aren't checkboxes and add a click event listener to each of them.
            .filter(function (el) {
                return el.className.indexOf('editoropt') !== -1;
            .forEach(function (el) {
                el.addEventListener('click', clickCallback, false);

// Call the function passing the dom elements with class '.seq-box-form-field' as argument. Checkboxes are contained within them. Also, transform the nodelist
// into a proper array so that methods defined in Array.prototype can be used.

The code is commented and (I think) quite self-explanatory. However, if you have any doubt or want me to elaborate any point further, please, let me know.

Finally, here's the working fiddle.


Same function (more or less) but now it accepts an array of values that will correspond to the initial state of the checkboxes:

(function (domElements, cbState) {
    function clickCallback() {

    function toggleElements(className, initialShow) {
        var checkNumber = ((/ editoropt(\d*) /).exec(className))[1],
            checkBox = document.getElementById('checkboxopt' + checkNumber),
            division = document.querySelectorAll('.editoraccvar' + checkNumber)[0],
            isShown = initialShow === undefined ? window.getComputedStyle(division).display === 'none' : initialShow; = isShown ? 'block' : 'none';
        checkBox.checked = isShown;

            .filter(function (el) {
                return el.className.indexOf('editoropt') !== -1;
            .forEach(function (el, index) {
                el.addEventListener('click', clickCallback, false);
                toggleElements(el.className, cbState[index]);

// Initial state of the checkboxes goes in the second parameter. The index in the array correspond to the checkbox position in the page.
})([]'.seq-box-form-field')), [false, false]);

Here's the Fiddle to play with. Hope it helps.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download