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>