buttons added to table won't fire handler - javascript

In my table, I'm trying to include an Edit button at the end of each row. The idea is for the user to click one of these to alter the row's content. I can build and populate the table just fine, but I cannot get the buttons to fire off their handler.
Here's a code snippet:
window.onload = function (){
// a bunch of stuff happens correctly...
while (!Rs.EOF)
{
var oRow = oTicketsTable.insertRow();
for (j=0; j < field.length; j++)
{
var oCell = oRow.insertCell();
oCell.style.fontSize = "10";
oCell.style.fontWeight = "normal";
oCell.style.border = "thin black solid";
oCell.innerText = Rs(field[j]);
}
var oCell = oRow.insertCell();
oCell.style.border = "thin black solid";
var oBtn = document.createElement("button");
oCell.appendChild(oBtn);
oBtn.innerHTML = Rs('idnum');
oBtn.onClick = function () { alert("oBtn.onClick"); }
Rs.MoveNext();
}
Rs.Close ();
delete Rs;
var btn = document.createElement("button");
btn.style.height = "50px";
btn.style.width = "150px";
document.body.appendChild(btn);
btn.innerHTML="button1";
btn.onclick = function() { alert("button1 calling");
}
The code at the end creates a test button which fires off just fine. But none of the buttons in the table work.

The onclick function in the table is camel case: try changing it to lower case? Change obtn.onClick to obtn.onclick.
oBtn.onclick = function () { alert("oBtn.onClick"); }

Try:
oBtn.onclick = function () { alert("oBtn.onClick"); }
Rs.MoveNext();
}
Instead of:
oBtn.onClick = function () { alert("oBtn.onClick"); }
Rs.MoveNext();
}
capitalized 'C', should be just 'c'

If I not mistaken, you should place your event outside, as global.
var oBtn,btn;
window.onload = function (){
// other code
// other code
oBtn = document.createElement("button");
oBtn.innerHTML = Rs('idnum');
btn = document.createElement("button");
btn.style.height = "50px";
btn.style.width = "150px";
document.body.appendChild(btn);
btn.innerHTML="button1";
}
// make your event global
oBtn.onClick = function () { alert("oBtn.onClick"); }
btn.onclick = function() { alert("button1 calling"); }
.onClick is an old practice. But I think it would just prompt you a warning, not an error.

Related

How to create buttons in a for loop without losing their references?

I am trying to create buttons for each letter in alphabet. When the button is pressed, it will alert the letter written on the button. But i think since i create them i a for loop, js can't keep their reference because when i open the browser, on the each button 'undefined' is written. I also tried to add the buttons to an array then append them to the container, but the result was same. Is there any way to fix this problem? Thanks.
function CreateButtons()
{
var letters = "ABCDEFGHJKLMNOPRSTUVYZQWXI";
var frame = document.getElementById('buttons'); //container.
for (var i = 0; i < letters.length;i++)
{
document.addEventListener('DOMContentLoaded', function() {
var button = document.createElement('button');
button.type = 'button';
button.innerHTML = letters[i];
button.className = 'btn-styled';
button.style.padding = "20px";
button.style.marginTop = "10px";
button.style.lineHeight = "30px";
button.style.fontWeight = "bold";
button.style.padding = "0 30px";
button.style.background = "salmon";
button.style.border = "none";
button.style.color ="blue";
button.onclick = function() {
alert(letters[i]); //when the button is pressed, it will alert the letter at i. position.
};
frame.appendChild(button);
}, false);
}
}
You need to create a closure. Because loop will finish its execution and the button created will never know the value of letter[i]
function CreateButtons() {
var letters = "ABCDEFGHJKLMNOPRSTUVYZQWXI";
var frame = document.getElementById('buttons'); //container.
for (var i = 0; i < letters.length; i++) {
(function(z) {
document.addEventListener('DOMContentLoaded', function() {
var button = document.createElement('button');
button.type = 'button';
button.innerHTML = z;
button.className = 'btn-styled';
button.style.padding = "20px";
button.style.marginTop = "10px";
button.style.lineHeight = "30px";
button.style.fontWeight = "bold";
button.style.padding = "0 30px";
button.style.background = "salmon";
button.style.border = "none";
button.style.color = "blue";
button.onclick = function() {
alert(z); //when the button is pressed, it will alert the letter at i. position.
};
frame.appendChild(button);
}, false);
}(letters[i]))
}
}
CreateButtons()
<div id='buttons'></div>
Alternatively instead of var use let
function CreateButtons() {
var letters = "ABCDEFGHJKLMNOPRSTUVYZQWXI";
var frame = document.getElementById('buttons'); //container.
for (let i = 0; i < letters.length; i++) {
document.addEventListener('DOMContentLoaded', function() {
var button = document.createElement('button');
button.type = 'button';
button.innerHTML = letters[i];
button.className = 'btn-styled';
button.style.padding = "20px";
button.style.marginTop = "10px";
button.style.lineHeight = "30px";
button.style.fontWeight = "bold";
button.style.padding = "0 30px";
button.style.background = "salmon";
button.style.border = "none";
button.style.color = "blue";
button.onclick = function() {
alert(letters[i]); //when the button is pressed, it will alert the letter at i. position.
};
frame.appendChild(button);
}, false);
}
}
CreateButtons()
<div id='buttons'></div>

why my input element which is a div child is unclickable while when i replace this input by a button, the button is clickable

I want to create a div element which contains a button and an input element.
but when the input is in the div the input becomes unclickable
var video_button = document.createElement("BUTTON");
var user_area = document.createElement("DIV");
var inp = document.createElement("INPUT");
function upload_video(e){
console.log("upload_video function");
var v = document.createElement("VIDEO");
inp.onchange = function(e){
v.src = window.URL.createObjectURL(inp.files[0]);
v.style.heigth = "1000px";
v.style.width = "1000px";
user_area.appendChild(v);
}
}
function input(e){
console.log("input function");
inp.setAttribute("type","file");
user_area.appendChild(inp);
inp.addEventListener("click",upload_video)
}
window.onload = function(){
video_button.innerHTML = "upload a video";
video_button.addEventListener("click",input);
user_area.setAttribute("contentEditable","true");
user_area.style.width = "100px";
user_area.style.height = "500px";
document.body.appendChild(user_area);
user_area.appendChild(video_button);
}
This is not working on firefox because of the content editable attribute set to true. And there is a reason behind it.
If you don't need it that much, you can remove it.
var video_button = document.createElement("BUTTON");
var user_area = document.createElement("DIV");
var input_wrapper = document.createElement("DIV");
var inp = document.createElement("INPUT");
function upload_video(e){
console.log("upload_video function");
var v = document.createElement("VIDEO");
inp.onchange = function(e){
v.src = window.URL.createObjectURL(inp.files[0]);
v.style.heigth = "1000px";
v.style.width = "1000px";
user_area.appendChild(v);
}
}
function input(e){
console.log("input function");
inp.setAttribute("type","file");
input_wrapper.setAttribute("contentEditable","false");
user_area.appendChild(input_wrapper);
input_wrapper.appendChild(inp);
inp.addEventListener("click",upload_video)
}
window.onload = function(){
video_button.innerHTML = "upload a video";
video_button.addEventListener("click",input);
user_area.setAttribute("contentEditable","true");
user_area.style.width = "100px";
user_area.style.height = "500px";
document.body.appendChild(user_area);
user_area.appendChild(video_button);
}

JavaScript button doesn't work on second click

I want to make a program changing background color of a div after clicking on a button.
After first click it should change one color to the second one. After second click the color should come back to the first option. And for the last time, the color should be switched again to the second option. So it should work for 3 times. But in my code it works just for the first click.
What did I do wrong?
var btn = document.getElementById('button');
var box = document.getElementById('sq');
function changeColor() {
var isPink = true;
var colorA = "#BA498B";
var colorB = "#5964E3";
var i = 0;
while (i < 3) {
if (isPink) {
change(colorB);
isPink = false;
i++;
} else {
change(colorA);
isPink = true;
i++;
}
}
}
function change(color) {
btn.addEventListener('click', function () {
box.style.backgroundColor = color;
});
}
window.onload = changeColor;
You're adding a new, identical event handler every time there's a click. Instead just add it once when the page loads, so that the redundant handlers don't cancel each other out.
var isPink = true;
function changeColor() {
var colorA = "#BA498B";
var colorB = "#5964E3";
if (isPink) {
change(colorB);
} else {
change(colorA);
}
isPink = !isPink;
}
function change(color) {
document.getElementById('sq').style.backgroundColor = color;
}
window.onload = function() {
document.getElementById('button').addEventListener('click', changeColor);
};
#sq {
width: 100px;
height: 100px;
position: relative;
}
<button id=button>CLICK</button>
<div id=sq></div>
Don't know what you wanted with the loop though, so I removed it. It runs immediately, and so you'd never see such a rapid color change.
try this:
var isPink = true;
var color = "#BA498B"
function changeColor() {
var colorA = "#BA498B";
var colorB = "#5964E3";
if (isPink) {
color = (colorB);
isPink = false;
} else {
color = (colorA);
isPink = true;
}
}
window.onload = function(){
var btn = document.getElementById('button');
var box = document.getElementById('sq');
btn.addEventListener('click', function () {
changeColor();
box.style.backgroundColor = color;
});
};
This way I'm only using 'addEventListener' on the button once
Here is an example which may help you:
var btn = document.getElementById('button');
var box = document.getElementById('sq');
var isPink = true;
function changeColor() {
var colorA = "#BA498B";
var colorB = "#5964E3";
var color=isPink?colorA:colorB;
isPink=isPink?false:true;
return color;
}
function change() {
box.style.backgroundColor = changeColor();
}
btn.addEventListener('click', change);
window.onload = change();
<h1 id="sq">Test Text for Example</h1>
<button id="button">Click</button>

how do i add functionality to each of the buttons?

The first part of the code is working correctly, but now that each button appears, how do i add functionality to each of them? currently the only button which does something when pressed is always the last one, the rest do nothing.
Change it to
{
var output = "";
var data = JSON.parse(e.target.responseText);
for(var i=0; i<data.length; i++)
{
output = data[i].title + ' ';
var p = document.createElement("p");
var div = document.getElementById("response");
var textNode = document.createTextNode(output);
p.appendChild(textNode);
var button = document.createElement("button");
button.innerHTML = "Download";
p.appendChild(button);
div.appendChild(p);
button.addEventListener ("click", () =>
{
alert("Test");
});
}
}
You are adding the below code out side the for loop
button.addEventListener ("click", () =>
{
alert("Test");
} );
Keep the above code inside the for loop. So that for each button the event listener will be added.
Another way to approach this would be to add the callback function to the onclick variable of the elements prototype:
function doStuff() {
var output = "";
var data = JSON.parse(e.target.responseText);
for (var i = 0; i < data.length; i++) {
output = data[i].title + ' ';
var p = document.createElement("p");
var div = document.getElementById("response");
var textNode = document.createTextNode(output);
p.appendChild(textNode);
var button = document.createElement("button");
button.innerHTML = "Download";
// Adds the callback function here
button.onclick = () => {
// fill in your arrow function here...
alert("Test");
};
p.appendChild(button);
div.appendChild(p);
};
}
doStuff();
Here is a jsFiddle
You should use event delegation for dynamically added elements
// sample data
var data = [{
title: 'one'
}, {
title: 'two'
},{
title: 'three'
}];
var output = "";
for (var i = 0; i < data.length; i++) {
var output = data[i].title + " ";
var p = document.createElement("p");
var div = document.getElementById("response");
var textNode = document.createTextNode(output);
p.appendChild(textNode);
var button = document.createElement("button");
// added output to button text for identification
button.innerHTML = output + " Download";
p.appendChild(button);
div.appendChild(p);
}
// Get the parent element, add a click listener
document.getElementById("response").addEventListener("click", function(e) {
// e.target is the clicked element!
// If it was a button
if (e.target && e.target.nodeName == "BUTTON") {
// Button found! Output the identifying data!
// do other work on click
document.getElementById("display").innerHTML = e.target.innerHTML + " Clicked";
}
});
<div id="response"></div>
<div id="display">Display</div>

HTML Button created in object constructors onclick event not working

So whatever is causing the error must actually be in this loop:
Creating a box by calling the gridBox constructor on its own works. But those created by the buildField function do not return an on click event.
var grid = [];
function buildField(size){
//loops through each row
for(var y=0; y<size;y++){
//loops through each column
grid[y]=[];
for(var x=0; x<size; x++){
//create new object for grid
grid[y][x] = new gridBox(x,y);
}
document.getElementById("board").innerHTML += "<br>";
}
}
function gridBox(x,y){
this.x=x;
this.y=y;
var me = this;
//function to create and add button.
function makeBtn(){
var btn = document.createElement("BUTTON");
btn.type = "BUTTON";
btn.className = "gridButton";
btn.value = "BUTTON";
btn.name = me;
btn.onclick = function(){
console.log("click");
};
document.getElementById("board").appendChild(btn);
console.log("madeButton");
}
makeBtn();
}
document.getElementById("board").innerHTML += "<br>";
This will:
Convert the DOM to HTML
Add <br> to that HTML
Convert that HTML to DOM
Overwrite the existing DOM with that
… the onclick event handlers will not be part of the serialised HTML, so they will be lost when step 4 happens.
Use createElement and appendChild again. Don't use innerHTML.
This is working for me:
function gridBox(x,y){
this.x=x;
this.y=y;
var me = this;
//function to create and add button.
function makeBtn(){
var btn = document.createElement("BUTTON");
btn.className = "gridButton";
btn.textContent = "Click Me";
btn.name = me;
btn.onclick = function(){
console.log("click");
};
document.getElementById("board").appendChild(btn);
console.log("madeButton");
}
makeBtn();
}
gridBox(10,10);
.gridButton {
height:30px;
width:100px;
}
<div id=board></div>
try adding btn.onClick after document...appendChild(..) :
this works for me
function gridBox(x,y){
this.x=x;
this.y=y;
var me = this;
//function to create and add button.
function makeBtn(){
var btn = document.createElement("BUTTON");
btn.type = "BUTTON";
btn.className = "gridButton";
btn.value = "BUTTON";
btn.name = me;
document.getElementById("board").appendChild(btn);
btn.onclick = function(){
console.log("click");
};
console.log("madeButton");
}
makeBtn();
}
// make simple button
gridBox(10,10);
<div id="board">
</div>
Try with:
btn.addEventListener('click', function(){ });
instead of your btn.onclick

Categories