I have a button as such whose id I am not aware of
<button id="" class="mybtn" type=""></button>
and now I want to get the id of this button on click
("//what to write here").click(){
console.log($(this).id);//something like this i want
}
but the problem with using class selector is that I have multiple buttons which so it will select all of them and not just the one which is clicked.
You can do it like this. I commented the code for the syntax
$("button.mybtn").on("click", function() {
console.log($(this).attr("id")); // return blank when no id
console.log(this.id); // return undefined when no id
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="hello" class="mybtn" type="">Sample</button>
<button id="hello1" class="mybtn" type="">Sample</button>
The event handler below is attached to all buttons (elements) with the class .btn but since you can only click one button at a time, you will only see one id per click - the id of the button clicked:
$('.mybtn').on('click', function() {
console.log( this.id );
});
$(function() {
$('.mybtn').on('click', function() {
console.log( this.id );
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="id1" class="mybtn" type="">Button 1</button>
<button id="id2" class="mybtn" type="">Button 2</button>
<button id="id3" class="mybtn" type="">Button 3</button>
<button id="id4" class="mybtn" type="">Button 4</button>
Related
I'm trying to make a copy of the original container div with the cloneNode method in javascript inside the container there are 3 buttons with btn class, when I make a copy of the original one the last only the last element in the copied item is only printing hello in the console, any ideas?
let add = document.querySelector('.add-button');
const item = document.querySelector('.container');
let btn = document.querySelectorAll('.btn');
add.addEventListener('click', function() {
makecopy();
});
btn.forEach(el => {
el.addEventListener('click', function() {
console.log("hello")
})
});
function makecopy() {
let copiedItem = item.cloneNode(true);
item.parentNode.insertBefore(copiedItem, item);
}
<div class="add-panel">
<button type="button" class="add-button">Create new</button>
</div>
<div class="container">
<div>
<button type="button" class="btn">+</button>
</div>
<div>
<button type="button" class="btn">+</button>
</div>
<div>
<button type="button" class="btn">+</button>
</div>
You are only setting up event listeners on the first set of buttons, not the cloned ones. Instead of setting up listeners on each button, use "event delegation" to allow the event to "bubble" up to a common ancestor and handle the event there. This way, all the newly added elements will immediately work without needing their own handler and there is only one handler that needs to be set up instead of many.
You've also got some redundant code and code that will no longer be needed when you take this approach.
// No need to set up an anonymous handler that calls the real one. Just
// register the real one
document.querySelector('.add-button').addEventListener('click', makecopy);
const item = document.querySelector('.container');
function makecopy() {
let copiedItem = item.cloneNode(true);
item.parentNode.insertBefore(copiedItem, item);
}
// Listen for clicks on the document:
document.addEventListener('click', function(event) {
// Check to see if it was a button that was clicked:
if(event.target.classList.contains("btn")){
console.log("hello");
};
});
<div class="add-panel">
<button type="button" class="add-button">Create new</button>
</div>
<div class="container">
<div>
<button type="button" class="btn">+</button>
</div>
<div>
<button type="button" class="btn">+</button>
</div>
<div>
<button type="button" class="btn">+</button>
</div>
</div>
Just appears you weren't adding new listeners when you made new buttons. Some adjustments.
let add = document.querySelector('.add-button');
const item = document.querySelector('.container');
let btn = document.querySelectorAll('.btn');
add.addEventListener('click', function() {
makecopy();
});
btn.forEach(el => {
el.addEventListener('click', function() {
console.log("hello")
})
});
function makecopy() {
let copiedItem = item.cloneNode(true);
item.parentNode.insertBefore(copiedItem, item);
copiedItem.addEventListener('click', function() {
console.log("hello")
})
}
<div class="add-panel">
<button type="button" class="add-button">Create new</button>
</div>
<div class="container">
<div>
<button type="button" class="btn">+</button>
</div>
<div>
<button type="button" class="btn">+</button>
</div>
<div>
<button type="button" class="btn">+</button>
</div>
Is it possible to create a function that returns which button was pressed, even though all buttons have the same class?
It is important that the classes of the buttons must not be changed.
<html>
<body>
<button class="button">text</button>
<button class="button">text</button> //this button was clicked
<button class="button">text</button>
</body>
</html>
The code is only for visualisation I know it isn't right.
function myfunction(){
console.log(clickedbutton)
}
What I have to fill in so the code runs?
Sorry for the bad code i don't know how to make it more clearly.
Hello and happy new 2021!
I think this might be a slight duplicate of this.
As Gabriele said, you can get the HTML element by using the target. If you need some logic for differentiating the structures (using them in some state later on), you would need to assign an id or a different class.
Delegate
document.getElementById("buttonDiv").addEventListener("click",function(e) {
const tgt = e.target;
if (tgt.classList.contains("button")) console.log(tgt.textContent,"clicked")
})
<div id="buttonDiv">
<button class="button">text 1</button>
<button class="button">text 2</button>
<button class="button">text 3</button>
</div>
When an event happens and the handler that is bound to that event for that element is called, it is passed the event as the first parameter. And one of the properties of the event is the target which points to the element that triggered the event.
so
function clickHandler(event) {
const clickedElement = event.target;
console.log(clickedElement.textContent);
}
document
.querySelectorAll('.button')
.forEach(button => button.addEventListener('click', clickHandler))
<button class="button">text 1</button>
<button class="button">text 2</button>
<button class="button">text 3</button>
If you assign a function to the onClick event of a button (or multiple buttons), you can receive the event info as an argument, like so:
function myfunction(e) {
console.log(e.target.id)
}
<!DOCTYPE html>
<html>
<body>
<button id="button-1" class="button" onclick="myfunction(event)">text</button>
<button id="button-2" class="button" onclick="myfunction(event)">text</button>
<button id="button-3" class="button" onclick="myfunction(event)">text</button>
</body>
</html>
You can make use of data-id for getting index of button clicked.
const button = document.querySelectorAll(".button");
function getClickedIndex(evt) {
console.log(evt.target.getAttribute("data-id"));
}
button.forEach(button => button.addEventListener('click', getClickedIndex))
<html>
<body>
<button class="button" data-id="1">text</button>
<button class="button" data-id="2">text</button>
<button class="button" data-id="3">text</button>
</body>
</html>
I'm encountering a typical situation while accessing the innerHTML property using jQuery. I've fetched the target button using the jQuery attribute selector.
Below is the snippet of jQuery attribute selector.
jQuery('button[type="button"][class="btn btn-primary"]').each(function () {
var btn = jQuery(this);
console.log(btn);
if (btn[0].innerHTML === "OK") {
console.log("ok");
jQuery(this).click();
}
});
Following is the screenshot of the console log of the target button. It's innerHTML property is set to OK.
Following is the screenshot of the value of the innerHTML while debugging the target button object. In this case the value is "".
Ideally, the values of the innerHTML should be the same for both the cases.
EDIT
Why does this behavior differ that the ideal one? For both of the cases, the value of the innerHTML should be the same.
Also, there were multiple buttons. I have taken screenshots of different buttons. Thus their ID's are different. But still, the behavior is same.
Try something like this.
function SomeEvent($ele) {
alert($ele.html());
return false;
}
function invokeBtnEvents() {
$("[data-action=some-event]").off(); // clear old events
$("[data-action=some-event]").on("click", function() {
var $this = $(this);
return SomeEvent($this);
}) // define event(s)
return false;
}
$(document).ready(function() {
invokeBtnEvents();
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="row">
<div class="col-12">
<br />
<button data-action="some-event" class="btn btn-primary">Button 1</button>
<button data-action="some-event" class="btn btn-primary">Button 2</button>
<button data-action="some-event" class="btn btn-primary">Button 3</button>
<button data-action="some-event" class="btn btn-primary">Button 4</button>
</div>
</div>
</div>
Your issue
What you are doing that I think is your main issue is the $.each() method.
Store the buttons in a variable,
let $button = $("button"); // this returns an array of all the buttons on the DOM
You can then use the $.each() method to get the clicked element
$.each($button, function(index, btn){
const $this = $(btn);
$this.off();
$this.click(function(){someEvent($this)});
});
I would not invoke button clicks like this because every time you click a button, this each loop gets ran. It will then send all of the buttons to that action unless you parse by an ID or something (you are using the innerText).
If you use the code in my snippet, only the clicked button will be triggered.
An alternative approach to my first snippet is using something like a dispatcher.
function DoActionOneClick($ele){
alert("Action 1 " + $ele.html());
}
function DoDefaultClick($ele){
alert("Default Action " + $ele.html());
}
function DispatchEvent(action, $ele){
switch(action){
case "some-event-1":
DoActionOneClick($ele);
break;
default:
DoDefaultClick($ele);
break;
}
}
function invokeActions(){
$("[data-action]").off();
$("[data-action]").on("click", function(){
// get this
var $this = $(this);
// get action
var action = $this.data().action;
DispatchEvent(action, $this);
});
}
$(document).ready(function(){
invokeActions();
})
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="row">
<div class="col-12">
<br />
<button data-action="some-event-1" class="btn btn-primary">Button 1</button>
<button data-action="some-event-2" class="btn btn-primary">Button 2</button>
<button data-action="some-event-2" class="btn btn-primary">Button 3</button>
<button data-action="some-event-2" class="btn btn-primary">Button 4</button>
</div>
</div>
</div>
I have multiple buttons with the same class on my page, now when I try to call a method on the click event of the button, that method executes for all of the buttons because they have the same class.
The buttons on my page are dynamically created so I cant give different class to each button.
I am looking for a way to only execute some particular method on the click of the first element with the given class.
By using Jquery's .first() function, you can get the first element and then only bind the click event to it.
$(".sameClass").first().on("click", function() { console.log("clicked"); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="sameClass">Button 1</button>
<button class="sameClass">Button 2</button>
<button class="sameClass">Button 3</button>
Here it is:
$("button").each(function(i, item) {
if(i === 0) {
$(item).on("click", function() {
console.log('works only for the first button');
})
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class"test-class">btn 1</button>
<button class"test-class">btn 2</button>
<button class"test-class">btn 3</button>
<button class"test-class">btn 4</button>
<button class"test-class">btn 5</button>
I'm looping through all buttons and adding event listener only for the first of them.
I want to pass a parameter of my button values to dropdown list. The source code below is working but only for one button "Base 1", then if I press the other button the value in dropdown list will not change and still shows "Base 1"!
<div class="uk-margin">
<div data-uk-button-radio="">
<button id="sunny" class="uk-button" onclick="passValues()" value="1">Base 1</button>
<button id="sunny" class="uk-button" onclick="passValues()" value="2">Base 2</button>
</div>
and for my dropdown
document.getElementById('Floor').value = document.getElementById('sunny').value;
Two elements cannot have the same ID. Give same class names.
Then you can get correct value from this.value from the button click event.
<button class="sunny" class="uk-button" value="1">Base 1</button>
<button class="sunny" class="uk-button" value="2">Base 2</button>
var buttons = document.getElementsByClassName("sunny");
for (var i = 0; i < buttons.length; i++) {
buttons[i].addEventListener("click", function(e) {
alert(this.value);
});
};
<script type="text/JavaScript">
function passValues(el)
{document.getElementById('Floor').value =el.value}
</script>
and for button:
onclick="passValues(this)"