I have an Uncaught ReferenceError: FAVOURITES is not defined(onclick), i don't understand where is my sintax error in button.setAttribute("onclick", "ContactLoader.table(" + table +")");.
ContactLoader.table =
function(table){
ContactLoader.CURRENT_PATTERN = null;
ContactLoader.CURRENT_TABLE = table;
ContactLoader.CURRENT_LETTER = "A";
ContactLoader.loadData();
}
function generateSearchLetter(){
var divSearch = document.getElementById("search");
if(divSearch.lastChild.id === "search_name");
divSearch.removeChild(divSearch.lastChild);
var divSearchLetter = document.createElement('div');
divSearchLetter.setAttribute("id", "search_letter");
divSearch.appendChild(divSearchLetter);
var divAllFav = document.createElement('div');
divAllFav.setAttribute("class", "search_all_favourites");
divSearchLetter.appendChild(divAllFav);
var arr1 = new Array("ALL","FAVOURITES");
for(var i=0; i<2; i++){
var button = document.createElement('div');
var textNode = document.createTextNode(arr1[i]);
button.appendChild(textNode);
var table = button.textContent;
button.setAttribute("class" , "letterAF");
button.setAttribute("onclick", "ContactLoader.table(" + table +")");
divAllFav.appendChild(button);
}
}
As you're trying to bind an event to a DOM element, it's not a good idea to bind click event using setAttribute. This approach is been deprecated since many years ago.
To bind the click event to the button variable, it is better to replace:
button.setAttribute("onclick", "ContactLoader.table(" + table +")");
with
button.addEventListener("click", function () {
ContactLoader.table(table);
});
Related
btnUpdate = document.createElement("BUTTON");
var t = document.createTextNode("Update");
btnUpdate.id = 'update0';
btnUpdate.appendChild(t);
tabCell.appendChild(btnUpdate);
I have a simple line of code where I have created a button with my javascript. How do I access this button through the same javascript file? I want to add onClick feature to it.
document.getElementById("update0").onclick = edit_row(0);
I tried doing so by adding the above line of code, but now it won't display the table but straight away jumps to the edit_row() function.
Edit:
function showCustomer() {
var obj, dbParam, xmlhttp, myObj, x, txt = "",tabCell;
var btnUpdate;
obj = { "table":"Successful", "limit":20 };
dbParam = JSON.stringify(obj);
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
myObj = JSON.parse(xmlhttp.responseText);
console.log(myObj);
var col = [];
for (var i = 0; i < myObj.length; i++) {
for (var key in myObj[i]) {
if (col.indexOf(key) === -1) {
col.push(key);
}
}
}
key="Update";
col.push(key);
console.log(col);
// CREATE DYNAMIC TABLE.
var table = document.createElement("table");
// CREATE HTML TABLE HEADER ROW USING THE EXTRACTED HEADERS ABOVE.
var tr = table.insertRow(-1); // TABLE ROW.
for (var i = 0; i < col.length; i++) {
var th = document.createElement("th"); // TABLE HEADER.
th.innerHTML = col[i];
tr.appendChild(th);
}
// ADD JSON DATA TO THE TABLE AS ROWS.
for (var i = 0; i < myObj.length; i++) {
tr = table.insertRow(-1);
tabCell = null;
for (var j = 0; j < col.length-1; j++) {
tabCell = tr.insertCell(-1);
tabCell.innerHTML = myObj[i][col[j]];
}
tabCell = tr.insertCell(-1);
btnUpdate = document.createElement("BUTTON");
var t = document.createTextNode("Update");
btnUpdate.id = 'update'+i;
btnUpdate.appendChild(t);
tabCell.appendChild(btnUpdate);
}
tr = table.insertRow(-1);
tabCell = null;
for (var j = 0; j < col.length-1; j++) {
tabCell = tr.insertCell(-1);
tabCell.innerHTML = " ";
}
tabCell = tr.insertCell(-1);
var btn = document.createElement("BUTTON");
var t = document.createTextNode("Add Row");
btn.appendChild(t);
tabCell.appendChild(btn);
document.getElementById("update0").addEventListener = function (){
edit_row(0);
};
// FINALLY ADD THE NEWLY CREATED TABLE WITH JSON DATA TO A CONTAINER.
var divContainer = document.getElementById("showData");
divContainer.innerHTML = "";
divContainer.appendChild(table);
}
};
xmlhttp.open("POST", "http://localhost:8090/Vaccine", true);
xmlhttp.setRequestHeader("Content-type", "application/JSON");
xmlhttp.send("x=" + dbParam);
}
function edit_row(no)
{
alert("HELLO");
}
With this line :
document.getElementById("update0").onclick = edit_row(0);
You are not "attaching" the click event to the edit_row function. You're setting the onclick property with the result of the edit_row(0) invokation.
Also, don't use the onclick property.
Use the addEventListener function instead.
document.getElementById("update0").addEventListener("click", function () {
edit_row(0);
});
If you need a reason : by overwriting the onclick property, you could be disabling any other click event listener on your elements. By using addEventListener(), you can have several events listener on the same element/event couple.
And you can do this right after you created the button. You don't need to get it by its id later.
Your code would look like this :
btnUpdate = document.createElement("BUTTON");
var t = document.createTextNode("Update");
btnUpdate.id = 'update0';
btnUpdate.appendChild(t);
btnUpdate.addEventListener("click", function () {
edit_row(0);
});
You have to do that in callback of on click event. If you inline, it executes directly when javascript reading your code.
document.getElementById("update0").onclick = function (){
edit_row(0);
};
How do I access this button through the same javascript file?
The same way you've been accessing it all along.
It is stored in the btnUpdate variable. Use that.
but now it won't display the table but straight away jumps to the edit_row() function.
That is because you are calling edit_row and setting its return value as the click handler.
Since you want to pass arguments to it, the easiest thing to do is to create a new function.
function edit_row_first_argument_0 () {
edit_row(0);
}
button.addEventListener("click", edit_row_first_argument_0);
(You can use an anonymous function expression, I use the verbose approach above for clarity).
Try this:
btnUpdate = document.createElement("BUTTON");
var t = document.createTextNode("Update");
btnUpdate.id = 'update0';
btnUpdate.appendChild(t);
tabCell.appendChild(btnUpdate);
btnUpdate.addEventListener("click", (e) => {
// this linked to btnUpdate
// Here make whatever you want
// You can call edit_row now
edit_row(0)
})
It seems that your button is not in the DOM yet, so you are not able to find it with document. You can use the variable btnUpdate if it is in the same file like btnUpdate.onclick = function() {}, or using addEventListenerlike btnUpdate.addEventListener('click', function() {}).
Also, it seems you are executing the edit_row(0) function. You need to put it inside a function like
btnUpdate.addEventListener('click', function() {
edit_row(0);
})
You call the function when you have () at the end so
document.getElementById("update0").onclick = edit_row(0);
will immediately call edit_row
Why not do this instead:
btnUpdate = document.createElement("BUTTON");
var t = document.createTextNode("Update");
btnUpdate.id = 'update0';
btnUpdate.onclick=function() {
edit_row(this.id.replace("update","")); // or use a data-attribute
}
btnUpdate.appendChild(t);
tabCell.appendChild(btnUpdate);
or use event delegation:
Native JS equivalent to jquery delegation
below I'm trying to add new anchor elements to the DOM.
I also like to add an onclick event to each new created element that returns its id, but can't get it done.
All help is welcome!
var text = document.getElementById("output");
for (var i = 0; i < uld.length; i++){
var x = document.createElement("A");
var t = document.createTextNode(uld[i][1]);
x.setAttribute('id', i);
x.onclick = function getId() {alert("kikker");};
x.appendChild(t);
text.appendChild(x);
}
The 'this' pointer in a onclick is refering to the element.
So you could use the 'id' like this:
var text = document.getElementById("output");
var i;
for (i = 0; i < uld.length; i++) {
var x = document.createElement("A");
var t = document.createTextNode(uld[i][1]);
x.setAttribute("id", i);
x.onclick = function() {
var id = this.id;
alert(id);
};
x.appendChild(t);
text.appendChild(x);
}
So I was in the presumption that this function
button.onclick = exampleFunk;
would give me a handler on each button when I click them, but it doesn't. When replacing it with:
button.onclick = alert("bananas");
I'm getting alerts at page onload. The problem is already solved with this:
button.setAttribute("onclick", "removeIssue(this)");
Out of curiousity... What's going on?
edited layout of post
EDIT
var issues = [];
window.onload = function () {
//alert("venster geladen");
issuesToList()
}
function issuesToList(data) {
/*alert(
"array length is " + data.issues.length + "\n" +
"total_count is " + data.total_count + "\n" +
"limit is " + data.limit + "\n" +
"offset is " + data.offset + "\n" + ""
);*/
for (i = 0; i < data.issues.length; i++) {
issue = data.issues[i];
createIssue(issue);
}
}
function createIssue(issue){
var id = issue.id;
var tracker = issue.tracker;
var status = issue.status;
var priority = issue.priority;
var subject = issue.subject;
var description = issue.description;
var assignee = issue.assignee;
var watchers = issue.watchers;
var ticket = new Issue(id, tracker, status, priority, subject, description, assignee, watchers);
issues.push(ticket);
var button = document.createElement("button");
button.innerHTML = "-";
button.onclick = function (){ alert("bananas")};
//button.setAttribute("onclick", "removeIssue(this)");
var item = document.createElement("div");
item.setAttribute("id", id);
item.appendChild(button);
item.innerHTML += " " + subject;
var container = document.getElementById("container");
container.appendChild(item);
}
function removeIssue(e){
var key = e.parentNode.getAttribute("id");
var count = issues.length;
if(confirm("Confirm to delete")){
for(i=0; i<count; i++){
if (issues[i].id == key ){
issues.splice(i,1);
var element = document.getElementById(key);
element.parentNode.removeChild(element);
}
}
}
}
function Issue(id, tracker, status, priority, subject, description, assignee, watchers){
this.id = id;
this.tracker = tracker;
this.status = status;
this.priority = priority;
this.subject = subject;
this.description = description;
this.assignee = assignee;
this.watchers = watchers;
}
EDIT
<body>
<h1>List of Issues</h1>
<div id="container"></div>
<script src="http://www.redmine.org/issues.json?limit=10&callback=issuesToList"></script>
</body>
You need to mask the alert in a function:
button.onclick = function (){ alert("bananas")};
As such:
var btn = document.createElement("BUTTON");
var t = document.createTextNode("CLICK ME");
btn.appendChild(t);
btn.onclick = function() {alert("bananas")};
document.body.appendChild(btn);
Whats going on?
You alert() is executed on page load because its a function call. When the execution of your script reaches that line your assignment
button.onclick = alert("bananas");
is actually executing the alert statement and not assigning it to button.onclick
You can bind arguments to the function so that it returns with the function you want it to call using your arguments (with additional arguments passed later added on to the end). This way doesn't require writing extraneous code (when all you want to do is call a single function) and looks a lot sleeker. See the following example:
button.onclick = alert.bind(window, "bananas");
An unrelated example of how it works in your own code is like this:
var alert2 = alert.bind(window, 'Predefined arg');
alert2(); // 'Predefined arg'
alert2('Unused'); // 'Predefined arg'
For IE, this requires IE9 as a minimum. See MDN for more information.
EDIT: I've looked closer at your code and there was one significant change that was needed for it to work... You cannot add onto the innerHTML when you've added JavaScript properties to a child element. Changing the innerHTML of the parent element will convert your element into HTML, which won't have the onclick property you made before. Use element.appendChild(document.createTextNode('My text')) to add text dynamically.
See a functioning example here: http://jsfiddle.net/2ftmh0gh/2/
I have a script where I'm appending elements to a list. I would need that when I click the element a function is called, and for this function the value of a variable when creating the li is needed (it's the li content).
I've checked solutions like adding newLi.onclick = function(){...}.
The problem with this solution is that I'm not getting the right value in the function, I get the value of another element in the list.
Right now this is how I'm creating the elements:
var ULlist = document.getElementById('ULid');
for(i=0;i<data.length;i++){
var Value = data[i] //function to get data
var newLi = document.createElement('li');
newLi.appendChild(elements.createTextNode(Value));
newLi.onclick = function(){alert(Value)} //not displaying the right value
ULlist.appendChild(newLi);
}
So the question is, is there any way to create te onclick event giving to the element the right value of the variable?
Edit: I've added a portion more of code.
Li's are being created, and information displayed correctly, the only problem is when trying to create the event that it's not giving the right value, that should be the value cointained at the li
You can achieve this by creating function inside and keeping the value in the scope of that function.
var data = [10, 20, 30, 40, 50, 60, 70];
addItems = function() {
var list = document.getElementById("list");
for (var i = 0; i < data.length; i++) {
var newLi = document.createElement("li");
newLi.innerHTML = i + 1;
list.appendChild(newLi);
(function(value){
newLi.addEventListener("click", function() {
alert(value);
}, false);})(data[i]);
}
}
jsfiddle : http://jsfiddle.net/Qf5JZ/1/
Use DOM2 event listeners, in particular the element.addEventListener API:
function clickHandlerFor(data) {
return function(event) {
var li = event.target;
// do something with data and li.
};
}
for (...) {
var Data = ... //function to get data
var newLi = elements.createElement('li');
newLi.appendChild(elements.createTextNode(Data));
newLi.addEventListener("click", clickHandlerFor(Data), false);
ULlist.appendChild(newLi);
}
Another option is much simpler: use the TextNode value in your handler:
function handler(event) {
var dataValue = event.target.firstChild.nodeValue; // value of TextNode created by elements.createTextNode(Data)
// handle dataValue
}
newLi.addEventListener("click", handler, false);
When I experienced this problem, I solved it like this:
var ULlist = document.getElementById('ULid');
for(var i=0; i<data.length; i++){
var index = i;
(function() {
var Value = data[index] //function to get data
var newLi = document.createElement('li');
newLi.appendChild(elements.createTextNode(Value));
newLi.onclick = function() { ... };
ULlist.appendChild(newLi);
}());
}
Edit: Today, I remember another thing about for scope. It is another solution to send parameter 'i' to function inside the loop:
var ULlist = document.getElementById('ULid');
for(var i=0; i<data.length; i++){
(function(index) {
var Value = data[index] //function to get data
var newLi = document.createElement('li');
newLi.appendChild(elements.createTextNode(Value));
newLi.onclick = function() { ... };
ULlist.appendChild(newLi);
}(i));
}
Try this and let me know if it works.
I am having trouble removing the child of a child of an object created using JS.
Basically once I create a comment object I appendChild(replyBox) to it. Inside the replyBox there is a cancel button which is supposed to completely delete the replyBox.
Here is the code :
function Comment(message){
var self = this;
var message = message;
var comment = document.createElement("li");
comment.id = "comment";
comment.style = "display: none;";
comment.textContent = message;
createButtons(comment);
var parent = document.getElementById("wall");
parent.appendChild(comment);
return comment;
}
function deleteComment(comment){
var parent = document.getElementById("wall");
parent.removeChild(comment);
}
function newReply(comment){
var buttons = comment.getElementsByTagName("input");
buttons.item(0).disabled="disabled";
var replyBox = document.createElement("div");
replyBox.id="replyBox";
var replyTxt = document.createElement("input");
replyTxt.type="text";
replyTxt.value="Write a reply";
replyTxt.onfocus = "if(this.value==this.defaultValue) this.value='';" ;
replyTxt.onblur="if(this.value=='') this.value=this.defaultValue;";
replyBox.appendChild(replyTxt);
createButtons(replyBox);
comment.appendChild(replyBox);
}
function createButtons(parent){
var button = document.createElement("input");
button.type = "submit";
if(parent.id=="comment"){
var reply = button.cloneNode();
reply.value = "reply";
reply.addEventListener("click", function(){newReply(parent)},false);
parent.appendChild(reply);
var deleteBtn = button.cloneNode();
deleteBtn.value = "delete";
deleteBtn.addEventListener("click", function(){deleteComment(parent)},false);
parent.appendChild(deleteBtn);
}
else{
var submitBtn = button.cloneNode();
submitBtn.value = "submit";
//reply.addEventListener("click", function(){newReply(parent)},false);
parent.appendChild(submitBtn);
var cancel = button.cloneNode();
cancel.value = "cancel";
cancel.addEventListener("click", function(){cancel(parent)},false);
parent.appendChild(cancel);
}
}
function cancel(replyBox){
replyBox.parentNode.removeChild(replyBox);
}
cancel.addEventListener("click", function(){cancel(parent)},false);
Which cancel is which? You have an object called cancel as well as a function with the same name. Try renaming one.
I see a problem here:
comment.id = "comment";
If you're setting all IDs of the comment elements to comment, the DOM may be getting confused.