Multiple onclick button events Vanilla Javascript - javascript

I would like to change an inputs value whenever one of my many "li" tags are clicked (without using jQuery). I listed two of the list tags in my HTML below and I want to differentiate between them in my if statement. What would I put inside the if parameters to display buttons[0] being clicked or buttons[1]?
function myFunction() {
var input = document.getElementById('values');
var buttons = document.getElementsByTagName('li');
if(buttons[0]) {
input.value = 0;
}
else if(buttons[1]) {
input.value += 1;
}
};
HTML :
<div class="box">
<input id="values" type="text" placeholder="2017">
<ul>
<li onclick="myFunction()" id="1">C</li>
<li onclick="myFunction()" id="2">1</li>
</ul>
</div>

Two mistakes.
First, It is because of your if statement checks whether button[0] and button[1] are undefined.
Since button[0] is defined, it never goes to your second condition. So, your statement is just the same as:
function myFunction() {
var input = document.getElementById('values');
var buttons = document.getElementsByTagName('li');
if(buttons[0]) {
input.value = 0;
}
// the second if else is redundant because buttons[0] is not undefined
};
Second, input value is in string, so to increment, you need to parse it to integer. So for the fix:
function myFunction(e) {
var input = document.getElementById('values');
var buttons = document.getElementsByTagName('li');
if(buttons[0].id === e.target.id) {
input.value = 0;
}
else if(buttons[1].id === e.target.id) {
input.value = parseInt(input.value) + 1;
}
};
And your html needs to change a bit, because the function needs to capture the click event:
<div class="box">
<input id="values" type="text" placeholder="2017">
<ul>
<li onclick="myFunction(event)" id="1">C</li>
<li onclick="myFunction(event)" id="2">1</li>
</ul>
</div>

Given html at Question, if <li> elements have an id, you can pass this to myFunction, use id of li element
<li onclick="myFunction(this)" id="1">C</li>
<li onclick="myFunction(this)" id="2">1</li>
if(this.id === "1") {
input.value = 0;
}
else if(this.id === "2") {
input.value += 1;
}

I am somewhat confused as to what you want, but I think this should come pretty close? Let me know and I'm happy to help further.
EDIT: Just noticed you were calling this function from the element itself. Ignore this unless you want to abstract it, which I would usually suggest.
function myFunction() {
var input = document.getElementById('values');
var buttons = document.getElementsByTagName('li');
for (let i = 0; i < buttons.length; i++) {
buttons[i].addEventListener('click', function() {
if (i === 0) {
input.value = 0;
}
else if(i === 1) {
input.value += 1;
}
})
}
}

Instead of binding events to each <li>, use event delegation. Details are commented in Snippet.
SNIPPET
// Reference the <ul>
var list = document.querySelector('ul');
// When list is clicked call function delegator()
list.addEventListener('click', delegator, false);
/* This function uses a pattern called event...
||...delegation. Basically we register the event...
||...on the parent of multiple clickable elements...
||...In this case it would be <ul> and the children...
||...<li> would be the last in an event chain...
||...which would make that particular <li>...
||...the event.target (the one that's clicked)...
||...Any other elements above event.target are...
||...event.currentTarget. By knowing this, we can...
||...determine event.target by determining what is...
||...event.currentTarget.
*/
function delegator(event) {
// If it ain't event.currentTarget...
if (event.target !== event.currentTarget) {
/*...then it's gotta be event.target...
||...so let's store it's id in a var
*/
var tgt = event.target.id;
// Reference the id to as an DOM object
var target = document.getElementById(tgt);
// Get and store target's text
var value = target.textContent;
// Get and set textbox's value to the text of target
document.getElementById('values').value = value;
}
return false;
}
<div class="box">
<input id="values" type="text" placeholder="2017">
<ul>
<li id="i1">C</li>
<li id="i2">1</li>
</ul>
</div>

Related

Get "count" variable rather than "Object Mouse Event"

I have a toggle switch and a button on a page. I also have a variable called "count". My goal is for "count" to record the number of times the button is pressed but ONLY when the toggle switch is ON.
Here's my code
var count = 0;
btnReset.addEventListener("click",
function(count) {
if (toggle.checked == true) {
count += 1;
document.getElementById('count').innerHTML=count;
}
});
Problem is, it's returning "[object MouseEvent]1" rather than the value of "count".
How do I get it to return var count (i.e. # of clicks when toggle is on)?
Thanks in advance.
Your issue is that an event listener receives the Event object. For some reason, you put count there and hoped it would be that?
Here is the right way to do it:
let count = 0;
const toggle = document.querySelector('#chkToggle');
const btn = document.querySelector('#btnCount');
const output = document.querySelector('.count');
btn.addEventListener("click", function(evt) {
if (toggle.checked == true) {
count++;
output.innerHTML = count;
}
});
Enabled: <input type="checkbox" id="chkToggle"><br>
<button type="button" id="btnCount">Count</button>
<div class="count">0</div>

JavaScript EventListener not passing event variable to event handler

I'm trying to use the event variable to edit the CSS of the element. The error that im getting is saying that event is undefined even tho it should be passed by the event listener.
Thanks for any help
function newClick(event){
event.style.backgroundColor = '#ABAEAB';
document.addEventListener("keyup" , function(e){
let sel = window.getSelection();
let ele = sel.anchorNode;
ele.textContent = e.key;
if(ele.textContent.trim()){
ele.focus
setCursorToEnd(ele);
}
ele.parentElement.style.backgroundColor = '#FFFFFF';
ele.parentElement.setAttribute("class" , "old");
});
}
function SetNewBranch(){
let li_NewSpan = document.getElementsByClassName("new");
for(let i = 0; i < li_NewSpan.length; i++){
if(li_NewSpan[i].getAttribute("EventListener") == 'false' && li_NewSpan[i].getAttribute("class") == "new"){
li_NewSpan[i].addEventListener("click" , newClick , false);
}
}
}
You are adding keyup event inside a click handler which will add new listener function everytime a click happens which is not right!
Take keyup event handler to its own function and call it once inside SetNewBranch or whereever you need. see example below.
Also, to get the element, you can use event.target
function attachKeyUpEvent() {
document.addEventListener("keyup" , function(e){
let sel = window.getSelection();
let ele = sel.anchorNode;
ele.textContent = e.key;
if(ele.textContent.trim()){
ele.focus
// setCursorToEnd(ele);
}
ele.parentElement.style.backgroundColor = '#FFFFFF';
ele.parentElement.setAttribute("class" , "old");
});
}
function newClick(event){
event.target.style.backgroundColor = '#ABAEAB';
}
function SetNewBranch(){
let li_NewSpan = document.getElementsByClassName("new");
for(let i = 0; i < li_NewSpan.length; i++){
if(!li_NewSpan[i].getAttribute("EventListener") && li_NewSpan[i].getAttribute("class") == "new"){
li_NewSpan[i].addEventListener("click" , newClick , false);
}
}
attachKeyUpEvent();
}
SetNewBranch();
<ul>
<li class="new"> one </li>
<li class="new"> two </li>
<li class="new"> three </li>
</ul>

bind javascript function to input control on window load

I amm develloping an web form with multiple text box with same css class.
and i want to bind a specific method to all these textboxes who use that class.
belows are my codes
window.onload = function ()
{
var tObj = document.getElementsByClassName('exa');
for (var i = 0; i < tObj.length; i++) {
tObj[i].onblur(convertAmount(event,this));
}
}
the another function 'convertAmount()' is below
function convertAmount(evt, obj) {
if (obj.value != "") {
var num = parseFloat(obj.value);
num = Math.round((num + 0.00001) * 100) / 100;
obj.value = num.toFixed(2);
}
else {
obj.value = "0.00";
}
}
html codes
<div>
<input type="text" id="finalvalue" class="exa"/>
<input type="text" id="grossvalue" class="exa"/>
<div>
when browser load first time only '0.00' values are coming on those text boxes. but when i type some values on those text boxes and press tab its not working! please help what is wrong here
As commented before, you should assign a eventHandler and not pass it as callback.
So you code would be:
tObj[i].onblur = convertAmount.bind(this, event, this);
Also, event is default argument for any eventListener and current object/element is automatically binded to it, so above code can be simplified to
tObj[i].onblur = convertAmount;
This will bind the context and you will get all properties in this.
Sample Fiddle
Note: you should use addEventListener instead. onBlur = will replace all previous events. addEventListener will add another one.
Sample Fiddle
I hope this link helpful to you.
<div>
<input type="text" id="finalvalue" class="exa"/>
<input type="text" id="grossvalue" class="exa"/>
<div>
$(document).ready(function(){
$('.exa').each(function(index,value){
$(this).attr('onblur',convertAmount(event,$(this)))
})
})
function convertAmount(evt, obj) {
if (obj != "") {
$(obj).val('0.00')
}
else {
$(obj).val('0.00')
}
}

Checkboxes in JavaScript

I've got a problem. I must create a form with five check-boxes.
The user must select exactly three of the five check-boxes.
At the time of change check-box updates the marker at check-box
When the user presses a fourth element should light up at the red light.
3. When you deselect any item marker when it disappears (is white) and the rest are green.
Here is what I'm done: http://jsfiddle.net/epredator/98TfU/
and some of my code, because I can't post a JSfiddle link without some code in text ;):
function checkGreen() {
if (this.checked && counter >= 3) {
console.log("if test in checkGreen()");
}
}
I've got a problem with point 3, because i don't know how to change red light to green after uncheck one of check-boxes with green light. I spend a lot of time on it. As you can see I am not the master of Javascript and ask you for help, pleas help me :) ... and for the end i must use pure JavaScript (no jQuery). Thanks a lot for help ...
Here is how I would do it. It is cleaner than how you were doing it before. FIDDLE. Keep an array of the checked boxes, and use it to determine which ones should be what color.
(function() {
var checked = [];
document.getElementById("Checkbox1").addEventListener("click",toggle);
document.getElementById("Checkbox2").addEventListener("click",toggle);
document.getElementById("Checkbox3").addEventListener("click",toggle);
document.getElementById("Checkbox4").addEventListener("click",toggle);
document.getElementById("Checkbox5").addEventListener("click",toggle);
function toggle() {
if (this.checked) {
checked.push(this);
} else {
var index = checked.indexOf(this);
var box = checked.splice(index,1)[0];
box.nextElementSibling.className = "white";
}
refresh();
}
function refresh() {
for (var i = 0; i < checked.length; i++) {
if (i < 3) {
checked[i].nextElementSibling.className = "green";
} else {
checked[i].nextElementSibling.className = "red";
}
}
}
}());
For Javascript, you can use below code
<script type="text/javascript">
// method to bind handler
function bindEvent(element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} else {
element.attachEvent('on' + type, handler);
}
}
// binding click event to all the checkboxes with name 'choice'
// you can generalize this method
window.onload = function () {
var elements = document.getElementsByName('choice');
if (!elements)
return;
for (var i = 0; i < elements.length; i++) {
var ele = elements[i];
bindEvent(ele, 'click', function () {
changeColor();
});
}
}
// Pass the checkbox name to the function
// taken from stack overflow answer
//http://stackoverflow.com/questions/8563240/how-to-get-all-checked-checkboxes
function getCheckedBoxes(chkboxName) {
var checkboxes = document.getElementsByName(chkboxName);
var checkboxesChecked = [];
// loop over them all
for (var i = 0; i < checkboxes.length; i++) {
// And stick the checked ones onto an array...
if (checkboxes[i].checked) {
checkboxesChecked.push(checkboxes[i]);
}
}
// Return the array if it is non-empty, or null
return checkboxesChecked.length > 0 ? checkboxesChecked : null;
}
// with your other function, you can call this function or club the functionality
function changeColor() {
var elements = document.getElementsByName('choice');
if (!elements)
return;
var selectedCheckBoxes = getCheckedBoxes('choice');
if (selectedCheckBoxes && selectedCheckBoxes.length == 3) {
// set color to green
}
}
</script>
and HTML used as: (note only 'name' property from input element)
<span>
<input type="checkbox" name="choice" id="Checkbox1" />1</span>
<span>
<input type="checkbox" name="choice" id="Checkbox2" />2</span>
<span>
<input type="checkbox" name="choice" id="Checkbox3" />3</span>
<span>
<input type="checkbox" name="choice" id="Checkbox4" />4</span>
<span>
<input type="checkbox" name="choice" id="Checkbox5" />5</span>
You can get all the checked elements and if the count is 3, mark every body with interested color.

Get clicked class index javascript

I have 3 divs with class: wpEdit and onClick: alertName()
<div class="wpEdit" onClick="alertName()">Bruce Lee</div>
<div class="wpEdit" onClick="alertName()">Jackie Chan</div>
<div class="wpEdit" onClick="alertName()">Jet li</div>
When clicked i want to know the Index of class wpEdit of the clicked Div:
function alertName(){
//Something like this
var classIndex = this.className.index; // This obviously dosnt work
alert(classIndex);
}
when clicked on Bruce Lee it should alert : 0
when clicked on Jackie Chan it should alert : 1
when clicked on Jet Li it should alert : 2
I need to know which instance of class="wpEdit" is clicked on
Try this
function clickedClassHandler(name,callback) {
// apply click handler to all elements with matching className
var allElements = document.body.getElementsByTagName("*");
for(var x = 0, len = allElements.length; x < len; x++) {
if(allElements[x].className == name) {
allElements[x].onclick = handleClick;
}
}
function handleClick() {
var elmParent = this.parentNode;
var parentChilds = elmParent.childNodes;
var index = 0;
for(var x = 0; x < parentChilds.length; x++) {
if(parentChilds[x] == this) {
break;
}
if(parentChilds[x].className == name) {
index++;
}
}
callback.call(this,index);
}
}
Usage:
clickedClassHandler("wpEdit",function(index){
// do something with the index
alert(index);
// 'this' refers to the element
// so you could do something with the element itself
this.style.backgroundColor = 'orange';
});
The first thing you might want to address in your code is the inline HTML binding.
You could use document.addEventListener on each element, or rely on event delegation.
The widely most used implementation of event delegation comes with jQuery. If you're already using jQuery, this is the way to go!
Alternatively I've also my own little delegate utility.
const delegate = (fn, selector) => {
return function handler(event) {
const matchingEl = matches(event.target, selector, this);
if(matchingEl != null){
fn.call(matchingEl, event);
}
};
};
const matches = (target, selector, boundElement) => {
if (target === boundElement){
return null;
}
if (target.matches(selector)){
return target;
}
if (target.parentNode){
return matches(target.parentNode, selector, boundElement);
}
return null;
};
This is how you would register the event listener.
document.getElementById('#parent')
.addEventListener('click', delegate(handler, '.wpEdit'));
And this is how you could get the index of the element that generated the event.
const handler = (event) => {
console.log(Array.prototype.indexOf.call(event.currentTarget.children, event.target));
}
Live demo:
const delegate = (fn, selector) => {
return function handler(event) {
const matchingEl = matches(event.target, selector, this);
if (matchingEl != null) {
fn.call(matchingEl, event);
}
};
};
const matches = (target, selector, boundElement) => {
if (target === boundElement) {
return null;
}
if (target.matches(selector)) {
return target;
}
if (target.parentNode) {
return matches(target.parentNode, selector, boundElement);
}
return null;
};
const handler = (event) => {
console.log(Array.prototype.indexOf.call(event.currentTarget.children, event.target));
}
document.getElementById('parent')
.addEventListener('click', delegate(handler, '.wpEdit'));
<div id="parent">
<div class="wpEdit">Bruce Lee</div>
<div class="wpEdit">Jackie Chan</div>
<div class="wpEdit">Jet li</div>
</div>
If you want the index of the div's based on your class wpEdit you can do like this:
HTML:
<div class="wpEdit">Bruce Lee</div>
<div class="wpEdit">Jackie Chan</div>
<div class="other">Other</div>
<div class="wpEdit">Jet li</div>
JS:
$(".wpEdit").bind("click", function(){
var divs = $(".wpEdit");
var curIdx = divs.index($(this));
alert(curIdx);
});
Live example : http://jsfiddle.net/pJwzc/
More information on the index function of jQuery : http://api.jquery.com/index/
Using vanilla javascript, this one works for me:
var wpEdits = document.querySelectorAll(".wpEdit");
for (let i = 0; i < wpEdits.length; i++)
wpEdits[i].addEventListener("click", showID);
function showID(evt) {
for (let i = 0; i < wpEdits.length; i++)
if(wpEdits[i] == evt.target)
alert(i);
}
May not be the best solution though as I am still new to js.
Since I am very new to JS, take the following explanation with a grain of salt:
(Line-1)
This is similar to var wpEdits = document.getElementsByClassName("wpEdit");. It will assign all instances of class="wpEdit" from the html file to the wpEdits variable.
(Line-3 and Line-4)
This two lines will cause any click on the class="wpEdit" to call function showID() defined below.
(Line-6 and Line-10)
When a click event happens, the browser will pass the unique properties of the item being clicked to the evt variable. This then is used in the for loop to compare against all available instances incrementally. The evt.target is used to get to the actual target. Once a match is found, it will alert the user.
To avoid wasting CPU time, running a break; is recommended to exit the loop soon after the match is found.
I could not understand, why people add new functions in previous answers, so...
const wpEdit = document.getElementsByClassName('wpEdit');
for(let i = 0; i < wpEdit.length; i++){
wpEdit[i].addEventListener('click',function(){
alert(i);
});
}
I just added 'click' event, using the loop. And [i] already is the current clicked class index...
FIDDLE

Categories