Javascript - onclick event is not working - javascript

So I have this piece of code:
window.onload = function () {make_buttons ('calc'); }
function make_buttons (id) {
console.log (id);
var input = document.createElement("INPUT");
document.getElementById(id).appendChild(input);
for (var i = 0;i < 10; i++){
var btn = document.createElement ("BUTTON");
var t = document.createTextNode (i);
btn.appendChild(t);
document.getElementById(id).appendChild(btn).onclick=document.getElementsByTagName("INPUT").value=i;
}
};
Now when I have created the button with the for loop, it should also have the onclick event attached to it which writes the current value of i into my input form.
Code I have written produces no errors but when the button is clicked, it simply does not do anything. Why is that?
New version:
window.onload = function () {make_buttons ('calc'); }
function make_buttons (id) {
var input = document.createElement("input");
input.type = 'text';
input.id = 'inp';
document.getElementById(id).appendChild(input);
for (var i = 0;i < 10; i++){
var btn = document.createElement ("button");
btn.id = i;
var txt = document.createTextNode (i);
btn.appendChild(txt);
var make_btn = document.getElementById(id).appendChild(btn);
make_btn.onclick = button_pressed (i);
}
};
function button_pressed (id) {
document.getElementById("inp").value += id;
};

Method document.getElementsByTagName() returns a NodeList collection that you should iterate through.
You need to go in loop through retrieved elements and assign the value attribute to each of them.
So that you can change
document.getElementById(id).appendChild(btn).onclick=document.getElementsByTagName("INPUT").value=i;
to something like this:
var id = 'my-form',
btn = document.createElement('input');
btn.type = 'button';
btn.value = 'Click me!';
btn.onclick = function() {
var inputs = document.getElementsByTagName('input');
// NodeList to Array if needed:
// var inputsArray = Array.prototype.slice.call(inputs);
for(var i = 0, l = inputs.length; i < l; i++) {
inputs[i].value = i;
}
return false;
};
document.getElementById(id).appendChild(btn);
DEMO #1
Update:
About your second question, yes it won't work in this way since at the time when your onclick event handler is called it's using the last value assigned to i variable. To avoid this you can just use closures.
For example,
HTML:
<form action="" id="my-form">
<input type="text" id="inp" />
</form>
JavaScript:
var btn,
input,
form,
createHandler;
input = document.getElementById('inp');
form = document.getElementById('my-form');
createHandler = function(i) {
return function() {
input.value += i;
};
};
for(var i = 0; i < 5; i++) {
btn = document.createElement('input');
btn.type = 'button';
btn.value = 'Append ' + i;
form.appendChild(btn);
btn.onclick = createHandler(i);
}
DEMO #2
Also you can use just immediately invoked anonymous function to create that closure in the body of your loop:
for(var i = 0; i < 5; i++) {
// ...
btn.onclick = (function(theNumberToAppend) {
return function() {
input.value += theNumberToAppend;
};
})(i);
}
DEMO #3

Related

document.getElementById class applies to the whole array instead of each element

<p><span id="sr" class="btn">elements of the array</span></p>
for(var i = 0; i < myarray.length; i++)
{
var sr = (function(val) {
btn = document.createElement('button');
btn.data = val;
btn.innerHTML = val;
btn.addEventListener('click', checkAnswer);
document.body.appendChild(btn);
return btn.data = val;
})//(myarray[i]);
document.getElementById("sr").innerHTML = myarray;
}
With this code the elements of the array appear in the html span. I want each element to appear as a button, as defined in the class "btn". However, the class changes the style of the array as a whole, not as single buttons. What is the correct way to define the style of each button?
I tried document.getElementById("sr").innerHTML = myarray.class="btn";. It does not work. Definitely not the correct syntax. Any idea?
Is this what you want to achieve?
let container = document.getElementById('sr');
let array = ['element1', 'element2', 'element3'];
function checkAnswer () {
console.log('Selected answer: ', this.textContent);
}
for (let i = 0; i < array.length; i++) {
let button = document.createElement('button');
button.textContent = array[i];
button.addEventListener('click', checkAnswer);
container.appendChild(button);
}
<p><span id="sr" class="btn"></span></p>
If I understand you correctly, you want to add btn class to your dynamically created buttons with myarray elements.
What is the correct way to define the style of each button?
I tried document.getElementById("sr").innerHTML = myarray.class="btn";
You can use element.classList.add('your-class');
var myarray = ["Array", "elements"]; //let's say
for (var i = 0; i < myarray.length; i++) {
var sr = (function(val) {
btn = document.createElement('button');
btn.data = val;
btn.innerHTML = val;
btn.classList.add("btn")
btn.addEventListener('click', checkAnswer);
document.body.appendChild(btn);
return btn.data = val;
})(myarray[i]);
//document.getElementById("sr").innerHTML = myarray;//I don't know why this line here?
}
function checkAnswer(e){
}
Use Element.dataset instead of creating a .data property. Pass i to IIFE. If you are trying to display the array myarray as .innerHTML of #sr, concatenate "[" to beginning and "]" to end of myarray setting at .innerHTML, as .innerHTML casts Array to String.
If you are trying to append created element to #sr, do not append element to document.body, but #sr.
function checkAnswer() {
console.log(this.dataset.value)
}
var myarray = [1, 2, 3];
for (var i = 0; i < myarray.length; i++) {
(function(val) {
var btn = document.createElement('button');
btn.dataset.value = val;
btn.className = "btn"; // set `btn` `.className` to `"btn"`
btn.innerHTML = val;
btn.addEventListener('click', checkAnswer);
document.body.appendChild(btn);
// document.getElementById("sr").appendChild(btn);
})(i);
}
document.getElementById("sr").innerHTML = "[" + myarray + "]";
<p><span id="sr" class="btn">elements of the array</span></p>

Pass contextual variable to onclick event handler as argument

*This is happening inside a larger block of code, in a for loop. See end of post for entire loop.
I've read all of the posts that seem to be about this subject, but I'm still lost.
I'm trying to assign an onclick event to a checkbox. The function being assigned to the onclick event needs to have access to a variable that is available in the scope where the checkbox is defined (idvariable).
var idvariable = parentChildList[i].children[j]["subjectid"];
var input = document.createElement("input");
input.type = "checkbox";
input.value = "";
input.onclick = function () {
return clicked(idvariable);
};
function clicked(id) {
alert(id);
};
I've tried every variation of inline and named functions, but I can't figure out how to give the clicked function access to idvariable. In this example above, the value of that variable is undefined.
Or, if I try it with this way:
var input = document.createElement("input");
input.type = "checkbox";
input.value = "";
var idvariable = parentChildList[i].children[j]["subjectid"];
input.onclick = function (idvariable) {
return clicked(idvariable);
};
function clicked(id) {
alert(id);
};
I get an alert that says [object MouseEvent]. Same with the following where I removed the () from the method name I'm assigning to the onclick event:
var idvariable = parentChildList[i].children[j]["subjectid"];
input.onclick = function () {
return clicked;
}(idvariable);
function clicked(id) {
return alert(id);
};
*entire loop:
for (var i = 0; i < parentChildList.length; i++) {
var row = table1.insertRow(-1);
var cell = row.insertCell(0);
cell.innerHTML =
"<h4 class=\"panel-title\"><a data-toggle=\"collapse\" data-parent=\"#accordion\" href=\"#collapse" + i + "\">" + parentChildList[i]["title"] + "</a></h4>";
if (parentChildList[i].children.length > 0) {
var row2 = table1.insertRow(-1);
var cell2 = row2.insertCell(0);
var table2 = document.createElement("table");
table2.className = "collapse";
table2.id = "collapse" + i;
cell2.appendChild(table2);
for (var j = 0; j < parentChildList[i].children.length; j++) {
var row3 = table2.insertRow(-1);
var cell3 = row3.insertCell(0);
var div = document.createElement("div");
div.className = "checkbox";
var label = document.createElement("label");
label.innerText = parentChildList[i].children[j]["title"];
var input = document.createElement("input");
input.type = "checkbox";
input.value = "";
input.setAttribute('subj', idvariable);
var idvariable = parentChildList[i].children[j]["subjectid"];
alert(idvariable);
input.onclick = function () {
return clicked(this.getAttribute('subj'));
};
function clicked(id) {
return alert(id);
};
cell3.style.padding = "0px 0px 0px 10px";
cell3.style.fontsize = "x-small";
cell3.appendChild(div);
div.appendChild(label);
label.insertBefore(input, label.childNodes[0]);
}
}
}
onclick handler receives Event object. If a handler attached as elem.onclick=handler then the element is available inside the handler as this. So this is workaround.
var idvariable = parentChildList[i].children[j]["subjectid"];
var input = document.createElement("input");
input.type = "checkbox";
input.value = "";
input.setAttribute('data-subj', idvariable);
input.onclick = function () {
return clicked(this.getAttribute('data-subj'));
};
function clicked(id) {
alert(id);
};
You will have to append the checkbox to some existing element first, using the following code.
var element = document.getElementById("one").appendChild(input);
Then you can get the parent by using something like the following...
var x = document.getElementById("someId").parentElement;
where x will contain the parent element.
This link https://stackoverflow.com/a/9418326/886393 is about custom data in an event (custom event). Hope that helps.
Thanks
Paras

Javascript: How to implement the "enter/return key" to save a value?

Sorry, I am not really good with JS.
The code is essentially the user double clicks on the text, textbox appears, changes text, and saves a new value. However, I want the user to be able to also click enter to save the new value.
In addition, if possible, to have a dedicated "Save" button to save the new value and "discard" to keep the old value.
Also, if I double click many times, the text appears as "(input type="text")". Is there a way to remove that?
Please help if you can.
The HTML + JS code
<html>
<head>
<script type="text/javascript">
window.onload = function() {
var elements = getElementsByClassName('text-edit', '*', document);
for(var i = 0; i < elements.length; i++) {
elements[i].ondblclick = function() {
this.setAttribute('oldText', this.innerHTML); // not actually required. I use this just in case you want to cancel and set the original text back.
var textBox = document.createElement('INPUT');
textBox.setAttribute('type', 'text');
textBox.value = this.innerHTML;
textBox.onblur = function() {
var newValue = this.value;
this.parentNode.innerHTML = newValue;
}
this.innerHTML = '';
this.appendChild(textBox);
}
}(i);
}
function getElementsByClassName(className, tag, elm) {
var testClass = new RegExp("(^|\\s)" + className + "(\\s|$)");
var tag = tag || "*";
var elm = elm || document;
var elements = (tag == "*" && elm.all) ? elm.all : elm.getElementsByTagName(tag);
var returnElements = [];
var current;
var length = elements.length;
for(var i = 0; i < length; i++) {
current = elements[i];
if(testClass.test(current.className)) {
returnElements.push(current);
}
}
return returnElements;
}
</script>
</head>
<div><span class="text-edit">Some text</span></div>
</html>
The snippet below allows you to modify the value of a textbox using save button or enter key and discarding any changes using cancel button.
<!-- HTML -->
<h1 id="editable">Lorem Ipsum</h1>
// JavaScript
window.onload = function(){
var h1 = document.getElementById('editable');
h1.onclick = function(){
var old = this;
var input = document.createElement("INPUT");
input.type = "text";
input.value = this.innerHTML;
input.onkeyup = function(e){
var code = (e.keyCode ? e.keyCode : e.which);
if(code == 13) {
old.innerHTML = input.value;
input.parentNode.replaceChild(old, input);
save.parentNode.removeChild(save);
cancel.parentNode.removeChild(cancel);
}
};
this.parentNode.replaceChild(input, this);
var save = document.createElement("INPUT");
save.type = "button";
save.value = "Save";
(function(old, input){
save.onclick = function(){
old.innerHTML = input.value;
input.parentNode.replaceChild(old, input);
this.parentNode.removeChild(this);
cancel.parentNode.removeChild(cancel);
};
})(old, input);
input.parentNode.insertBefore(save, input.nextSibling);
var cancel = document.createElement("INPUT");
cancel.type = "button";
cancel.value = "Cancel";
(function(old, input){
cancel.onclick = function(){
input.parentNode.replaceChild(old, input);
this.parentNode.removeChild(this);
save.parentNode.removeChild(save);
};
})(old, input);
input.parentNode.insertBefore(cancel, input.nextSibling);
};
};
Working jsBin

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);
}

createElement (input) with Id ;with counter ,Id1,Id2,Id3

i trie to generate dynamic Input fields with unique Ids but i stucked:
function addTxtBx(){
var txtBxHolder = document.getElementById('txtBoxHolder');
var newTxtBx = document.createElement('input');
newTxtBx.type = 'text';
var i=1;
//newTxtBx.id = document.getElementById("txtWaypoint"[i])
if(i<10){
newTxtBx.id = "txtWaypoint"+[i];
i++;
break;
}
txtBoxHolder.appendChild(newTxtBx);
}
i tried it with a for() but always got Id='name'9,
i know im an trainee. :)
I think so where you miss to loop it properly.
function addTextBox(ops) {
var no = document.getElementById('id1').value;
for (var i = 0; i < Number(no); i++) {
var text = document.createElement('input');
text.type = "text";
text.id = "txtWaypoint" + i; //id created dynamically
document.getElementById('divsection').appendChild(text);
}
}
Try it

Categories

Resources