how to prevent checkbox check when clicking on link inside label - javascript

I have a link inside a label. The problem is, when user clicks 'back' after having read the terms, the checkbox is unchecked, because when they clicked on the link they also unchecked the box at the same time, since the link is inside a label.
<input type="checkbox" id="terms" name="terms" checked="checked" />
<label for="terms">I agree to be bound by the Terms</label>
How can I prevent the checkbox from being checked when link is clicked? Tried doing event.preventDefault() on label click, but that doesn't prevent checkbox from being checked/unchecked.
I could just take out the link from inside a label (which means more CSS styling). But now I'm curious whether the above is possible.

You can cancel the click event by routing it through an onclick event.
The "return false;" part will prevent the click event from moving up to the label.
<input type="checkbox" id="terms" name="terms" checked="checked" />
<label for="terms">I agree to be bound by the Terms</label>

Also good practice to allow opening links with target="_blank" in new tabs.
/*
Fix links inside of labels.
*/
$( 'label a[href]' ).click( function ( e ) {
e.preventDefault();
if ( this.getAttribute( 'target' ) === '_blank' ) {
window.open( this.href, '_blank' );
}
else {
window.location = this.href;
}
});

Why not move the link outside the label?
<label for="terms">I agree to be bound by the</label> Terms

Just add the 'for' attibute and it will prevent from unwanting bubbling

You could have the link open up in a new window so that the page doesn't change.
If you don't want to do that you could check to see if the link has been visited and then automatically check the box.

I have a similar situation, but the link actually opens a new window when clicked. This doesn't check/uncheck the box. I believe it is because the click doesn't bubble up through the link to the label.
So, to extend this, if you want the link to open in the same page, you could make it open using a click handler and preventing the click on the link from bubbling, like so:
$('label a').click(function(ev) { ev.preventDefault(); window.location.href = $(this).attr('href'); }
(It's untested and not the nicest use of JS, but it should solve your issue)

I agree the best way (for usability and ease) would be to open the terms in a new window, but if you wish to open it in the same one you can use this little function:
function stopLabel(e) {
e.preventDefault();
window.location= '/terms';
}
You could also put them straight into your onclick but this is a bit nicer imo.
You would have to pass the event to the function too:
<label for="terms">I agree to be bound by the Terms</label>
If you decide to open it in a new window you can just change the window.location to window.open

The link should be outside the label and not a part of it since clicking on it will trigger two action (opening the link and checking the checkbox).
The user is expecting to trigger only one action,
if the link looks like a link he would expect to be taken to the links target,
or if the text is related to the checkbox the user will expect it to check the checkbox.

If you are ok with opening the link in a new tab (and I think it is better, because maybe the user has already filled some data on the page) then this can be handled even without js
<input type="checkbox" id="agreed" />
<label for="agreed">
I agree with Terms of use and Privacy Policy
</label>
here is js fiddle example
http://jsfiddle.net/davo3/zkcv3L3d/

Related

Div click event when div is inside a form

I have troubles to show an alert when a button (actually an input type=image object) is disabled because user should first to click on a terms checkbox.
This is my jQuery code:
$('#divButton').on("click", function() {
if ($('#buybutton').prop('disabled', true)) {
alert('Please confirm . . .');
}
});
And this is the HTML code:
<form>
...
<div id="divButton">
<input type="image" id="buybutton"...
</div>
</form>
When buybutton is disabled and I click inside divButton (over disabled button for example) nothing happens.
I am a mobile developer trying to write JavaScript code, so be patient with me.
What am I doing wrong?
EDIT: Debugging it on Chrome, when buybutton is disabled it is never entering inside divButton's click handler function to check
if ($('#buybutton').prop('disabled', true)).
Looks like onClick event in that div be disabled.
best approach is Pat Dobson's recipe, is not exactly the same than I was trying to do, but can works:
Make alert window when clicking a disabled button
Thanks for your help, guys ;-)

Javascript/Adobe DTM: Tracking Checkbox Clicks Only Once

First, as usual, sorry if this answer exists but I searched and couldn't quite find the answer for which I am looking.
I'm trying to track an action on an input checkbox only once, that is if I have a list of checkboxes I want to only track if user clicked on it once, so even if they deselect a chackbox they've checked only the first click is tracked.
I know there's a way to check if a checkbox has been clicked in JS via querySelector().input type call, but I'm lost as to how to bring that full circle to only have tracking event fire only once regardless of how many times the user toggles it.
Consider the following markup:
<li class="js-form-item form-item form-item__item form-item--checkbox__item">
<span class="checkbox">
<input view_id="explore" display_id="explore_main" data-drupal-selector="edit-category-title-app" type="checkbox" id="edit-category-title-app" name="category[title_app]" value="title_app" class="form-checkbox form-item__textfield">
<label for="edit-category-title-app" class="checkbox__label">
<span class="checkbox__faux"></span><span class="form-item__label">App</span>
</label>
</span>
</li>
Any help would be greatly appreciated. Vanilla JS only, please.
Attach an event listener and remove it when it is triggered.
function addEventListenerOnce(target, type, listener) {
target.addEventListener(type, function fn(event) {
target.removeEventListener(type, fn);
listener(event);
});
}
addEventListenerOnce(document.getElementById("edit-category-title-app"), "change", function (event) {
alert("You'll only see this once!");
// DTM call here
});
See this post

radio button checked property not setting when preventDefault is also used

The problem I am having is that the radio buttons in my scenario are not being selected when they are clicked. I have created a JSFiddle to show the code and the issue.
For whatever reason, I have an entire area that is surrounded in an element.
<a href="/link">
//some stuff
<div class="protected">
<input type="radio" name="b1" value="1" /> Button 1
<input type="radio" name="b1" value="2" /> Button 2
</div>
//some stuff
</a>
There is a small section within this tag that needs to be protected from the default behaviour of the link. This section contains some radio inputs which need to be selectable.
The way I currently have it, I am protecting the "protected" section with an event listener and:
$('.protected').off('click').on('click', function (e) {
e.preventDefault();
});
I also have an event listener on the radio buttons so that I can perform the change of property when they are clicked.
$('.protected > :radio').off('click').on('click', function (e) {
$(this).siblings(':radio').removeAttr('checked');
$(this).attr('checked', 'checked');
});
Unfortunately, this is setting the checked attribute in the dom however the radio button is not being filled in on the screen for the user.
Any help would be greatly appreciated.
You need to add stopPropagation()
$('.protected > :radio').off('click').on('click', function (e) {
e.stopPropagation();
//$(this).siblings(':radio').removeAttr('checked');
//$(this).attr('checked', 'checked');
});
Also, make sure to comment out
$(this).siblings(':radio').removeAttr('checked');
$(this).attr('checked', 'checked');
You don't need them as the browser handles this for you.
DEMO
What was happening is, since you had preventDefault in the container click handler, the nested click event was propagating to that click handler and was preventing the radio button from being set.

Cannot bind after unbinding

I am attempting to bind a click event after previously unbinding it and I cannot get it to work.
Here is my HTML:
<div class="input-group date">
<input type="text" class="form-control" id="dp1" style="width: 100px; vertical-align: middle" />
<span class="input-group-addon" id="dp1Icon" style="outline-style:none"><img src="<%=context%>/images/calendar-glyph.png"></span>
</div>
The input is actually a bootstrap datepicker component. The span contains a bootstrap glyph that triggers the datepicker to open. I have a radio button group that toggles disabling these like this:
$(".date-wrap input[type='radio']").on("click", function(e){
if ($(e.target).val() == "permanent"){
$("#dp1, #dp1Icon").prop("disabled", true);
$("#dp1Icon").unbind("click"); // Disabled attribute only works on form controls, not spans. So we have to unbind the event
$("#dp1").removeAttr("readonly", "readonly");
}else{
$("#dp1, #dp1Icon, #e3").prop("disabled", false);
$("#dp1Icon").bind("click");
$("#dp1").removeAttr("readonly");
}
});
So, if the value of the radio button they click is "permanent", everything becomes disabled; that works great. Otherwise, I attempt to turn them back on.
The only thing I can think of is that when I try to bind the click event to the glyphicon again, I must define the actual handler that opens the datepicker; like this:
$("#dp1Icon").bind("click", $("#dp1").datepicker('show'));
But all that does is open the datepicker as soon as I click the other radio button. I want it to open only when they click it.
What important piece am I missing here? Does anyone have an idea?
Thanks for any tips.
bind("click") does not magically re-add the event. You need to add it back the event.
$("#dp1Icon").on("click", function(){ $("#dp1").datepicker('show'); } );
You might be better off just setting a flag inside that function and not removing the event.

jQuery change focus on tab or focusout

(sorry for my english)
Hi!, i'm using jquery in an app where i have a dinamycally created table with text inputs inside like this:
<td><input type="text" id="code"></td>
<td><select id="type"><option value="0">Normal</option><option value="1">Other</option></select></td>
<td><input type="text" id="price" class="price"></td>
<td><input type="text" id="total"></td>
and in other part i have a button, when this button is clicked, create another line in the table.
The container of this table and button exists inside a template.. this templates is rendered using underscore.js
Now the problem: I need to iterate over the inputs in order: code, type, price. When i fill the input price i calculate the total and shows up in the input, and then i need to change focus to the button (#more_button) to let the user click or press enter to create another line in table.
I use this:
$('.price').blur(function(e){
_this.setTotal($(e.currentTarget).val());
$('#more_button').removeClass('inactive').focus();
e.preventDefault();
e.stopPropagation();
});
When the #more_button is focused the css background change.
When i execute this piece of code, the button change the background but the focus inmediatly change to url bar. This happend in firefox and Chrome.
I try to use this to set the focus:
$('.price').blur(function(e){
_this.setTotal($(e.currentTarget).val());
$('#more_button').removeClass('inactive').;
setTiemout(function(){
$('#more_button').focus();
},100);
e.preventDefault();
e.stopPropagation();
});
But don't work either.....
Can you give some guideline to acomplish this?
The user can change the focus of input.price when press Tab or click in other part of the page.. in this moment i need to trigget seTotal and focus on the button.
I don't know what the simple method
$('your_selector').focusout(function(){
$('#more_button').focus();
});
doesn't work with tab key (only with the mouse to change the focus).. so i solve using a mix between keydown event and focusout. like this:
$('.price').bind('keydown',function(e){
if(e.keyCode === 9){//Tab key
tab = true;
check(e);
return false;
}
}).bind('focusout',function(e){
if(!tab){
check(e);
}else{
tab = false;
}
e.preventDefault();
return false;
});
where check() is a function to validate the value and tab is a flag to check if the tab key was pressed.
$('your_selector').focusout(function(){
$('#more_button').focus();
});
works in FF and chrome here at least.
here a fiddle: http://jsfiddle.net/Zabn4/
The most modern solution (jQuery 1.7+) is to use the following code:
$('#your-input').on('focusout', function(e){
$('#submit-btn').focus();
});

Categories