Reputation: 3446
I have an <input type="checkbox">
tag inside of a <summary>
inside a <details>
, which unfortunately toggles the <details>
to open or close when it is checked or unchecked, not unlike this question concerning space toggling details, but unfortunately can't be fixed with the same method for me in my version of Firefox.
See below snippet:
$('input').change(function(e) {
e.stopPropagation();
e.preventDefault();
return false;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<details>
<summary>
<input type="checkbox">
</summary>
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse finibus bibendum lorem, vitae efficitur felis mattis vitae. Sed mattis tristique rutrum. Morbi a placerat purus, et pulvinar risus. Vivamus accumsan sapien et nisi vulputate blandit. Aenean nec consectetur nulla. Nunc efficitur tincidunt placerat. Vivamus blandit est lectus, ut fermentum velit vulputate ut. Morbi elementum sem massa, eleifend laoreet dui tristique quis. Nulla mi dolor, consectetur blandit fermentum quis, tempor id nisi. Phasellus vel lobortis enim, id blandit turpis. Nullam dapibus feugiat risus eu pharetra. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam enim justo, pharetra sit amet urna sed, ultricies tempor nibh.
</div>
</details>
How do I prevent the <details>
getting opened/closed by checking or unchecking the checkbox? (Other than the obvious answer of moving the <input>
tag outside the <summary>
. I am curious as to why this happens)
Edit
As mentioned by @Terry and then confirmed by me, this issue does not affect either Safari or Chrome, and even Firefox on Windows seems to act differently (it just ignores clicks on the checkbox entirely). Confirmed affects Firefox 66.0.2-3 on OS X Mojave 10.14.4.
Also if you capture the click event on the <summary>
and return false;
the checkbox still toggles the <details>
, even though clicking elsewhere in the <summary>
doesn't.
Edit 2
This was a Firefox bug and has been fixed in version 67.
Upvotes: 8
Views: 533
Reputation: 26
This issue has been fixed in Firefox 67.
See https://bugzilla.mozilla.org/show_bug.cgi?id=1524893.
(https://bugzilla.mozilla.org/show_bug.cgi?id=1554691 and https://bugzilla.mozilla.org/show_bug.cgi?id=1539490) are duplicates of the issue.
Upvotes: 1
Reputation:
Welcome to the incompatible world of browsers! :D
First of all, you should consider working with the click
event instead of the change
event, because if user clicks on a checkbox, first the click
event is triggered and then change
event, which means the click
event is responsible for the toggle behaviour and again not the change
event.
So, on both Chrome and Firefox, the click
event for special elements such as input
, button
, textarea
that lies in the summary
element bubbles up to the parent details
element, which is a normal behaviour, however the interesting thing is that the click
event is apparently only ignored in Chrome and not processed further, so that the details
element is not toggled. You can try it with another element, i.e. button
, on Chrome, and you will observe no difference. Firefox on the other hand just toggles it regardless of the type of element.
So, to overcome this problem, (with a little help of CSS) you can try it with a ghost checkbox
element, so to speak, that is absolutely positioned, thus not part of the normal document flow. It's invisible and most importantly operates the state of the visible checkbox by staying on top of it and handling the click
event in the first place, like so:
P.S. Works both on Firefox and Chrome - tested.
$('input.ghost-checkbox').click(function(e) {
$(this).next().prop('checked', !$(this).next().prop('checked'));
return false;
});
.ghost-checkbox {
opacity: 0;
position: absolute;
z-index: 2;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<details>
<summary>
<span style="overflow: hidden">
<input type="checkbox" class="ghost-checkbox">
<input type="checkbox">
</span>
</summary>
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse finibus bibendum lorem, vitae efficitur felis mattis vitae. Sed mattis tristique rutrum. Morbi a placerat purus, et pulvinar risus. Vivamus accumsan sapien et nisi vulputate blandit. Aenean nec consectetur nulla. Nunc efficitur tincidunt placerat. Vivamus blandit est lectus, ut fermentum velit vulputate ut. Morbi elementum sem massa, eleifend laoreet dui tristique quis. Nulla mi dolor, consectetur blandit fermentum quis, tempor id nisi. Phasellus vel lobortis enim, id blandit turpis. Nullam dapibus feugiat risus eu pharetra. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam enim justo, pharetra sit amet urna sed, ultricies tempor nibh.
</div>
</details>
Upvotes: 4
Reputation: 10975
To achieve expected result, use below options
$('input').change(function(e) {
if(!$("input").is(':checked')){
$('details').removeAttr('open');
}
e.stopPropagation();
e.preventDefault();
return false;
});
$('details').on('click', function(e) {
if(!$("input").is(':checked')){
if(e.target != this) return
e.stopPropagation();
e.preventDefault();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<details id="mydetails">
<summary>
<input type="checkbox">
</summary>
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse finibus bibendum lorem, vitae efficitur felis mattis vitae. Sed mattis tristique rutrum. Morbi a placerat purus, et pulvinar risus. Vivamus accumsan sapien et nisi vulputate blandit. Aenean nec consectetur nulla. Nunc efficitur tincidunt placerat. Vivamus blandit est lectus, ut fermentum velit vulputate ut. Morbi elementum sem massa, eleifend laoreet dui tristique quis. Nulla mi dolor, consectetur blandit fermentum quis, tempor id nisi. Phasellus vel lobortis enim, id blandit turpis. Nullam dapibus feugiat risus eu pharetra. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam enim justo, pharetra sit amet urna sed, ultricies tempor nibh.
</div>
</details>
Option 2: Using show and hide of div
$('input').change(function(e) {
if(!$("input").is(':checked')){
$('details').removeAttr('open');
}
e.stopPropagation();
e.preventDefault();
return false;
});
$('details').on('click', function(e) {
if(!$("input").is(':checked')){
$('div').hide();
$('details').removeAttr('open');
}else{
$('div').show();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<details id="mydetails">
<summary>
<input type="checkbox">
</summary>
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse finibus bibendum lorem, vitae efficitur felis mattis vitae. Sed mattis tristique rutrum. Morbi a placerat purus, et pulvinar risus. Vivamus accumsan sapien et nisi vulputate blandit. Aenean nec consectetur nulla. Nunc efficitur tincidunt placerat. Vivamus blandit est lectus, ut fermentum velit vulputate ut. Morbi elementum sem massa, eleifend laoreet dui tristique quis. Nulla mi dolor, consectetur blandit fermentum quis, tempor id nisi. Phasellus vel lobortis enim, id blandit turpis. Nullam dapibus feugiat risus eu pharetra. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam enim justo, pharetra sit amet urna sed, ultricies tempor nibh.
</div>
</details>
Upvotes: 1
Reputation: 1185
Have you tried event.stopImmediatePropagation()
this will stop immediate event
Upvotes: 0
Reputation: 84
If I understood well, you need to hide the details when checkbox is checked, so you can use hidden
attribute.
let bool = true;
const content = document.getElementById("content");
$('input').change(function(e) {
bool = !bool;
if (bool) {
content.setAttribute("hidden", true);
} else {
content.removeAttribute("hidden");
}
});
<details>
<summary>
abrir aqui
<input type="checkbox">
</summary>
<div hidden="true" id="content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse finibus bibendum lorem, vitae efficitur felis mattis vitae. Sed mattis tristique rutrum. Morbi a placerat purus, et pulvinar risus. Vivamus accumsan sapien et nisi vulputate blandit. Aenean nec consectetur nulla. Nunc efficitur tincidunt placerat. Vivamus blandit est lectus, ut fermentum velit vulputate ut. Morbi elementum sem massa, eleifend laoreet dui tristique quis. Nulla mi dolor, consectetur blandit fermentum quis, tempor id nisi. Phasellus vel lobortis enim, id blandit turpis. Nullam dapibus feugiat risus eu pharetra. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam enim justo, pharetra sit amet urna sed, ultricies tempor nibh.
</div>
</details>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Upvotes: 1
Reputation: 43920
Try .triggerHandler()
method. Define your event handler to the checkbox then use:
$(':checkbox').triggerHandler('click')
to isolate the click event from triggering anything else. I don't have my Mac so feedback is appreciated.
$(':checkbox').click(function(e) {
console.log($(this).is(':checked'));
});
$(':checkbox').triggerHandler('click')
details {
width: 50%
}
summary * {
display: inline-block;
cursor: pointer
}
mark {
float: right
}
<details>
<summary>
<input type="checkbox"><mark>TEST</mark>
</summary>
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse finibus bibendum lorem, vitae efficitur felis mattis vitae. Sed mattis tristique rutrum. Morbi a placerat purus, et pulvinar risus. Vivamus accumsan sapien et nisi vulputate blandit.
Aenean nec consectetur nulla. Nunc efficitur tincidunt placerat. Vivamus blandit est lectus, ut fermentum velit vulputate ut. Morbi elementum sem massa, eleifend laoreet dui tristique quis. Nulla mi dolor, consectetur blandit fermentum quis, tempor
id nisi. Phasellus vel lobortis enim, id blandit turpis. Nullam dapibus feugiat risus eu pharetra. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam enim justo, pharetra sit amet urna sed, ultricies tempor
nibh.
</div>
</details>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Upvotes: 0