JavaScript I have to click twice to select to element - javascript

Please anyone can help to fix the issue with my code, sometimes I have to click twice to select the next elements
var varientbtn = document.getElementsByClassName('clickthisbtn');
for(let i = 0; i < varientbtn.length; i++) {
varientbtn[i].onclick = function () {
const rbs = document.querySelectorAll('input[name="choice"]');
let selectedValue;
let varientSelectedPrice;
for (const rb of rbs) {
if (rb.checked) {
selectedValue = rb.value;
varientSelectedPrice = rb.getAttribute("data-price");
break;
}
}
document.getElementById('log').innerHTML = selectedValue;
document.getElementById('varientprice').innerHTML = varientSelectedPrice;
console.log(selectedValue, varientSelectedPrice);
}
}
Live preview:
https://codepen.io/Elkazi/pen/wvJeErg

That's because when one of labels be clicked, the checked value of related radio still not change.
Try this
const rbs = document.querySelectorAll('input[name="choice"]');
for(let i = 0; i < rbs.length; i++) {
rbs[i].addEventListener('change', function () {
let selectedValue;
let varientSelectedPrice;
for (const rb of rbs) {
if (rb.checked) {
selectedValue = rb.value;
varientSelectedPrice = rb.getAttribute("data-price");
break;
}
}
document.getElementById('log').innerHTML = selectedValue;
document.getElementById('varientprice').innerHTML = varientSelectedPrice;
console.log(selectedValue, varientSelectedPrice);
});
}
rbs[0].dispatchEvent(new Event('change'));

Since you are adding event listener to the label element, you should make use of its for attribute to get the related input field. That way you don't have to run a loop for all inputs and will always get the latest/correct value.
this will point to the element on which the event handler is called.
var varientbtn = document.getElementsByClassName('clickthisbtn');
for(let i = 0; i < varientbtn.length; i++) {
varientbtn[i].onclick = function () {
let relatedInput = document.getElementById(this.getAttribute("for"));
let selectedValue = relatedInput.value;
let varientSelectedPrice = relatedInput.getAttribute("data-price");;
document.getElementById('log').innerHTML = selectedValue;
document.getElementById('varientprice').innerHTML = varientSelectedPrice;
console.log(selectedValue, varientSelectedPrice);
}
}

Related

event listener on multiple buttons

I have 6 'like' buttons, clicking on which, counter increase. How can i use event handler on all 'like' buttons. In my example only the last one is working.
constructor(model) {
this.count = 0;
for(let i = 0; i < 6; i++){
this.renderInitialTodoForm();
}
this.likeButton.addEventListener('click', () => {
this.count++;
this.likeCount.innerHTML = this.count;
})
}
renderInitialTodoForm = () => {
this.app = this.getElement('#root');
this.likeButton = this.createElement('span', 'likeImg');
this.likeButton.textContent = '👍';
this.likeCount = this.createElement('span', 'like');
this.likeCount.textContent = 0;
this.app.append( this.likeButton, this.likeCount);
};
You render 6 like buttons but only keep a reference to one - this.likeButton. It is set to the last button created.
I think you should add the event listener to each button inside the loop.
You can do that by either adding the code bloc to renderInitialTodoForm or directly inside the for loop.
constructor(model) {
for(let i = 0; i < 6; i++){
this.renderInitialTodoForm();
}
}
renderInitialTodoForm = () => {
this.count = 0;
this.app = this.getElement('#root');
this.likeButton = this.createElement('span', 'likeImg');
this.likeButton.textContent = '👍';
this.likeButton.addEventListener('click', () => {
this.count++;
this.likeCount.innerHTML = this.count;
})
this.likeCount = this.createElement('span', 'like');
this.likeCount.textContent = 0;
this.app.append( this.likeButton, this.likeCount);
};
Does this work for you?

How to use for loop to sum a numbers inserted by the user?

i'm trying to create a simple project where the user is prompted to enter how many numbers he would like to add(sum). then when he click the button, a javascript will create a number of input tags equal to the number he inserted and then he will fill them with a number and click another button to calculate the result of the summation and here is the problem. below is a simplified snippet explain what is the problem:
function CL(){
const items = document.getElementById("items");
for (var i = 1; i < 3; i++) {
const inpt = document.createElement("input");
inpt.setAttribute("type","text");
inpt.setAttribute("style","margin:5px;");
inpt.setAttribute("id","y"+i);
inpt.setAttribute("value","");
const newline = document.createElement("br");
items.appendChild(inpt);
items.appendChild(newline);
}
}
function Add(){
const y = 0;
const sum = 0;
var is;
for (var i = 1; i < 3; i++) {
is = i.toString();
y = Number(document.getElementById('y'+ is).value);
sum = sum + y;
}
document.getElementById("demo").innerHTML = sum;
}
in the for loop how can i use getElementById with variables id like item1,item2,item3,...,itemN??
is there other way to achieve what i want?
You can take all items with ID "y" + consecutive number prefix on this way document.getElementById('y' + i).value;
Do not use "Add" for function name and Functions do not have to start with capital letters!
calckStart();
function calckStart() {
const items = document.getElementById("items");
for (var i = 1; i < 3; i++) {
const inpt = document.createElement("input");
inpt.setAttribute("type", "text");
inpt.setAttribute("style", "margin:5px;");
inpt.setAttribute("id", "y" + i);
inpt.setAttribute("value", "");
const newline = document.createElement("br");
items.appendChild(inpt);
items.appendChild(newline);
}
var button = document.createElement('button');
button.innerHTML = 'ClickMe'
items.appendChild(button);
button.addEventListener('click', calculateVal);
}
function calculateVal() {
var res = 0;
for (var i = 1; i < 3; i++) {
res = res + +document.getElementById('y' + i).value;
}
var items = document.getElementById("items");
var result = document.createElement('div');
result.innerHTML = res;
items.appendChild(result);
}
<div id="items"></div>
A better way is ...
When you create elements, you can assign them a CLASS attribute that is one for all input elements. You can then take the values from all elements with this class.
Example:
calckStart();
function calckStart() {
const items = document.getElementById("items");
for (var i = 1; i < 3; i++) {
const inpt = document.createElement("input");
inpt.setAttribute("type", "text");
inpt.setAttribute("style", "margin:5px;");
// inpt.setAttribute("id", "y" + i);
inpt.setAttribute("value", "");
inpt.setAttribute("class", "numbers"); //<-- Set class
const newline = document.createElement("br");
items.appendChild(inpt);
items.appendChild(newline);
}
var button = document.createElement('button');
button.innerHTML = 'ClickMe'
items.appendChild(button);
button.addEventListener('click', calculateVal);
}
function calculateVal() {
var list = document.getElementsByClassName('numbers'); //<-- Get by class
var res = 0;
for (var i = 0; i < list.length; i++) {
res = res + +list[i].value;
}
var items = document.getElementById("items");
var result = document.createElement('div');
result.innerHTML = res;
items.appendChild(result);
}
<div id="items"></div>
You can use ...args to collect arguments and use .reduce to add the arguments together.
const items = document.getElementById("items");
for (var i = 0; i < 3; i++) {
var inpt = document.createElement("input");
inpt.setAttribute("type","number"); //replaced with number
inpt.setAttribute("style","margin:5px;");
inpt.setAttribute("id","y"+i);
inpt.setAttribute("value","");
var newline = document.createElement("br");
items.appendChild(inpt);
items.appendChild(newline); //added newline appending
}
function sum(...args) {
return args.reduce((a, b) => a+b); //reduce arguments
}
<div id="items"></div><br /><button onclick="document.getElementById('answer').textContent = 'answer: ' + sum(+y0.value, +y1.value, +y2.value)">Add</button><div id="answer"></div>

Insert string to div on button click and clear it before next click

I try to create function which after click button, get string from user (from input) and spell it into div. It works, but only one time. When I change the string and click another one to button, page remember previous entered string.
I have tried to clear div and array before new iterating, but without success.
button.addEventListener('click', spell);
function spell(event) {
event.preventDefault();
let newArr = [];
for (let i=0; i<userText.length; i++) {
newArr.push(userText[i]);
}
programText.textContent = newArr;
}
How to clear an array to avoid this problem?
If you want to clear userText after you spell it, you can use userText.length = 0:
function spell(event) {
event.preventDefault();
let newArr = [];
for (let i=0; i<userText.length; i++) {
newArr.push(userText[i]);
}
userText.length = 0;
programText.textContent = newArr;
}
You don't even need to copy userText into newArr:
function spell(event) {
event.preventDefault();
programText.textContent = userText;
userText.length = 0;
}
Full code to this:
I have tried to clearing an array using: newArray = [] and newArray.length = 0. And clearing programText using programText.textContent = '' and programText.length = 0;
HTML
<article class=proj001Up>
<button class="button">Function 01</button>
<p>Spell the string</p>
</article>
<article class="proj001Down">
<input class="userText" type="text" name="userText" placeholder="Enter your string/word">
<article class="programText" placeholder="Result"></article>
JS
const button = document.querySelector('.button');
let userText = document.querySelector('.userText').value;
let programText = document.querySelector('.programText');
button.addEventListener('click', spell);
function spell(event) {
event.preventDefault();
let newArr = [];
for (let i=0; i<userText.length; i++) {
newArr.push(userText[i]);
}
programText.textContent = newArr;
}
Ok, I found the problem. I have to only delete value from let userText = document.querySelector('.userText'); and enter value to body of function. The correct version, below.
Thank you everybody for help :)
const button = document.querySelector('.button');
let userText = document.querySelector('.userText');
let programText = document.querySelector('.programText');
button.addEventListener('click', spell);
function spell(event) {
event.preventDefault();
let newArr = [];
for (let i=0; i<userText.value.length; i++) {
newArr.push(userText.value[i]);
}
programText.textContent = newArr;
}

Adding onClick function to select elements

I have a select tag of dynamically added elements. I need to add an event listener to each of the elements in the select tag except the first which:
adds the text of the element to a list,
makes the focus of the list the first element again, and
removes or hides the clicked element.
The first element is a 'none' element which doesn't need any event listener.
I've tried something like
for (var i = 0; i < array.length; i++)
{
var name = array[i];
var selectElement = document.getElementById(selectElementId);
addToSelectNode(document.getElementById(selectElementId), name);
var thisNode = selectElement.childNodes[i];
if (thisNode.value != "none")
{
thisNode.addEventListener("click", function(event)
{
appendNodeToList("artist-list", i);
selectElement.selectedIndex = 0;
selectElement.remove(selectElement.i);
selectElement.style.display = "none";
});
}
}
function addToSelectNode(element, optionText)
{
var newSelectElement = document.createElement("option");
newSelectElement.text = optionText;
element.add(newSelectElement);
}
function appendNodeToList(listId, text)
{
var newNode = document.createElement("LI");
var textNode = document.createTextNode(text);
newNode.appendChild(textNode);
document.getElementById(listId).appendChild(newNode);
}
Didn't work at all though
A few hours later I've solved my own question. The problem stemmed from trying to remove items in the select tag which just wasn't working - I'm nut sure if it's possible but making it disabled solved it. Anyway here's the result.
HTML:
<select id="artist-select-list">
<option value="none">none</option>
</select>
JavaScript:
window.onload = function()
{
var dropdown = document.getElementById("sampleDropdown");
var n = array.length;
// Loop to add to <select> dropdown
for (var i = 1; i <= n; i++)
{
addToSelectNode(dropdown, array[i - 1]);
}
// Loop to add id's to each element in the dropdown
for (var i = 0; i <= n; i++)
{
dropdown[i].id = "selectNum" + i;
}
// Loop to add event listener
for (var i = 0; i < dropdown.length; i++)
{
dropdown[i].addEventListener("click", function(event)
{
// Regardless of which option the user clicks move shown option to "none" (first index in dropdown)
dropdown.selectedIndex = 0;
if (event.target.id != "selectNum0")
{
// Disable once clicked
event.target.disabled = true;
// Do other things here in relation to event.target
}
});
}
}
var array =
[
"sampleText1", "sampleText2"
];
function addToSelectNode(element, optionText)
{
var newSelectElement = document.createElement("option");
newSelectElement.text = optionText;
element.add(newSelectElement);
}

Passing One's Self to OnClick Event JavaScript

The on click event that I add to an input in javascript isn't working in the proper manner.
My code so far looks like so:
function order(option) {
if(option.checked) {
document.getElementId("col_order").value = document.getElementById("col_order").value + " " + option.value;
}
}
...//somewhere further down
for(var i = 0; i < options.length; i++) {
var check = document.createElement("input");
var label = document.createElement("label");
var description = document.createTextNode(options[i]);
check.type = "checkbox";
check.name = "order_list[]";
check.value = options[i];
check.onclick = "order(check)"; //Problem here
label.appendChild(check);
label.appendChild(description);
element.appendChild(label);
}
I have also tried:
check.onclick = (function() { var option = check; return function() {order(option);}})();
The problem that I am having is the check.onlick line of code. When I add this with normal HTML:
<input type = "checkbox" name = "order_list[]" onclick = "order(this)" value = "randVal">randVal</input>
I don't have any problem whatsoever; the method executes with the intended results. Any thoughts?
Let me clarify: I make it to the order function just fine, but I never get into the if statement, even though the checkbox was just clicked
Use addEventListener instead, and even if it looks like it should work, you're overwriting the same variables on each iteration as there is no closure in for loops, so I would probably add a closure to avoid issues.
For a checkbox you would listen for the change event, not click
for(var j = 0; j < options.length; j++) {
(function(i) {
var check = document.createElement("input");
var label = document.createElement("label");
var description = document.createTextNode(options[i]);
check.type = "checkbox";
check.name = "order_list[]";
check.value = options[i];
check.addEventListener('change', function() {
if (this.checked) {
var col_order = document.getElementById("col_order");
col_order.value = col_order.value + " " + this.value;
}
}, false);
label.appendChild(check);
label.appendChild(description);
element.appendChild(label);
})(j);
}
FIDDLE
check.onclick = "order(check)"; assigns a String as an on-click handler. That doesn't work; the browser expects a function there:
check.onclick = function() {
order(check);
}

Categories

Resources