Prevent click on label from triggering child button - javascript

When setup like this, clicking on a label that has a child button triggers button's onclick event:
function fireButton() {
console.log("Button fired!");
}
<label>Label
<button onclick="fireButton()">Button</button>
</label>
is there a way to prevent this?

Add for attribute to label.
function fireButton() {
console.log("Button fired!");
}
<label for=''>Label
<button onclick="fireButton()">Button</button>
</label>

You can put the button outside the label
<label>Label</label>
<button onclick="fireButton()">Button</button>

You can add preventDefault for labels and keep the existing code:
document.querySelector("label").addEventListener("click", function(event) {
event.preventDefault();
}, false);

You could use a different tag e.g <span> rather than the label But if you really need to use the <label>, you should prevent the default behaviour of the label onclick() like so:
function fireButton(){
//add actions here
}
function preventDefault(event){
event.preventDefault()
}
<label onclick="preventDefault(event)">Label
<button onclick="fireButton()">Button</button>
</label>

Here's an approach in CSS which also disables triggering button's :active state when clicking on label. Overriding label's onClick event does not do that.
label {
pointer-events: none;
}
button {
pointer-events: initial;
}

Related

event.target triggers input and label elements in js

I am working on a form and in that I am using radio buttons but because of the styling issues i just hides them by display: none property. And done all the styling on its corresponding label element.
<form>
<div class="radio-input">
<input type="radio" style="display:none;" name="color" value="green" id="g2" />
<label class="square-box" for="g2"></label>
<input type="radio" style="display:none;" name="color" value="blue" id="b2" />
<label class="square-box not-allowed" for="b2"></label>
</div>
</form>
Now I have attached and event listener on that parent div and waiting for an event to bubble. But when i click label, event.target returns both label and input element. So that creates a problem.
document
.querySelector(".radio-input")
.addEventListener("click", function (event) {
if (event.target.classList.contains("not-allowed")) {
// do something...
} else {
// do something...
}
};
So in this if label has not-allowed class i wanna do some operation but because event.target returns both the elements, addeventlistener runs twice and fails the code(basically if condition).
So the two possible solutions might be
just ignore input elements by adding a condition in the if
event.target somehow don't return the input element
whatever the solution be please tell me!
As this answer, you can stop default behaviour of the addEventListener like this:
document
.querySelector(".radio-input")
.addEventListener("click", function (event) {
event.preventDefault(); // adding this to your code
if (event.target.classList.contains("not-allowed")) {
console.log("not allowed");
} else {
console.log("allowed");
}
});
You can also ignore input element:
document
.querySelector(".radio-input")
.addEventListener("click", function (event) {
if(event.target.nodeName === 'INPUT')return; // if it's input, just return
if (event.target.classList.contains("not-allowed")) {
// do something...
} else {
// do something...
}
};
As mentioned above preventDefault() or possibly stopimmediatepropagation()

How to trigger function only in parent div, not child

<button onClick={onClickParent}>
<div className={"iconDiv"}>
<div className={"iconNameDiv"}>
</button>
I have something like this structure.
When I click the button, It will change the color of the button
However, when I click the inside div, this onclick funtion didn't work.
How to prevent onclick inside div ? only parent
Generally whatever is inside a button tag should be used for the button click, so I would go for a div tag which can be used for alignment of children. Below is the code for preventing child element triggering clicks, just check the class and ensure that its the same as class of the parent div.
function test(event) {
if(event.target.className === 'test') {
console.log('execute click code');
}
}
.test {
padding: 50px;
}
<div onClick="test(event)" class="test">
<div className="test1"> asdfasdf</div>
<div className="test2"> asdfasdf</div>
</div>

How can i make a button clicked when i just click a div

<div id="mydiv"><div>
<button style="visibility:hidden; float:left"></button>
I wanna make the hidden button as is clicked when someone click the div "mydiv".
As AndrewL said, you don't need a button for this. But if you want to use a button anyways, simply assign a eventListener to your div that simulates a click on the button:
document.querySelector('#mydiv').addEventListener('click', () => {
document.querySelector('button').click();
});
Example
(I added some CSS rules and an extra function for visualization.)
document.querySelector('#mydiv').addEventListener('click', () => { // Listen for clicks on the div
document.querySelector('button').click(); // Simulate a click on the button
});
function test() { // This function gets called when clicking the button
console.log("Click!");
}
<div id="mydiv" style="height: 100px; width: 100px; background-color: red;">
<div>
<button style=" visibility:hidden; float:left; " onclick="test()"></button>
</div>
</div>
You dont need a hidden button for this. Just assign a click listener to the div itself using js like this:
const btn = document.getElementById('mydiv');
function doSomething(){
//run your script here when div is clicked
}
btn.addEventListener('click', doSomething);
You don't really need the hidden button to catch the click event. But if you really need it:
<div id="mydiv" onclick="document.getElementById('btn').click()">click on me<div>
<button id="btn" style="display:none;" ></button>
With jQuery, you can do something like this:
$('#div_id').click(function(){$('#btn_id').trigger('click');});
$('#btn_id').click(function(){//Business logic here on btn click
});

Change class group of buttons

I have three buttons and each one has a CSS class. At click of one of them, i would like remove the class and add a new CSS class only for the clicked element. Furthermore, I need to keep pressed the selected button.
I searched some examples and I found that is possible do something like this:
$(".class").removeClass("choice").addClass("active");
This works for all buttons, but not only for one. I try to change this in
$(this).removeClass("choice").addClass("active");
but this didn't work.
I make a fiddle for more compreansion: https://jsfiddle.net/90u6b3tj/3/
EDIT
I need the same behavior when i press a second time
Sorry for the basic problem.
Thanks in advance
Regards
I've updated your jsfiddle for a working solution:
https://jsfiddle.net/90u6b3tj/10/
Here's the javascript part:
$(function() {
$("button").click(function(e) {
e.preventDefault();
$(this).toggleClass("active");
});
});
as you are adding your click events like so:-
<button id="hourly" class="choice" onclick="change()">Orario</button>
you could use event.target:-
function change(){
event.preventDefault();
$(event.target).removeClass("choice").addClass("active");
}
OR, change your event and pass in this:-
<button id="hourly" class="choice" onclick="change(this)">Orario</button>
so you can do:-
function change(element){
event.preventDefault();
$(element).removeClass("choice").addClass("active");
}
OR better still:-
$('.choice').click(function(e){
e.preventDefault();
$(this).removeClass("choice").addClass("active");
});
and remove the inline click event.
You can use the following code instead.
$(".class").click(function(){
$(".class").addClass("choice");
$(".class").removeClass("active");
$(this).removeClass("choice").addClass("active");
});
Here, the "choice" class is removed only from the clicked class. Not from the others. Also the "active" class is added to the clicked one.
You may use change(this) in your button markup and refer to that element in your change() function, as shown in this fiddle.
function change(event){
event.preventDefault();
//$(".choice").removeClass("choice").addClass("active");
$(event.target).removeClass("choice").addClass("active");
}
<div>
<button id="hourly" class="choice" onclick="change(event)">Orario</button>
</div>
<div>
<button id="daily" class="choice" onclick="change(event)">Giornaliero</button>
</div>
<div>
<button id="monthly" class="choice" onclick="change(event)">Mensile</button>
</div>
Should it possible so select more than one item as active?
If not, checkout this:
Markup
<div>
<button id="hourly" class="choice">Orario</button>
</div>
<div>
<button id="daily" class="choice">Giornaliero</button>
</div>
<div>
<button id="monthly" class="choice">Mensile</button>
</div>
CSS
.active {
background-color: #A60076;
color: #FF0000;
}
.choice {
background-color: #000000;
color: #FFFFFF;
}
JS
$(document).ready(function() {
$('button').click(function(e) {
$("button").addClass('choice').removeClass('active');
$(this).removeClass('choice').addClass('active');
});
});
Here is a sample fiddle with the above code working.

Moving button doesn't receive click event

I have a text field which should hide when it loses focus. I also have a button. The problem is, when you click the button, the text field first loses focus, which moves the button, preventing it from receiving the click event.
HTML:
<div>
<p> Focus on the text field, and then click the button </p>
<div id="hideMeOnFocusOut">
<input type="text" id="focusMeOut" autofocus>
<br><br><br>
</div>
<button id="clickMe">click me</button>
</div>
JS:
$(function() {
$('#focusMeOut').on('focusout', function(e) {
$('#hideMeOnFocusOut').hide();
});
$('#clickMe').on('click', function(e) {
alert('clicked!');
});
});
http://jsfiddle.net/u86ycf5e/
The button should still move. But it should also receive the click event.
Add a container with a height around the element you are hiding: Fiddle
.container {
height: 50px;
}
HTML
<div class="container">
<div id="hideMeOnFocusOut">
<input type="text" id="focusMeOut" autofocus>
<br>
<br>
<br>
</div>
</div>
Alternatively, you could make the element hide after a short delay via setTimeout like so:
$('#focusMeOut').on('focusout', function (e) {
setTimeout(function() {
$('#hideMeOnFocusOut').hide();
}, 250);
});
Other fiddle
Try ...
$('#focusMeOut').on('focusout', function(e) {
$('#hideMeOnFocusOut').hide();
if (e.relatedTarget.id==="clickMe") {
$("#clickMe").trigger('click');
}
});
This will check to see if the button was clicked and fire it ...
Hide the text box instead with:
$('#focusMeOut').on('focusout', function(e) {
$(this).hide(); //this line changed
});
and optionally set the height of the <div> to prevent button moving with this CSS:
#hideMeOnFocusOut {
height:80px;
}
You might want to rename your IDs more appropriately now.
http://jsfiddle.net/u86ycf5e/4/

Categories

Resources