collapse fieldset when legend element clicked

Since text nodes are not elements, there is no way to toggle them.

As a last resort, if you cannot wrap them with an element, you can remove everything except the legend and add the elements and the text nodes back later:

$(document).ready(function() {
    $('legend.togvis').click(function() {
        var $this = $(this);
        var parent = $this.parent();
        var contents = parent.contents().not(this);
        if (contents.length > 0) {
            $this.data("contents", contents.remove());
        } else {
            $this.data("contents").appendTo(parent);
        }
        return false;
    });
});

You can test that solution here.


You simply cannot make text disappear in HTML, JavaScript or CSS. It needs to be contained in a HTML element that will have display:none; applied or something similar.

The following code will wrap everything into a div, and move your legend to the same level as the div, and make the div show/hide when you click on the legend.

$("fieldset legend").click(function() {
  if ($(this).parent().children().length == 2)
    $(this).parent().find("div").toggle();
  else
  {
    $(this).parent().wrapInner("<div>");
    $(this).appendTo($(this).parent().parent());
    $(this).parent().find("div").toggle();
  }
});
  • Code: http://jsbin.com/eleva3/edit
  • Preview: http://jsbin.com/eleva3

Glorious Pure HTML/CSS Solution

This can be done purely with HTML and CSS, now in the year 2019.

#toggle + #content {
    display: none;
}

#toggle:checked + #content {
    display:block;
}

legend {
    width: 85%;
    border: 1px solid black;
    padding: 3px 6px;
    cursor: pointer;
}

legend label {
    width: 100%;
    display: inline-block;
    cursor: inherit;
}

legend label::after {
    content: "▼";
    float: right;
}
<body>
<form>
<fieldset>
    <legend><label for="toggle">Test</label></legend>
    <!-- This input has no name, so it's not submitted with the form -->
    <input type="checkbox" id="toggle" checked="" hidden=""/>
    <div id="content">
        <label>Some text field<input type="text" name="some-text-field"/></label><br/>
        <label>Some color input<input type="color" name="some-color-field"/></label>
    </div>
</fieldset>
</form>
</body>

Javascript Version

While the Pure HTML/CSS Solution is clearly glorious, there's nothing wrong with using Javascript to program interactivity on a page. But I've noticed all other answers use JQuery, which is totally unnecessary in the year 2019.

window.addEventListener('load', () => {
    const collapser = document.getElementById('collapser');
    const collapsable = document.getElementById('collapsable');

    function collapse(event) {
        if (event) {
            event.stopPropagation();
        }

        collapsable.hidden = !collapsable.hidden;
    }

    collapser.addEventListener('click', collapse);
});
legend {
    width: 85%;
    border: 1px solid black;
    padding: 3px 6px;
    cursor: pointer;
    display: inline-block;
}

legend::after {
    content: "▼";
    float: right;
}
<body>
<form>
<fieldset>
    <legend id="collapser">Test</legend>
    <div id="collapsable">
        <label>Some text field<input type="text" name="some-text-field"/></label><br/>
        <label>Some color input<input type="color" name="some-color-field"/></label>
    </div>
</fieldset>
</form>
</body>

Tags:

Jquery

Toggle