Search code examples
javascriptjqueryhtmlcssradiobuttonlist

Combining show/hide toggle with radio buttons AND checkboxes


I can toggle the show/hide of a checkbox because it can be unchecked but the behavior is different on a radio group because clicking a checked radio button doesn’t uncheck it, only clicking another radio button in the same group.

DEMO WORKS FOR CHECKBOX NOT RADIO GROUPS

How can I modify this so it works for radio buttons and checkboxes in the same function? In this example I can click Item4 but it doesn’t hide upon clicking the others in the radio group.

How it should work: Put data-info-id="infox" on the input Put id="infox" on the container usually a div

jQuery solutions are welcome.

HTML

    <input type="checkbox" id="item1" data-info-id="info1" />
    <label for="item1">Item 1 Checkbox</label>
    <br/>
    <div id="info1">Content checkbox group</div>
    </p>
    <input type="radio" id="jb1" name="jb" />
    <label for="jb1">Item2 Radio</label>
    <br/>
    <input type="radio" id="jb2" name="jb" />
    <label for="jb2">Item3 Radio</label>
    <br/>
    <input type="radio" id="jb3" name="jb" data-info-id="info2" />
    <label for="jb3">Item4 Radio</label>
    <br/>
    <div id="info2">Content radio group</div>

CSS

[id^="info"] { 

          display: none;
    }

JS

document.addEventListener('change', function(e) {
      var id = e.target.getAttribute('data-info-id');
      var checked = e.target.checked;
      if (id) {
        var div = document.getElementById(id);
        if (div)
          div.style.display = checked ? 'block' : 'none';
      }

    });

Solution

  • I first added two containing divs around the checkbox and the radio buttons:

    <div id="checkbox">
        <input type="checkbox" id="item1" data-info-id="info1" />
        <label for="item1">Item 1 Checkbox</label>
    </div>
    <br/>
    <div id="info1">Content checkbox group</div>
    </p>
    <div id="radios">
        <input type="radio" id="jb1" name="jb" />
        <label for="jb1">Item2 Radio</label>
        <br/>
        <input type="radio" id="jb2" name="jb" />
        <label for="jb2">Item3 Radio</label>
        <br/>
        <input type="radio" id="jb3" name="jb" data-info-id="info2" />
        <label for="jb3">Item4 Radio</label>
        <br/>
    </div>
    <div id="info2">Content radio group</div>
    

    I then added a for loop to loop through the children of the parent of the item clicked. Because it was only triggering the change event for the clicked item.

    document.addEventListener('change', function (e) {
    
        var children = e.target.parentNode.children;
    
    
        for(var i = 0; i < children.length ; i ++)
        {
    
            var id = children[i].getAttribute('data-info-id');
            var checked = children[i].checked;
    
            if (id) {
                var div = document.getElementById(id);
                if (div) div.style.display = checked ? 'block' : 'none';
            }
    
        }
    
    });
    

    This works for me. It's a little down and dirty but it works just fine.