Reputation: 155035
My HTML form has this markup:
<fieldset>
<legend>
<label> <input type="checkbox" class="warnOnUncheck" /> Include the following data </label>
</legend>
<div class="fieldsetContent">
<!-- and a bunch of <input type="text" /> here. -->
</div>
</fieldset>
I have two scripts that are called by DOM-ready:
confirm()
confirmation message when the checkbox is unchecked. If the user clicks "No" then the checkbox is re-checked.The problem is that the first event handler is always called, so even if the user clicks "No" the fieldset content is still hidden.
Here's my (abridged) jQuery code (called during the DOM-ready event handler):
$("fieldset.collapseable legend input").change(function(event) {
var localFieldsetContent = $(this).closest("fieldset").find("div.fieldsetContent");
var checked = $(this).is(":checked");
if( checked && localFieldsetContent.is(":visible") ) {
// if checked and already visible, then skip entirely.
return;
}
localFieldsetContent.slideToggle(200);
);
$("input[type=checkbox].warnOnUncheck").change( function(event) {
if( !this.checked ) {
var message = $(this).data("warnMessage");
var confirmed = confirm( message );
if( !confirmed ) {
this.checked = true;
event.stopImmediatePropagation();
}
}
} );
I thought that event.stopImmediatePropagation();
would work, but it doesn't.
How can I prevent the fieldset from being collapsed when confirmed
is false?
Upvotes: 1
Views: 200
Reputation: 51780
Your immediate problem : the first handler is executed before the second one (the one with the confirm) has a chance to call stopImmediatePropagation
. Bind your handlers in the reverse order and it should work :
$("input[type=checkbox].warnOnUncheck").change( function(event) {
if( !this.checked ) {
var message = $(this).data("warnMessage");
var confirmed = confirm( message );
if( !confirmed ) {
this.checked = true;
event.stopImmediatePropagation();
}
}
} );
$("fieldset.collapseable legend input").change(function(event) {
var localFieldsetContent = $(this).closest("fieldset").find("div.fieldsetContent");
var checked = $(this).is(":checked");
if( checked && localFieldsetContent.is(":visible") ) {
// if checked and already visible, then skip entirely.
return;
}
localFieldsetContent.slideToggle(200);
);
However, I find it pretty unsafe to split this behaviour over two functions.
I would merge the two handlers into a single one :
$("input[type=checkbox].warnOnUncheck").change( function(event) {
var confirmed = true;
if( !this.checked ) {
var message = $(this).data("warnMessage");
var confirmed = confirm( message );
if( !confirmed ) {
this.checked = true;
}
}
if (confirmed) {
var localFieldsetContent = $(this).closest("fieldset").find("div.fieldsetContent");
localFieldsetContent.slideToggle(200);
}
} );
Here is a jsfiddle
If you can't merge the handlers, you can bind the "collapsing" function to some custom event, and have th "click" event on the checkbox trigger it.
See this updated jsfiddle :
$("input[type=checkbox].warnOnUncheck").change( function(event) {
var confirmed = true;
if( !this.checked ) {
var message = $(this).attr("data-warnMessage");
confirmed = confirm( message );
if( !confirmed ) {
this.checked = true;
}
}
if (confirmed) {
$(this).trigger("myToggleVisibility");
}
} );
$("fieldset.collapseable").on("myToggleVisibility", function(event) {
$(this).find('.fieldsetContent').slideToggle(200);
});
Upvotes: 1
Reputation: 40639
Try this:
$("input[type=checkbox].warnOnUncheck").change( function(event) {
if ( event.isImmediatePropagationStopped() ) {
return false;
}
if( !this.checked ) {
var message = $(this).data("warnMessage");
var confirmed = confirm( message );
if( !confirmed ) {
this.checked = true;
event.stopImmediatePropagation();
}
}
});
Read http://api.jquery.com/event.isImmediatePropagationStopped/
Upvotes: 0
Reputation: 6736
use event.preventDefault();
OR
if(!confirmed){
this.checked = true;
return false;
}
Upvotes: 0