I need to disable all buttons that match by class name and after the function runs, enable them back. I've tried the following but no luck.
let stb = document.getElementsByClassName("btn-st");
for (let i = 0; i < stb.length; i++) {
stb.onclick = null;
}
// run some additional functions and enable
stb.onclick = true;
What am I missing?
So the main two things that are missing is that the document.getElementsByClassName("btn-st"); returns an array so when you first go through and disable the .onclick you would have to do:
let stb = document.getElementsByClassName("btn-st");
for (let i = 0; i < stb.length; i++) {
stb[i].onclick = null;
}
For the second portion, a couple people have mentioned that setting .onclick = true; doesn't really make sense, so instead you should set the onclick to an unnamed function with the following:
// run some additional functions and enable
for (let i = 0; i < stb.length; i++) {
stb[i].onclick = function() {
// do things when this button is clicked
};
}
You need to loop through stb again:
let stb = document.getElementsByClassName("btn-st");
for (let i = 0; i < stb.length; i++) {
stb[i].onclick = null;
}
// run some additional functions and enable
for (let i = 0; i < stb.length; i++) {
stb[i].onclick = true;
}
Keep in mind however that setting the onclick attribute to null won't disable the event (see #Jeremy Thille's comment).
If you want to disable a button, you should instead set its disabled property:
let stb = document.getElementsByClassName("btn-st");
for (let i = 0; i < stb.length; i++) {
stb[i].disabled = true;
}
// run some additional functions and enable
for (let i = 0; i < stb.length; i++) {
stb[i].disabled = false;
}
Related
So... I'm making a page that has notifications, a mark as read button and a mark all as read button, when i try to activate the mark all as read using my loop
let markAllAsRead = () => {
let buttons = document.getElementsByClassName("markAsRead");
let notifications = document.getElementsByClassName("notification");
let newValue = Number(counter.innerText) - 7;
if (newValue < 0) {
newValue = 0;
}
console.log(buttons);
counter.innerText = newValue;
for (let i = 0; i < notifications.length; i++) {
notifications[i].classList.remove("new");
}
for (let i = 0; i < buttons.length; i++) {
buttons[i].remove(buttons[i]);
}
};
it only will eliminate one element yes and other no like so:
live test of the function
I'm back just to update this one, the problem it self was
for (let i = 0; i < buttons.length; i++) {
buttons[i].remove(buttons[i]);
}
instead of make it look for a "default loop" I made "i" be equal to the HTMLCollection lenght, then i>= 0; --i
for (let i = buttons.length - 1; i >= 0; --i) {
buttons[i].remove();
}
making it, the function works as it should removing all the buttons of mark as read.
The current process of setting multiple inputs to disabled works for me, but seems to be way too much code due to the multiple for loops:
var textEditors = document.getElementsByClassName('textEditor'),
textareas = document.getElementsByTagName('textarea'),
radioInputs = document.getElementsByClassName('radioSelect'),
textInputs = document.getElementsByTagName('input');
for (var i = 0; i < textEditors.length; i++) {
textEditors[i].disabled = true;
}
for (var g = 0; g < textInputs.length; g++) {
textInputs[g].disabled = true;
}
for (var f = 0; f < textareas.length; f++) {
textareas[f].disabled = true;
}
for (var z = 0; z < radioInputs.length; z++) {
radioInputs[z].disabled = true;
}
But this above works fine for me. The below is what I would assume would work instead - put all elements into a single array, and iterate over a single array to set each to disabled. When I view the HTMLCollection via console.log it says disabled:true yet the element on the screen is not disabled. What am I missing here?
var textEditors = document.getElementsByClassName('textEditor'),
textareas = document.getElementsByTagName('textarea'),
radioInputs = document.getElementsByClassName('radioSelect'),
textInputs = document.getElementsByTagName('input');
var normalInputs = [];
normalInputs.push(textEditors);
normalInputs.push(textInputs);
normalInputs.push(radioInputs);
normalInputs.push(textareas);
for (var i = 0; i < normalInputs.length; i++) {
console.log(normalInputs[i])
normalInputs[i].disabled = true;
}
This will serve your purpose.
In your second method you're pushing the array capture from getElement into normalInputs array and than looping through that array and applying disable property on elements of inputArray which is eventually array of all the selected elements not individual element.
var textEditors = document.getElementsByClassName('textEditor'),
textareas = document.getElementsByTagName('textarea'),
radioInputs = document.getElementsByClassName('radioSelect'),
textInputs = document.getElementsByTagName('input');
var normalInputs = [];
normalInputs.push(textEditors);
normalInputs.push(textInputs);
normalInputs.push(radioInputs);
normalInputs.push(textareas);
normalInputs.forEach(e=>{
e.forEach(ele =>{
ele.disabled = true;
})
})
Without ES6
for (var i = 0; i < normalInputs.length; i++) {
for(let j=0; j< normalInputs[i].length; j++){
normalInputs[i][j].disabled = true;
}
}
A better approach is use concat
var normalInputs = [];
normalInputs = normalInputs.concat(textEditors,textInputs,radioInputs, textareas);
for(let i=0; i<normalInputs.length; i++){
normalInputs[i].disabled = true;
}
Well, give all of them same class like .inputs and get all of them with one expression:
var items = document.querySelectorAll( '.inputs' );
if it's not possible, get all of them like this:
var items = document.querySelectorAll( 'input, .textEditor, .radioSelect, textarea' );
then you can fix that with one loop for all of them:
for ( var i = 0; i < items.length; i++ )
items[ i ].disabled = true;
I don't understand what the problem is. Do I have to give them unique names? If so how can I do that?
var co = document.querySelector("div");
var buttons = [];
for (i = 0; i < 10; i++) {
button = document.createElement("button");
buttons.push("button");
co.appendChild(button);
}
for (i = 0; i < 9; i++) {
buttons[i].style.backgroundColor = "blue";
}
You may push the button variable, not the string.
buttons.push(button);
For iterating the buttons, you may take the length property for iterating all buttons.
for (i = 0; i < button.length; i++) {
Don't forget to declare the index variable i at top.
var i;
Fully example of what you want :)
var co = document.querySelector("div");
var colors = ["blue","red","green","orange","black","violet","blueviolet"]
var buttons = [];
for (i = 0; i < 10; i++) {
button = document.createElement("button");
buttons.push(button);
co.appendChild(button);
}
for (i = 0; i < buttons.length; i++) {
buttons[i].style.backgroundColor = colors[Math.floor(Math.random() * colors.length)];
}
<div></div>
I have a list of events on a page. My end goal is to hide a purchase button (by adding a class to it) if the event has passed, using JQuery/Javascript. Each event has a 3 data attributes(month, day, year). I tried using the following method to cycle through an array:
var matches = document.querySelectorAll(".event-event");
var i = 0;
for (i = 0; i < matches.length; i++) {
var event = matches[i].getElementsByClassName('date');
var eventDate = event.getAttribute('data-date');
}
But it says that "getAttribute" is not a function, I've also tried ".attr" and it said the same thing.
var matches = document.querySelectorAll(".event-event");
for (var i = 0; i < matches.length; i++) {
var event = matches[i].getElementsByClassName('date');
if (event.length > 0) {
for (var j = 0; j < event.length; j++) {
var eventDate = event[i].getAttribute('data-date');
}
}
}
The getElementsByClassName method returns an array.
Try this:
var matches = document.querySelectorAll(".event-event");
for (var i = 0; i < matches.length; i++) {
var events = matches[i].getElementsByClassName('date');
for(var j = 0; j < events.length; j++) {
var eventDate = events[j].getAttribute('data-date');
}
}
events is an array that you must iterate through.
I want to clone some players inside my .shuffler div. Because I attached click-listeners to the .player divs I want to append the entire object instead of just their HTML.
When I loop through the code below I do get the correct result when logging playerClones[j] in the each loop but it doesn't append anything.
Any ideas on how to clone my players and append every player 25 times to my .shuffler. without losing the click listener?
this.amountOfDuplicates = 25;
var playerClones = [];
this.parentObject.find('.player').each(function () {
playerClones.push(jQuery(this).clone());
});
for (var i = 0; i < this.amountOfDuplicates; i++) {
for (var j = 0; j < playerClones.length; j++) {
this.parentObject.find('.shuffler').append(playerClones[j]);
}
}
Fiddle here!
Normally when you use $(this).clone(), everything of the object is cloned except the click listener.
It is better if you could declare a function like this and call it every time u clone the object.
attachClickToClone = function() {
$('.player').on('click', function() {
//to-do-function
}
}
And call it like this.
for (var i = 0; i < this.amountOfDuplicates; i++) {
for (var j = 0; j < playerClones.length; j++) {
this.parentObject.find('.shuffler').append(playerClones[j]);
}
}
attachClickToClone();