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!
Related
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 can I get the value of the button that the user clicked. I tried this but it doesn't work
for (var i = 0; i < 4; i++) {
var x = document.getElementsByClassName("button")[i].onclick() = function(){
console.log(x);
}
}
$("button").click(function() {
alert($(this).html()); // for the text in button tag. for value in button tag use $(this).val()
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="up" value="up">button up</button>
<button id="down" value="down">button down</button>
if you don't want to use jquery and use only pure javascript you can do following:
<button id="up" value="up" onclick="alert(this.value)">button up</button><!-- for value -->
<button id="down" onclick="alert(this.innerHTML)">button down</button><!-- for text in tag -->
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')
}
I made such a simple code to show and hide div but i don't know why it works only once. When i show and hide other div, then when iw ant to do it again it dosen't work. Here is code (content of div is not important). In css i set display:none on both of divs
function pokazMail(ID) {
if (document.getElementById(ID).style.display != 'none') {
if (document.getElementById('wizyta').style.display == 'block') {
document.getElementById('wizyta').style.display = 'none';
document.getElementById(ID).style.display = 'block';
} else {
document.getElementById(ID).style.display = 'block';
}
}
}
function pokazWizyta(ID) {
if (document.getElementById(ID).style.display != 'none') {
if (document.getElementById('mail').style.display == 'block') {
document.getElementById('mail').style.display = 'none';
document.getElementById(ID).style.display = 'block';
} else {
document.getElementById(ID).style.display = 'block';
}
}
}
#mail{display:none;}
#wizyta{display:none;}
<a class="btn btn-primary btn-lg" onclick="pokazMail('mail');">First.</a>
<a class="btn btn-primary btn-lg" onclick="pokazWizyta('wizyta');">Second.</a>
<div id="mail">dsjdhs </div>
<div id="wizyta">12313213</div>
Here it is: http://jsfiddle.net/Lcbm8m8m/
function pokazMail(IDtoShow,IDtoHide) {
document.getElementById(IDtoShow).style.display = 'block';
document.getElementById(IDtoHide).style.display = 'none';
}
#mail{display:none;}
#wizyta{display:none;}
<a class="btn btn-primary btn-lg" onclick="pokazMail('mail','wizyta');">First.</a>
<a class="btn btn-primary btn-lg" onclick="pokazMail('wizyta','mail');">Second.</a>
<div id="mail">dsjdhs </div>
<div id="wizyta">12313213</div>
You should use jQuery methods like .hide() and .show()
Here is and example of using it:
function pokazMail(ID) {
$("#mail").show();
$("#wizyta").hide();
}
function pokazWizyta(ID) {
$("#mail").hide();
$("#wizyta").show();
}
jsFiddle
function pokazMail(ID) {
$("#mail").show();
$("#wizyta").hide();
}
function pokazWizyta(ID) {
$("#mail").hide();
$("#wizyta").show();
}
#mail{display:none;}
#wizyta{display:none;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a class="btn btn-primary btn-lg" onclick="pokazMail('mail');">First.</a>
<a class="btn btn-primary btn-lg" onclick="pokazWizyta('wizyta');">Second.</a>
<div id="mail">dsjdhs </div>
<div id="wizyta">12313213</div>
I guess you can use Jquery since I see you using bootstrap classes. Using your approach checking if the display is block then hiding it:
//javascript
function pokazMail(ID) {
if($("#wizyta").css('display') == "block"){
$("#wizyta").css("display", "none");
}
$("#mail").css("display", "block");
}
function pokazWizyta(ID) {
if($("#mail").css('display') == "block"){
$("#mail").css("display", "none");
}
$("#wizyta").css("display", "block");
}
//css
#mail{display:none;}
#wizyta{display:none;}
<!--html-->
<a class="btn btn-primary btn-lg" onclick="pokazMail('mail');">First.</a>
<a class="btn btn-primary btn-lg" onclick="pokazWizyta('wizyta');">Second.</a>
<div id="mail">dsjdhs </div>
<div id="wizyta">12313213</div>
The problem you've stated was a little bit off than what your code was trying to achieve... BUT I THINK I've understood what you're actually trying to achieve...
So, if this is what you are trying to achieve than my solution will work just fine:
You expect than when you click on a display control element, other 'similar' associated elements are hidden but the one that's associated to the display control element you've clicked... A bit of a mouthful, right? Sorry, but I am not a native English person :(
So the code, as generic as possible is the one I've set you up with on your jsfiddle http://jsfiddle.net/Lcbm8m8m/71/
Anyway, just in case someone comes up w/ a better idea and overrides the fiddle, here's the code as well..
HTML
<a class="btn btn-primary btn-lg" onclick="javascript: hideAllButMe('mail');">First.</a>
<a class="btn btn-primary btn-lg" onclick="javascript: hideAllButMe('wizyta');">Second.</a>
<a class="btn btn-primary btn-lg" onclick="javascript: hideAllButMe('third');">Third.</a>
<a class="btn btn-primary btn-lg" onclick="javascript: hideAllButMe('fourth');">Fourth.</a>
<div id="mail" class="carouselle hidden">MAIL</div>
<div id="wizyta" class="carouselle hidden">WIZTYA</div>
<div id="third" class="carouselle hidden">THIRD</div>
<div id="fourth" class="carouselle hidden">FOURTH</div>
CSS
.hidden{display:none;}
.carouselle{}
JAVASCRIPT
function hideAllButMe(show) {
// Get all the elements on the page with the 'carouselle' class name.
var elementsMarkedForHidingList = document.getElementsByClassName('carouselle');
// document.getElementsByClassName returns a NodeList and this turns it into an array
var nodeArray = Array.prototype.slice.call(elementsMarkedForHidingList);
// we iterate the array and hide all the elements...
nodeArray.map( function(item) {
addClass(item, 'hidden');
});
// and we show the one referenced by the element we've clicked...
removeClass(document.getElementById(show), 'hidden');
}
function addClass(el, className) {
var cls = el.className.match(/\S+/g) || [];
if (!hasClass(el, className)) {
cls.push(className);
}
el.className = cls.join(' ');
}
function removeClass(el, className) {
var cls = el.className.match(/\S+/g) || [];
if (hasClass(el, className)) {
cls.pop(className);
}
el.className = cls.join(' ');
}
function hasClass(el, className) {
var re = new RegExp('(^|\\s+)' + className + '(\\s+|$)');
return re.test(el.className);
}
However, I strongly suggest using a javascript library such as JQuery for DOM manipulation and don't get carried away like myself and write vanilla 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.