Get value from THIS element that shares class in javascript? - javascript

So the app I'm making is pulling data from a json file and rendering the data dynamically. I'm using classes because I don't think I should pull an ID name from the json file to be added into the html element.. (or should I?) - How do I get querySelector to get the value from the one I click on? And not from every element that has the same class?
<button class="playBtn" value="{{filename}}"></button>
<button class="playBtn" value="{{filename}}"></button>
<button class="playBtn" value="{{filename}}"></button>
<button class="playBtn" value="{{filename}}"></button>
<button class="playBtn" value="{{filename}}"></button>
var selectedSong = document.querySelector('.playBtn').value;
json to Button Value to onClick send value to be a new Variable

If i understands you properly...
Something like this should help
Here you just listen for clicks on all playBtn, but gets value from the one you click.
document.addEventListener('click', function(event) {
var button;
button = event.target;
if (button.classList.contains('playBtn')) {
console.log(button.getAttribute('value'));
}
});
<button class="playBtn" value="{{filename}}"></button>
<button class="playBtn" value="{{filename}}"></button>
<button class="playBtn" value="{{filename}}"></button>
<button class="playBtn" value="{{filename}}"></button>
<button class="playBtn" value="{{filename}}"></button>

var play = document.getElementsByClassName('playBtn');
for(var i=0, len=play.length; i<len; i++){
(function(index){
play[i].onclick = function(){
alert(play[index].value);
}
})(i);
}
<button class="playBtn" value="one">button one</button>
<button class="playBtn" value="two">button two</button>
<button class="playBtn" value="three">button three</button>
<button class="playBtn" value="four">button four</button>
<button class="playBtn" value="five">button five</button>

Vanilla JS
document.querySelectorAll returns a NodeList so we need to iterate over that collection and apply the event listener to each element in it. By extending the NodeList prototype we can add our own little function to add any event to each node. We then have ourselves a nice jQueryesq method to use it:
NodeList.prototype.on = function(event,func) {
[].forEach.call(this, function (el) {
el.addEventListener(event, func, false);
});
return this;//return self to maintain chainability
};
//to listen for a click on each of these:
document.querySelectorAll('.playBtn').on('click',function(){
alert(this.value);
});
You can even chain these events like this:
document.querySelectorAll('.playBtn').on('mouseover',function(){
this.style.borderColor='red';
}).on('mouseout',function(){
this.style.borderColor='';
});
Here's the demo jsFiddle and snippet:
NodeList.prototype.on = function(event,func) {
[].forEach.call(this, function (el) {
el.addEventListener(event, func, false);
});
return this;//return self to maintain chainability
};
document.querySelectorAll('.playBtn').on('click',function(){
alert(this.value);
return false;
});
document.querySelectorAll('.playBtn').on('mouseover',function(){
this.style.borderColor='red';
}).on('mouseout',function(){
this.style.borderColor='';
});
<button class="playBtn" value="a">A</button>
<button class="playBtn" value="b">B</button>
<button class="playBtn" value="c">C</button>
<button class="playBtn" value="d">D</button>
<button class="playBtn" value="e">E</button>
With jQuery
Of course if jQuery is available to you then all this is baked in. It doesn't directly answer your question of "How do I get querySelector to get the value from the one I click on?" because it's not directly using querySelector but it does do what you need:
$(function(){//wait for document ready
$(".playBtn").on("click",function(){
alert($(this).val());
});
})
Demo jsFiddle
$(function(){
$(".playBtn").on("click",function(){
alert($(this).val());
});
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button class="playBtn" value="a">A</button>
<button class="playBtn" value="b">B</button>
<button class="playBtn" value="c">C</button>
<button class="playBtn" value="d">D</button>
<button class="playBtn" value="e">E</button>

document.querySelector() will return only the first found node. document.querySelectorAll would return a list that you would need to iterate.
However, this can be done with jQuery easily:
var selectedSong = '';
$('.playBtn').on('click', function()
{
selectedSong = $(this).val();
});
See fiddle.
Or with pure JS using getElementsByClassName or querySelectorAll
var selectedSong = '';
var a_btn = document.getElementsByClassName('playBtn');
// or querySelectorAll
// var a_btn = document.querySelectorAll('.playBtn');
for(var i = 0; i < a_btn.length; i++)
{
a_btn[i].onclick = function() {
selectedSong = this.value;
};
};
See fiddle.

Related

How can I change this button background color of the specific button that i have clicked? using javascript

I want to change the button's background color of the specific button that I have clicked, do I need to use loops and also condition? I tried to access the first index but I don't know how can I change the other button's background color.
let buttons = document.querySelectorAll('.btn');
let arraySelected = [];
buttons.forEach(button => {
button.addEventListener('click', seatFunction);
});
function seatFunction(e) {
const {
value
} = e.target;
let newArray = arraySelected;
const index = arraySelected.findIndex((element) => element === value);
let findValue = arraySelected.find((element) => element == value);
if (index !== -1) {
console.log(`The ${value} has been removed into the array.`);
// console.log(`The ${index} is the '${value}' of the item that has been removed.`);
newArray.splice(index, 1);
console.log(newArray);
buttons[0].style.backgroundColor = null;
} else {
console.log(`${value} has been pushed into the array.`)
arraySelected.push(value);
console.log(arraySelected);
buttons[0].style.backgroundColor = "red";
}
// Checking if the array is empty.
if (arraySelected.length === 0) {
alert(`The last value '${value}' has been removed\r\nThe array now is empty!`);
}
}
<div class="wrapper">
<button class="btn seat" value="A">A</button>
<button class="btn seat" value="B">B</button>
<button class="btn seat" value="C">C</button>
<button class="btn seat" value="D">D</button>
<button class="btn seat" value="E">E</button>
<button class="btn seat" value="F">F</button>
</div>
You're approaching it the right way. You just need to loop over all the buttons and reset their background, and then change the background of the button you clicked on.
I'm using classList and CSS for this example.
const buttons = document.querySelectorAll('.btn');
buttons.forEach(button => {
button.addEventListener('click', seatFunction, false);
});
function seatFunction() {
buttons.forEach(btn => btn.classList.remove('active'));
this.classList.add('active');
}
.active { background-color: Tomato; }
.btn:hover { cursor: pointer; }
<div class="wrapper">
<button class="btn seat" value="A">A</button>
<button class="btn seat" value="B">B</button>
<button class="btn seat" value="C">C</button>
<button class="btn seat" value="D">D</button>
<button class="btn seat" value="E">E</button>
<button class="btn seat" value="F">F</button>
</div>
Use loop to remove bgcolor from other buttons then add it to clicked button.
let buttons = document.querySelectorAll('.btn');
let arraySelected = [];
buttons.forEach(button => {
button.addEventListener('click', function() {
seatFunction(button)
});
});
function seatFunction(a) {
buttons.forEach(button => {
button.style.background = "none";
});
a.style.background = "red";
}
<div class="wrapper">
<button class="btn seat" value="A">A</button>
<button class="btn seat" value="B">B</button>
<button class="btn seat" value="C">C</button>
<button class="btn seat" value="D">D</button>
<button class="btn seat" value="E">E</button>
<button class="btn seat" value="F">F</button>
</div>
I think you do not need all of that (loop and condition), and you do not need to create another array.
First, I advise you to work with CSS class in order to change any style, even dynamically:
.active {
background-color: #00d4b1;
}
So now the logic is when a button is clicked "if there is the active class on it, remove the active class, else attach the active class."
function seatFunction(e){
e.target.classList.toggle("active");
}
The beginning of your script is good:
let buttons = document.querySelectorAll('.btn');
buttons.forEach(button => {
button.addEventListener('click', seatFunction);
});
Why don't you install jquery, you can achieve this easily.
just put this in your html header and try
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
In your JS, put like this
$('.btn').click(function(){
$('.btn').css({"background":""});
$(this).css({"background":"red"}); //put the color you want
});

How to get the button's id value with my js?

A simple html structure.
<button id="b1">b1</button>
<button id="b2">b2</button>
<button id="b3">b3</button>
Add event listener to buttons.
var bs = document.getElementsByTagName('button');
for(var i = 0; i < bs.length; i++){
bs[i].addEventListener("click", getInfo);
}
How to write getInfo function to output button's id when clicked?
function getInfo() {
}
Only one thing you need to do is to pass the event value to your getInfo functoin.
There's an example below:
var bs = document.getElementsByTagName('button');
for(var i=0;i<bs.length;i++){
bs[i].addEventListener("click",getInfo);
}
function getInfo(e){
alert(e.target.id);
}
<button id="b1" >b1</button>
<button id="b2" >b2</button>
<button id="b3" >b3</button>

How to build a click counter with multiple click values and combine them into a total click value?

I am a newbie and I built this click counter with jquery and it is working great but it seems clunky to me and I want to make my code cleaner. So my question is how can I combine the two click functions into one function and then use the total of the two variables "click1" and "click2" as the value for the variable "sum"? I am assuming one would loop through the separate elements and add their clicks to an array and then add the values stored in the array and assign that as the total, but I am not sure where to start or if that is even possible. I am learning jquery and plain javascript so I can understand suggestions in either syntax. Thank you all!
CODEPEN: http://codepen.io/chasereckling/pen/KgArLG?editors=1010
<div class="clickButton">
<button id="updateClick1" type="button">click me</button>
<span>Number of Clicks: <span class="clickNumber">0</span></span>
</div>
<div class="clickButton">
<button id="updateClick2" type="button">click me</button>
<span>Number of Clicks: <span class="clickNumber">0</span></span>
</div>
<div>Total Clicks: <span id="sumClicks">0</span></div>
<script>
var count1 = 0;
var count2 = 0;
var sum = 0;
$('#updateClick1').click(function() {
count1++;
sum++;
$(this).siblings().children('.clickNumber').html(count1);
$('#sumClicks').html(sum);
});
$('#updateClick2').click(function() {
count2++;
sum++;
$(this).siblings().children('.clickNumber').html(count2);
$('#sumClicks').html(sum);
});
</script>
You can do something like this:
var sum = 0;
function clickHandler () {
var $target = $(this),
$span = $target.siblings("span").children(".clickNumber"),
$sum = $("#sumClicks");
$span.text(parseInt($span.text()) + 1);
sum += 1;
$sum.text(sum);
}
$('button[type="button"]').click(clickHandler);
Here is codepen:
sum of clicks
Check the following code snippet
var count=0;
var sum = 0;
var $sumElement=$('#sumClicks');
sum=parseInt($sumElement.html());
$(document).ready(function(){
$('button').click(function() {
var element=$(this);
var $clickCount=$(this).siblings().children('.clickNumber');
var clickCountVal=parseInt($clickCount.html());
clickCountVal++;
sum++;
$clickCount.html(clickCountVal);
$sumElement.html(sum);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="clickButton">
<button id="updateClick1" type="button">click me</button>
<span>Number of Clicks: <span class="clickNumber">0</span></span>
</div>
<div class="clickButton">
<button id="updateClick2" type="button">click me</button>
<span>Number of Clicks: <span class="clickNumber">0</span></span>
</div>
<div>Total Clicks: <span id="sumClicks">0</span></div>
Hope this helps
You could try something like this, it'll be a bit cleaner:
<div class="clickButton">
<button id="updateClick1" type="button">click me</button>
<span>Number of Clicks: <span class="clickNumber1">0</span></span>
</div>
<div class="clickButton">
<button id="updateClick2" type="button">click me</button>
<span>Number of Clicks: <span class="clickNumber2">0</span></span>
</div>
<div>Total Clicks: <span id="sumClicks">0</span></div>
var count = [0,0];
$('#updateClick1').click(function() {
count[0]++;
$('.clickNumber1').html(count[0]);
$('#sumClicks').html(count[0] + count[1]);
});
$('#updateClick2').click(function() {
count[1]++;
$('.clickNumber2').html(count[1]);
$('#sumClicks').html(count[0] + count[1]);
});
JSFIDDLE: https://jsfiddle.net/s7pw5oqs/1/

(One button creates one element) multiple times

I'm trying to have a setup where there are multiple buttons that each add one element (and one only) to a list (further down my webpage) + disables the button which was just clicked (but not the other buttons). Moreover, if you click on the corresponding element that was created, it deletes itself and enables the corresponding button back.
I managed to do it for one instance of a button, with the following code :
Javascript :
var btn1 = document.getElementById('btn1')
, sortie = document.getElementById('sortie');
function createSortie() {
var d = document.createElement("span");
d.id = "sortieBtn1";
d.className = "label label-success";
d.onclick = removeSelf;
d.innerHTML = "Hey, sup', now click on me to make me disappear";
sortie.appendChild(d);
}
function removeSelf() {
document.getElementById('sortieBtn1').remove();
document.getElementById('btn1').disabled = false;
}
function modifyButton(a) {
document.getElementById(a).disabled = true;
}
HTML :
<button class="btn btn-primary" id="btn1" onclick="createSortie();modifyButton(this.id)">Click on me to create a new element</button><br />
<br/>
<br/>
Sortie :
<div id="sortie"></div>
Example : http://www.codeply.com/go/SEL7ZqBI49
I now want it for multiple buttons, I could of course do something like this, but there are smarter ways to do achieve what I need (*), namely, more buttons and obviously, without having designated functions for each pair of button/created element.
(*) : maybe - but not mandatory - with something similar to function factories in R ?
Any idea on how to achieve that ? Thanks.
You can actually pass the reference to the clicked button as a parameter to the onclick function which makes things lots easier than trying to work with ids. Also, you won't have to find the elements every time and thus you can apply to as many items as you want. Check a working example:
var btns = document.getElementsByClassName('.btn'),
sortie = document.getElementById('sortie');
// Creates the labels on the output div when a button is clicked
function createSortie(button) {
// Create a label using a <span> element
var label = document.createElement("span");
// The ID will not be used but it's useful to link it to the
// originating button in some way
label.id = "sortie" + button.id;
label.className = "label label-success";
// Set click handler on the label
label.onclick = function() {
// Remove itself, using self-reference as argument
removeLabel(label);
// Toggle the originating button to enabled again
// (disabled = false)
toggleButton(button, false);
};
label.innerHTML = "I''m label for " + button.id;
// Set button to disabled
toggleButton(button, true);
// Add this label to sortie
sortie.appendChild(label);
}
// Removes a label, passed as parameter
function removeLabel(label) {
label.remove();
}
// Toggles a button ON or OFF, as specified on the state parameter
function toggleButton(button, state) {
button.disabled = state;
}
.label {
cursor: pointer;
display: block;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<h3>Buttons</h3>
<button class="btn btn-primary" id="btn1" onclick="createSortie(this);">Element 1</button>
<br />
<button class="btn btn-primary" id="btn2" onclick="createSortie(this);">Element 2</button>
<h3>Sortie :</h3>
<div id="sortie">
</div>
I also forked your Codeply: http://www.codeply.com/go/cJwYL0iBeY
Feel free to ask anything.
If you use classes for the buttons, and then use a number in the ID's, it would be easy to target the sortie belonging to each button, something like
var buttons = document.getElementsByClassName('btn');
for (var i=0; i<buttons.length; i++) {
buttons[i].addEventListener('click', btnClick);
}
function btnClick() {
var sortie = document.getElementById('sortie' + this.id.replace('btn',''));
createSortie(sortie, this);
}
function createSortie(sortie, button) {
var d = document.createElement("span");
d.className = "label label-success";
d.addEventListener('click', function() {
button.disabled = false;
this.remove();
});
d.innerHTML = "Hey, sup', now click on me to make me disappear";
sortie.appendChild(d);
button.disabled = true;
}
<button class="btn btn-primary" id="btn1">Click on me to create a new element</button><br />
<br/><br/>
Sortie :
<div id="sortie1"></div>
<br/><br/>
<button class="btn btn-primary" id="btn2">Click on me to create a new element</button><br />
<br/><br/>
Sortie :
<div id="sortie2"></div>
<br/><br/>
<button class="btn btn-primary" id="btn3">Click on me to create a new element</button><br />
<br/><br/>
Sortie :
<div id="sortie3"></div>
I created a fiddle for you, it is mostly based on relative selection and not on IDs, i pass the whole element in function and then do further action on that basis, have a look
Fiddle
HTML
<div>
<button class="btn btn-primary" id="btn1" onclick="createSortie(this);modifyButton(this)">Click on me to create a new element</button><br />
<br/>
<br/>
Sortie :
<div class="sortie"></div>
</div>
<div>
<button class="btn btn-primary" id="btn1" onclick="createSortie(this);modifyButton(this)">Click on me to create a new element</button><br />
<br/>
<br/>
Sortie :
<div class="sortie"></div>
</div>
JS
function createSortie(elem) {
elem.parentElement.querySelector('.sortie').innerHTML+='<span class="label label-success" onclick="removeSelf(this)">Hey, sup, now click on me to make me disappear</span>';
}
function removeSelf(ele) {
console.log( ele.parentElement.parentElement.querySelector('button'));
ele.parentElement.parentElement.querySelector('button').removeAttribute('disabled')
ele.remove();
}
function modifyButton(ele) {
ele.setAttribute('disabled','disabled')
}

changing a button text after loading/resetting by bootstrap

I'm trying to create like / unlike buttons using bootstrap3.
Here is my button
<button type="button" id="testBtn"
class="btn btn-success glyphicon glyphicon-thumbs-up"
data-loading-text=" ... " onclick="like()" >
4</button>
Here is a simplified version of my JavaScript function without AJAX call:
function like(){
var btn = $('#testBtn');
btn.button('loading');
var current = parseInt(btn.text());
current++;
console.log(current);
btn.button('reset');
btn.text(current);
}
Usually this works and button text increments on each click.
However now that I'm using bootstrap, after resetting the button it keeps the old text even though in the console.log(current); I see a new incremented one.
I think because I'm using bootstrap button loading/resetting I have to do something else to change button text.
'btn.text()' is getting data-loading-text value, not '4'. So I updated my answer which created vote up and down for you in FIDDLE
HTML
<button type="button" id="testBtn" class="btn btn-success glyphicon glyphicon-thumbs-up" data-loading-text=" ... ">
4</button>
<button type="button" id="testBtnDown" class="btn btn-success glyphicon glyphicon-thumbs-down" data-loading-text=" ... ">
4</button>
JS
$('#testBtn').click(function () {
var cnt=4;
var btn = $(this);
btn.button('loading');
setTimeout(function () {
cnt++;
btn.button('reset');
btn.text(' ' + cnt);
}, 1000);
});
$('#testBtnDown').click(function () {
var cnt=4;
var btn = $(this);
btn.button('loading');
setTimeout(function () {
if (cnt > 0) {
cnt--;
}
btn.button('reset');
btn.text(' ' + cnt);
}, 1000);
});
The reason for this is related to that function not being on the global context. You can find more details on this answer here.
Basically, recommendation is to do the binding on Document Ready and not to use onclick for this.
Hope this helps!

Categories

Resources