I'm studding HTML, CSS and JS and while I was creating an exercise, I was forced to stop due to an error. I created an button dynamically, setted an onclick to it and then created a function with that onclick. The problem is that the function isn't working, at leats it doesn't made anything till now.
let formularys = document.querySelector('section#formulary')
let slct = document.createElement('select')
let opts = document.createElement('option')
let optp = document.createElement('option')
let fbtn = document.querySelector('input#formularybtn')
let nbtn = document.createElement('input')
let br = document.createElement('br')
slct.id = 'pors'
slct.size = '2'
opts.value = 'rsite'
opts.innerHTML = 'Rate site'
optp.value = 'rp'
optp.innerHTML = 'Rate products'
nbtn.setAttribute('type', 'button')
nbtn.setAttribute('value', 'Next')
nbtn.setAttribute('onclick', 'nbutton')
function nbutton(){
console.log('Next working')
/*if(slct.selectedIndex == 1){
console.log('Valid rate choose')
}*/`enter code here`
}
instead of using setAttribute you can just do
nbtn.onclick = nbutton
in javascript, onclick isn't a string but a function.
The problem is, you are not appending your html code generated from JavaScript to DOM. You can either append to main DOM like below
document.body.appendChild(nbtn);
document.body.appendChild(optp);
or you can append them to some parent div by first getting div id
document.getElementById("divId").appendChild(nbtn);
where divId is id of your div where you want to add this html.
Also you should assign event listener in correct way as suggested by Tony and Rashed Rahat.
Try:
element.onclick = function() { alert('onclick requested'); };
Related
I need to create checkbox for each element in data.contents. So far I have created checkboxes using createElemnt(), set ID as their respective title and calling myFunction() during onClick. Now I am trying to retrieve ID when the checkbox is clicked using getElementbyID(b.title) and ended up with an error "b is not defined" which is obvious because I am trying to access b.title outside for loop.
I can't place myFunction() inside for loop because getElementById(b.title) is giving last checkbox's ID for all checkboxes if i do onClick which is also obvious because that's the last iteration's (b.title) of for loop.
My purpose is to retrieve ID(which was dynamically set inside for loop) of a checkbox during onClick from outside for loop. Any help would be much appreciated.
data.contents.forEach(b => {
const btn = document.createElement('input')
btn.type = 'checkbox'
btn.setAttribute("id", b.title)
btn.setAttribute("onClick", "myFunction();");
var t = document.createTextNode(b.title);
mydiv.appendChild(btn);
mydiv.appendChild(t);
});
window.myFunction = function() {
var checkBox = document.getElementById(b.title);
console.log(b.title)
}
HTML
<div id="mydiv">
</div>
Rather than using setAttribute('onClick', consider assigning directly to the onclick property - that will allow you to use the b in that iteration in the handler's closure. There's also no need to create a global function, and you can simply assign to the id property of btn rather than using setAttribute:
data.contents.forEach(b => {
const btn = document.createElement('input')
btn.type = 'checkbox'
btn.id = b.title;
btn.onclick = () => {
console.log(b.title);
// do stuff with button and b
};
var t = document.createTextNode(b.title);
mydiv.appendChild(btn);
mydiv.appendChild(t);
});
If the only reason you were setting the ID was to be able to select it again with getElementById later, you can omit that entirely, due to the closure.
Try this,
data.contents.forEach(b => {
const btn = document.createElement('input')
btn.type = 'checkbox'
btn.setAttribute("id",b.title);
btn.setAttribute("data",b.title);
btn.setAttribute("onClick","myFunction('"+b.title+"');");
var t = document.createTextNode(b.title);
mydiv.appendChild(btn);
mydiv.appendChild(t);
});
window.myFunction = function(id) {
var checkBox = document.getElementById(id);
console.log(id);
}
I'm trying to put a delete button on each li using JavaScript and to make an event handler that runs when a button is clicked that removes the li. However when I try to add the handler, I get:
Cannot read property 'addEventListener' of null
I think this is because I am referencing a class that not exist before run the function createbtn. So How can I solve this?
The Code:
I set the variables, put querySelector to buttons because I testing how to do it:
var button = document.getElementById("enter");
var input = document.getElementById("userinput");
var ul = document.querySelector("ul");
var list = document.querySelectorAll ("li");
var buttons = document.querySelector (".btn-danger");
var li = document.createElement("li")
How I create the button:
function createbtn() {
for (var i = 0; i < list.length; i++) {
var btn = document.createElement("button");
btn.appendChild(document.createTextNode("Delete"));
btn.classList.add("btn", "btn-danger","btn-sm");
list[i].appendChild(btn);
}
}
The function I try to run:
function liDel(){
li.parentNode.removeChild(li);
}
buttons.addEventListener("click", liDel);
This is my fiddle to see all the code.
The reason why you are getting the null error is because;
You have assigned the variable buttons to a node which doesn't exist yet. (Note that the button is created after the page has been loaded, which means .btn-danger hasn't yet been created at that time).
According to MDN the querySelector method does the the ff:
The Document method querySelector() returns the first Element within the document that matches the specified selector, or group of selectors. If no matches are found, null is returned.
Based on the code you have in the fiddle, here is a guide to achieve the desired results.
First of all, get rid of the global li variable on line 6.
The reason is that if you create a new li from the input, it will render on the same line because it's still referencing the same element node (I'm sure you've realized that)
then in your createListElement function, do the ff
function createListElement() {
var li = document.createElement('li');
li.appendChild(document.createTextNode(input.value));
var btn = document.createElement("button");
btn.appendChild(document.createTextNode("Delete"));
btn.classList.add("btn", "btn-danger","btn-sm");
btn.addEventListener('click', function(e){
if(!e) e = window.event;
try{
ul.removeChild(this.parentNode)
}catch(err){
alert(err.message)
}
})
li.appendChild(btn)
ul.appendChild(li);
input.value = "";
}
Then when you create the buttons, you have to attach the event listener function to it. So you do the ff in your createbtn function:
// To create a button
function createbtn() {
for (var i = 0; i < list.length; i++) {
var btn = document.createElement("button");
btn.appendChild(document.createTextNode("Delete"));
btn.classList.add("btn", "btn-danger","btn-sm");
btn.addEventListener('click', function(e){
if(!e) e = window.event;
try{
ul.removeChild(this.parentNode)
}catch(err){
alert(err.message)
}
})
list[i].appendChild(btn);
}
}
anyways, there are more efficient ways to do this. But this is a quick workable model based on the code in your fiddle
Rather than querying and adding the event to the buttons object
try the chaining inside the document load.
window.onload = function () {
document.querySelector('.btn-danger').addEventListener('click', liDel);
};
The above code should work!
Thanks a lot everybody, I got a solution after reading all your answers:
First I got rid the following:
var buttons = document.querySelector (".btn-danger");
var li = document.createElement("li")
Then create this function for remove the "li"
Using "this" you avoid the error for don't have a reference, because with that you don't care in what kind of element this is, you only now something is there and grab it for anything you need.
function liDel(){
ul.removeChild(this.parentNode);
}
and put this in createBtn for delete the existing "li" in the html:
btn.addEventListener('click', liDel);
then put this on createElement for do the same of the above, but for the new "li" creates with the DOM:
btn.addEventListener('click', liDel);
li.appendChild(btn);
And with that the problems was solved.
Thanks again and you can see how the page works on the fiddle
I'm struggling to make the onclick event listener work in my results.
here is my code:
function createLink(text, parentElement) {
var a = document.createElement('p');
var linkText = document.createTextNode(text);
a.appendChild(linkText);
temp1 = text.replace("/","-");
temp2 = res1.replace("/","-");
a.onclick=function(){goMainMenuFromResults();};
parentElement.appendChild(a);
var br = document.createElement('br');
parentElement.appendChild(br);
}
The line in question is:
a.onclick=function(){goMainMenuFromResults();};
The function is present in another section but works in the hardcoded html events. I just can't make it work when its imported into the element in javascript.
Any help will be greatly appreciated!
James, it seems to work fine, just a var called res1 was getting error here. Take a look:
temp2 = res1.replace("/","-");
http://jsfiddle.net/MarcelKohls/23tBM/291/
I removed the lines containing variables that were not defined. I then added a call to preventDefault() on the event raised inside the event handler. And it now works fine. New elements are created and the click handler works on the new elements.
function createLink(text, parentElement) {
var a = document.createElement('p');
var linkText = document.createTextNode(text);
a.appendChild(linkText);
//temp1 = text.replace("/","-");
//temp2 = res1.replace("/","-");
a.onclick = function(e) {
e.preventDefault();
goMainMenuFromResults();
};
parentElement.appendChild(a);
var br = document.createElement('br');
parentElement.appendChild(br);
}
I'm currently building a small Todo list application using vanilla Javascript but I'm having some issues creating a delete button that onClick removes it's parent element.
From what I have read, when an onClick is called in Javascript the this keyword can be used to refer to the element that called the function. With this in mind I have the following code:
window.onload = initialiseTodo;
function addRecord(){
var title = document.getElementById('issueTitle');
var issueContent = document.getElementById('issueContent');
var contentArea = document.getElementById('contentArea');
if(title.value.length > 0 && issueContent.value.length > 0){
var newItem = document.createElement('div');
newItem.id = 'task' + count++;
newItem.className = 'task';
newItem.innerHTML = '<div class="taskbody"><h1>' + title.value + '</h1>'+ issueContent.value + '</div><div class="deleteContainer">'
+ '<a class="delete">DELETE</a></div>';
contentArea.appendChild(newItem);
assignDeleteOnclick();
}
}
function deleteRecord(){
this.parentNode.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode);
}
function assignDeleteOnclick(){
var deleteArray = document.getElementsByClassName('delete');
for(var i=0;i<deleteArray.length;i++){
deleteArray[i].onclick= deleteRecord();
}
}
function initialiseTodo(){
var btn_addRecord = document.getElementById('addRecord');
btn_addRecord.onclick = addRecord;
}
Basically I have a form that has two fields. When these fields are filled and the addRecord button is clicked a new div is added at the bottom of the page. This div contains a delete button. After the creation of this I assign an onclick event to the delete button which assigns the deleteRecord function when the delete button is clicked. My issue is with the deleteRecord function. I have used this to refer to the calling element (the delete button) and wish to remove the task div that is the outermost container however I current get a message that says: 'Cannot read property 'parentNode' of undefined ' which suggests to me the this keyword is not working correctly.
Any help would be greatly appreciated.
I've added the full code to a fiddle.
http://jsfiddle.net/jezzipin/Bd8AR/
J
You need to provide the element itself as a parameter. I did so by changing the html to include onclick="deleteRecord(this)" to make it a little easier to deal with. This means you can remove the assignDeleteOnclick() function
function deleteRecord(elem){
elem.parentNode.parentNode.remove();
}
Demo
You might style the .content to be hidden better if there are no elements to prevent that extra white space
Edit
Since you don't want an inline onclick, you can do it with js the same:
function deleteRecord(elem){
elem.parentNode.parentNode.remove();
}
function assignDeleteOnclick(){
var deleteArray = document.getElementsByClassName('delete');
for(var i=0;i<deleteArray.length;i++){
// Has to be enveloped in a function() { } or else context is lost
deleteArray[i].onclick=function() { deleteRecord(this); }
}
}
Demo
I am adding a button dynamically in html like below:
On click of that button I want to call a Javascript function:
var but = document.createElement("button");
but.value="delete row";
but.setAttribute("onclick","callJavascriptFunction()");
//this is not working
but.onclick="callJavascriptFunction()"
//this is also not working
document.getElementById("but").onclick="callJavascriptFunction()"
//this is also not working
but.id="but"+inc;
How can this be resolved?
try this:
but.onclick = callJavascriptFunction;
or create the button by wrapping it with another element and use innerHTML:
var span = document.createElement('span');
span.innerHTML = '<button id="but' + inc +'" onclick="callJavascriptFunction()" />';
Remove the () from your expressions that are not working will get the desired results you need.
but.setAttribute("onclick",callJavascriptFunction);
but.onclick= callJavascriptFunction;
document.getElementById("but").onclick=callJavascriptFunction;
This code work good to me and look more simple. Necessary to call a function with specific parameter.
var btn = document.createElement("BUTTON"); //<button> element
var t = document.createTextNode("MyButton"); // Create a text node
btn.appendChild(t);
btn.onclick = function(){myFunction(myparameter)};
document.getElementById("myView").appendChild(btn);//to show on myView
Try
but.addEventListener('click', yourFunction)
Note the absence of parantheses () after the function name. This is because you are assigning the function, not calling it.
but.onclick = function() { yourjavascriptfunction();};
or
but.onclick = function() { functionwithparam(param);};
I was having a similar issue but none of these fixes worked. The problem was that my button was not yet on the page. The fix for this ended up being going from this:
//Bad code.
var btn = document.createElement('button');
btn.onClick = function() { console.log("hey"); }
to this:
//Working Code. I don't like it, but it works.
var btn = document.createElement('button');
var wrapper = document.createElement('div');
wrapper.appendChild(btn);
document.body.appendChild(wrapper);
var buttons = wrapper.getElementsByTagName("BUTTON");
buttons[0].onclick = function(){ console.log("hey"); }
I have no clue at all why this works. Adding the button to the page and referring to it any other way did not work.
Try this:
var inputTag = document.createElement("div");
inputTag.innerHTML = "<input type = 'button' value = 'oooh' onClick = 'your_function_name()'>";
document.body.appendChild(inputTag);
This creates a button inside a DIV which works perfectly!
but.onclick = callJavascriptFunction;
no double quotes no parentheses.
Using modern JavaScript, this solution works well:
let btn = document.getElementById("btnID");
btn.onclick = () => {onAction(url, method);};
for me this works!
button.onclick = () => (removechore());