0

I have been using the following script to check multiple checkboxes at a time, and all is going well:

    <script type="text/javascript">
    function toggle(source) {
        var aInputs = document.getElementsByTagName('input');
        for (var i=0;i<aInputs.length;i++) {
            if (aInputs[i] != source && aInputs[i].className == source.className) {
                aInputs[i].checked = source.checked;
            }
        }
    }
    </script>

Some general code where I use this is:

...
    <li>surface analysis</li>
    <input type="checkbox" id="checkbox_wpc_sfc00" class="wpc_sfc">00Z 
    <input type="checkbox" id="checkbox_wpc_sfc03" class="wpc_sfc">03Z 
    <input type="checkbox" id="checkbox_wpc_sfc06" class="wpc_sfc">06Z 
    <input type="checkbox" class="wpc_sfc" onClick="toggle(this)"> Toggle All surface
    
    <li>upper air analysis</li>
    <input type="checkbox" id="checkbox_wpc_ua00" class="wpc_ua">00Z 
    <input type="checkbox" id="checkbox_wpc_ua03" class="wpc_ua">03Z 
    <input type="checkbox" id="checkbox_wpc_ua06" class="wpc_ua">06Z 
    <input type="checkbox" class="wpc_ua" onClick="toggle(this)"> Toggle All upper air
...
    

This creates a list of 'surface analyses' checkboxes for 00Z, 03Z, 06Z, and an option to select all 3 of these boxes at once. There is another list of the same style but for 'upper air analysis'. This works great the way that this is.

The issue is I now want to create 00Z, 03Z, and 06Z checkboxes. In other words, the 00Z checkbox would mark the 'checkbox_wpc_sfc00' as well as the 'checkbox_wpc_ua00' text. However, I have run into a bit of a wall as I would figure a separate 'toggle' function would work where I use a str.contains('00'), but this seems to be failing. Any thoughts on this? I would like to try and keep this to either HTML or Javascript, if possible.

Miss_Orchid
  • 308
  • 1
  • 8

2 Answers2

2

I think this should do the job:

    function toggle(source, aux) {
        var aInputs = document.getElementsByTagName('input');
        
        if (aux != "surface and air"){
            for (var i=0; i<aInputs.length; i++) {
                if (aInputs[i] != source && aInputs[i].className == source.className) {
                    aInputs[i].checked = source.checked;
                }
            }
        } else {
            var sSelection = source.id;
            var sType = sSelection.slice(-2);
            var sCheckBox, sLast2;
            
            for (var i=0; i<aInputs.length; i++) {
                sCheckBox = aInputs[i].id;
                sLast2 = sCheckBox.slice(-2);            
                if (sLast2 == sType) {
                    aInputs[i].checked = source.checked;
                }
            }
        }
    }
    <li>surface analysis</li>
    <input type="checkbox" id="checkbox_wpc_sfc00" class="wpc_sfc">00Z 
    <input type="checkbox" id="checkbox_wpc_sfc03" class="wpc_sfc">03Z 
    <input type="checkbox" id="checkbox_wpc_sfc06" class="wpc_sfc">06Z 
    <input type="checkbox" class="wpc_sfc" onClick="toggle(this, 'surface')"> Toggle All surface
    
    <li>upper air analysis</li>
    <input type="checkbox" id="checkbox_wpc_ua00" class="wpc_ua">00Z 
    <input type="checkbox" id="checkbox_wpc_ua03" class="wpc_ua">03Z 
    <input type="checkbox" id="checkbox_wpc_ua06" class="wpc_ua">06Z 
    <input type="checkbox" class="wpc_ua" onClick="toggle(this, 'air')"> Toggle All upper air
    
    <li>general type selection</li>
    <input type="checkbox" id="checkbox_wpc_00" class="wpc_00" onClick="toggle(this, 'surface and air')">00Z 
    <input type="checkbox" id="checkbox_wpc_03" class="wpc_03" onClick="toggle(this, 'surface and air')">03Z 
    <input type="checkbox" id="checkbox_wpc_06" class="wpc_06" onClick="toggle(this, 'surface and air')">06Z 
Rbon
  • 152
  • 8
  • 1
    Something I was reading yesterday said that we should prefer `document.querySelectorAll` over `getElementsByTagName`, on account of the results they return. The first one returns a static list that remains unchanged. The other one returns a 'live-list'. That is, a list that can be updated after retrieval. My understanding of the most obvious benefit is speed, though there are memory concerns too. Here's the post I'm thinking of: https://stackoverflow.com/questions/54952088/how-to-modify-style-to-html-elements-styled-externally-with-css-using-js/54952474#54952474 – enhzflep Jan 17 '21 at 02:24
1

Your current method is to pass the "master checkbox" as the sole argument, and use values extracted from it in the control function. This doesn't appear to be necessary. If it was not more than the most expedient manner you saw to accomplish your goal, please comment such that I might provide a better solution.

function toggle(selector, state) {
    Array.from(
        document.querySelectorAll(selector)
    ).forEach(
        (element)=>element.checked = state
    )
}

Contrasted with your current implementation, this expects values to be passed based on your "master checkbox," versus passing the checkbox itself. I'm also using an array function instead of an explicit loop, and I'm using an arrow function. If you're unfamiliar with either, I can provide references.

Use of this would be as follows:

<li>surface analysis</li>
<input type="checkbox" id="checkbox_wpc_sfc00" class="wpc_sfc">00Z 
<input type="checkbox" id="checkbox_wpc_sfc03" class="wpc_sfc">03Z 
<input type="checkbox" id="checkbox_wpc_sfc06" class="wpc_sfc">06Z 
<input type="checkbox" class="wpc_sfc" onClick="toggle(`.${this.className}`,this.checked)"> Toggle All surface

<li>upper air analysis</li>
<input type="checkbox" id="checkbox_wpc_ua00" class="wpc_ua">00Z 
<input type="checkbox" id="checkbox_wpc_ua03" class="wpc_ua">03Z 
<input type="checkbox" id="checkbox_wpc_ua06" class="wpc_ua">06Z 
<input type="checkbox" class="wpc_ua" onClick="toggle(`.${this.className}`,this.checked)"> Toggle All upper air

<li>Toggle Region</li>
<input type="checkbox" class="all_00Z" onClick="toggle(`[id$='00']`,this.checked)">
<input type="checkbox" class="all_03Z" onClick="toggle(`[id$='03']`,this.checked)">
<input type="checkbox" class="all_06Z" onClick="toggle(`[id$='06']`,this.checked)">

The above uses string templates and expression matching selectors. Again, if these are unfamiliar, I can help you find some references.

Sam Hughes
  • 665
  • 8
  • 10