React Error : (function) is not defined at HTMLButtonElement.onclick - javascript

I am using ReactJS and I am creating a button "remove" in a method called showData() and appending it to a row in a table of people.
I am setting its attribute onclick to my method removePerson() implemented in the same class of the method showData().
This is all good until I click on the button "remove" - then an error shows:
ReferenceError: removePerson() is not defined at HTMLButtonElement.onclick
This is my code:
showData() {
let localStoragePersons = JSON.parse(localStorage.getItem("personsForms"));
persons = localStoragePersons !== null ? localStoragePersons : [];
let table = document.getElementById('editableTable');
let x = table.rows.length;
while (--x) {
table.deleteRow(x);
}
let i = 0;
for (i = 0; i < persons.length; i++) {
let row = table.insertRow();
let firstNameCell = row.insertCell(0);
let lastNameCell = row.insertCell(1);
let birthdayCell = row.insertCell(2);
let salaryCell = row.insertCell(3);
let choclatesCell = row.insertCell(4);
let genderCell = row.insertCell(5);
let workTypeCell = row.insertCell(6);
let hobbiesCell = row.insertCell(7);
let descriptionCell = row.insertCell(8);
let colorCell = row.insertCell(9);
firstNameCell.innerHTML = persons[i].firstName;
lastNameCell.innerHTML = persons[i].lastName;
birthdayCell.innerHTML = persons[i].birthday;
salaryCell.innerHTML = persons[i].salary;
choclatesCell.innerHTML = persons[i].Choclates;
genderCell.innerHTML = persons[i].Gender;
workTypeCell.innerHTML = persons[i].workType;
hobbiesCell.innerHTML = persons[i].Hobbies;
descriptionCell.innerHTML = persons[i].Description;
colorCell.innerHTML = persons[i].favoriteColor;
colorCell.style.backgroundColor = persons[i].favoriteColor;
let h = persons[i].ID;
let removeButton = document.createElement('button');
removeButton.setAttribute('onclick', 'removePerson(' + h + ')')
removeButton.innerHTML = 'Remove';
row.appendChild(removeButton);
}
}
I tried to change the code
removeButton.setAttribute('onclick', 'removePerson(' + h + ')');
to
removeButton.onclick = this.removePerson(h);
but everyTime the "showData()" method runs this method "removePerson()" run also and i don't want this to happen.
removePerson(ID) {
alert(ID);
let table = document.getElementById('editableTable');
if (persons.length === 1) {
table.deleteRow(1);
persons.pop();
localStorage.setItem("personsForms", JSON.stringify(persons));
}
let target;
let i;
for (i = 0; i < persons.length; i++) {
if (persons[i].ID === ID) {
target = persons[i].firstName;
persons.splice(i, 1); break;
}
}
for (i = 1; i < table.rows.length; ++i) {
let x = table.rows[i];
if (x.cells[0].innerHTML === target) {
table.deleteRow(i); break;
}
}
let temp = [];
let j = 0;
for (i = 0; i < persons.length; ++i) {
if (persons[i] !== null) {
temp[j++] = persons[i];
}
}
persons = temp;
localStorage.clear();
localStorage.setItem("personsForms", JSON.stringify(persons));
this.showData();
}

When you set a variable to some value, the value is computed first.
Hence, when you write removeButton.onclick = this.removePerson(h); the right side of the equation is evaluated first.
You can wrap it with a fat-arrow function, so that the function that will be called upon user click would be the function that calls this.removePerson(h). This way its value is a lambda function, and not the actual value of this.removePerson(h):
removeButton.onclick = () => this.removePerson(h);

Related

It always show either one output, either it highlight the keywords or only the alert box,how to achieve both at the same time

//grab all div elements in the pages;
let elt = document.getElementsByTagName("div");
var i;
var b = [];
b[0] = "password";
b[1] = "update";
b[2] = "account";
b[3] = "blocked";
b[4] = "alert";
b[5] = "confirm";
b[6] = "cash";
b[7] = "extra";
b[8] = "subscribe";
b[9] = "sample";
b[10] = "winner";
b[11] = "offer";
b[12] = "promotion";
b[13] = "urgent";
b[14] = "action";
b[15] = "update";
b[16] = "luxury";
b[17] = "limited";
b[18] = "login";
b[19] = "alert";
b[20] = "income";
b[21] = "bonus";
b[22] = "verify";
b[23] = "banking";
b[24] = "lowest";
b[25] = "deal";
b[26] = "unusual log in activity";
function scanDOM() {
//loop for html elements;
for (i = 0; i < elt.length; i++) {
var singleDiv = elt[i];
//loop for keywords;
for (j = 0; j < b.length; j++) {
var str = singleDiv.innerHTML;
if (str.indexOf(b[j]) > -1) {
//if found that the keywords match with the one in array, it will highlight the words;
str = str.replace(b[j], '<span style="background-color:#f6ff00;">' + b[j] + '</span>');
singleDiv.innerHTML = str;
popup();
}
}
}
}
// scan through the pages every 5 seconds;
setInterval(scanDOM, 5000);
//alert message;
function popup() {
alert * ("**WARNING!**");*
}

Javascript Loop Button always takes last value

I have a function that crawls infos from tmdb. i want to work with that response. i do for example search for a movie and want to put the results(titles and the poster-images) into a table with a button.
That works fine.
For that i have a loop that creates a table with entries every loop. In 1 entry i have a button, that is supposed to call another function and give it the value(form the poster-path the movie has) that is set in the specific loop. Works partially...Problem is: the value given to the new fuction is always the last value (value of the last loop). I dont know how to fix that :/
I already tried an "Immediately-Invoked Function Expression"(found in this forum) which looks like this
for (var i = 0; i < 3; i++) {
(function(index) {
console.log('iterator: ' + index);
})(i);
}
Same Problems still :/
thats my script ("bbcode" and "imglink" were set before this)
if (this.status === 200) {
var jsonResponse = JSON.parse(this.responseText);
totalresults = jsonResponse.total_results;
if (totalresults === 0){ noresult(); }
if (totalresults === 1){ oneresult(); }
else {
var x = document.createElement("TABLE");
x.setAttribute("id", "myTable");
x.setAttribute("border", "1");
document.getElementById("log").appendChild(x);
for (var j = 0; j < totaresults; j++) {
(function(i) {
posterpath = jsonResponse.results[i].poster_path;
newbbcode = bbcode.replace(imglink, "http://image.tmdb.org/t/p/w400"+ posterpath);
var y = document.createElement("TR");
y.setAttribute("id", "myTr" + i);
document.getElementById("myTable").appendChild(y);
var z = document.createElement("TD");
var t = document.createTextNode(jsonResponse.results[i].title);
z.appendChild(t);
document.getElementById("myTr" + i).appendChild(z);
var z = document.createElement("TD");
var t = document.createElement("IMG");
t.setAttribute("src", "http://image.tmdb.org/t/p/w92"+jsonResponse.results[i].poster_path);
z.appendChild(t);
document.getElementById("myTr" + i).appendChild(z);
var z = document.createElement("TD");
var t = document.createElement("INPUT");
t.setAttribute("type","button");
t.setAttribute("value","pick this");
t.addEventListener("click", function(){workwithnewbbcode(newbbcode)} );
z.appendChild(t);
document.getElementById("myTr" + i).appendChild(z);
})(j);
}
}
Maybe someone has a very simple (noob friendly^^) idea to do that with javascript.
Thank you guys!
EDIT: Thanks to Jaromanda X for the solution!
instead of
newbbcode = bbcode.replace(imglink, "http://image.tmdb.org/t/p/w400"+ posterpath);
just add var
var newbbcode = bbcode.replace(imglink, "http://image.tmdb.org/t/p/w400"+ posterpath);
OR
if (this.status === 200) {
var jsonResponse = JSON.parse(this.responseText);
totalresults = jsonResponse.total_results;
if (totalresults === 0) {
noresult();
} else if (totalresults === 1) {
oneresult();
} else {
var table = document.createElement("TABLE");
table.id = "myTable";
table.border = "1";
jsonResponse.results.forEach(function(result) {
var posterpath = result.poster_path;
var newbbcode = bbcode.replace(imglink, "http://image.tmdb.org/t/p/w400" + posterpath);
var tr = document.createElement("TR");
var td1 = document.createElement("TD");
td1.appendChild(document.createTextNode(result.title));
tr.appendChild(td1);
var td2 = document.createElement("TD");
var img = document.createElement("IMG");
img.src = "http://image.tmdb.org/t/p/w92" + posterpath;
td2.appendChild(img);
tr.appendChild(td2);
var td3 = document.createElement("TD");
var input = document.createElement("INPUT");
input.type = "button";
input.value ="pick this";
input.addEventListener("click", function() {
workwithnewbbcode(newbbcode);
});
td3.appendChild(input);
tr.appendChild(td3);
table.appendChild(tr);
});
document.getElementById("log").appendChild(table);
}
}
Consider the following example:
for (var i=0;i<10;i++){
setTimeout(function(){
console.log(i);
},1000);
}
You will always get 10 in the output because by the time the nested function is called, the variable i already reached the end of the loop.
In your case, your response object arrives in an XHR callback. This has the same flow as setTimeout. You can create a function wrapper to keep the iterator variable in the call stack:
var myfunc=function(x){ //a function that returns a function
setTimeout(function(){
console.log(x);
},1000);
}
for (var i=0;i<10;i++) myfunc(i);

Names from localstorage into array to random name picker

i am trying to make a random name picker from an array of names taken from localstorage which seems that the error isn't popping up when i inspect it with google chrome.
Here's my code:
function getUserData() {
var Detail = localStorage.getItem("Detail");
if (Detail == null) {
Detail = []; // on new computer, create the local storage item } else {
Detail = JSON.parse(Detail); // convert from string to array
}
for (var i = 0; i < Detail.length; i++) { // loop through the array
var row = document.getElementById("Detail").insertRow(-1);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);
var cell4 = row.insertCell(3);
var cell5 = row.insertCell(4);
cell1.innerHTML = Detail[i].name;
cell2.innerHTML = Detail[i].admin;
cell3.innerHTML = Detail[i].email;
cell4.innerHTML = Detail[i].contact;
cell5.innerHTML = Detail[i].country;
}
}
function NamePicker() {
var Detail = localStorage.getItem("Detail");
if (Detail == null) {
Detail = []; // on new computer, create the local storage item
} else {
Detail = JSON.parse(Detail); // convert from string to array
}
// copy names
var nameArray = [];
for (var i = 0; i < Detail.length; i++) { // loop through the array
nameArray[i] = Detail[i].name;
}
for (var i = 0; i < Detail.length; i++) { // loop through the array
// get a number from random num generator %numArray.length
name = nameArray[num];
while (nameArray.length < 11) {
var randomnumber = Math.max(Math.ceil(Math.random() * 11))
var found = false;
for (var i = 0; i < nameArray.length; i++) {
if (name[i] == randomnumber) {
found = true;
break
}
}
if (!found) name[nameArray.length] = randomnumber;
}
// Display using modal
alert(name);
// remove using splice(num, 1);
name.splice(num, 1);
document.getElementById("Detail").innerHTML = name;
}
}
the problem is that it seems that num isn't removing the name from the list and alert function isn't popping up...
i really appreciate the help thanks in advance...
I found a couple of problems in you second function; you are using the local variable i in three for loops, and I think in one of them you meant to use num. Also, I changed Detail.length to nameArray.length in the second for loop since you are going through the nameArray. I also change the third for loop to use z instead of i.
function NamePicker() {
var Detail = localStorage.getItem("Detail");
if (Detail == null) {
Detail = []; // on new computer, create the local storage item
} else {
Detail = JSON.parse(Detail); // convert from string to array
}
// copy names
var nameArray = [];
for (var i = 0; i < Detail.length; i++) { // loop through the array
nameArray[i] = Detail[i].name;
}
for (var num = 0; num < nameArray.length; num++) { // loop through the array
// get a number from random num generator %numArray.length
name = nameArray[num];
while (nameArray.length < 11) {
var randomnumber = Math.max(Math.ceil(Math.random() * 11))
var found = false;
for (var z = 0; z < nameArray.length; z++) {
if (name[z] == randomnumber) {
found = true;
break
}
}
if (!found) name[nameArray.length] = randomnumber;
}
// Display using modal
alert(name);
// remove using splice(num, 1);
name.splice(num, 1);
document.getElementById("Detail").innerHTML = name;
}
}
Hope that helps!

Search and match CSV file values with javascript

I've uploaded a CSV-file to an HTML page via javascript. The CSV rows are: name and email-address, e.g. rambo,rambo#rambo.com.
How to SEARCH the 'name' from these loaded CSV-file?
Also, one of the data is an email-address and I want to send a mail to that email-address. Is that value retrieved to a variable?
My code to search each elements:
function Search() {
var fileUpload = document.getElementById("fileUpload");
var regex = /^([a-zA-Z0-9\s_\\.\-:])+(.csv|.txt)$/;
if (regex.test(fileUpload.value.toLowerCase())) {
if (typeof (FileReader) != "undefined") {
var reader = new FileReader();
reader.onload = function (e) {
var table = document.createElement("table");
var rows = e.target.result.split("\n");
for(var i = 0; i < rows.length; i++)
{
var row = table.insertRow(-1);
var cells = rows[i].split(",");
for(var j = 0; j < cells.length; j++)
{
var cell = row.insertCell(-1);
// cell.innerHTML = cells[j];
// Here repeated checkboxes:
var radio = document.createElement('input');
radio.type = 'checkbox';
radio.name = 'check';
}
var ser=document.getElementById("texts");
if(cells[i].indexOf(ser))
{
alert("matches");
cell.innerHTML = cells[i];
}
else
{
alert("unmatches");
}
var cell = row.insertCell(-1);
cell.appendChild(radio);
//cell.appendChild(button);
}
var button = document.createElement('button');
button.textContent = 'Send';
cell.appendChild(button);
button.onclick = function(){ alert();};
var dvCSV = document.getElementById("dvCSV");
dvCSV.innerHTML = "";
dvCSV.appendChild(table);
}
reader.readAsText(fileUpload.files[0]);
}
}
}
Ad search: indexOf() is your friend here. This should give you a figure:
var table = $('#your-table'),
searchstring = 'your-searchstring';
searchstring.toLowerCase();
for (var i = 0, cell; cell = table.cells[i]; i++) {
if (cell.indexOf(searchstring)) {
// I don't know what you want to do with the search-results...
// ..but you can do it here.
}
}
Ad email-address: you can add the address to a variable in your CSV-import:
var cells = rows[i].split(","),
address = cells[1];
I'd suggest making an array addresses and fill it each row.

TypeError: tableObj.appendChild is not a function

var oTable;
$(document).ready(function() {
loadSubMenus();
});
function loadSubMenus() {
var resultStringX = $.ajax({
type : "POST",
url : "getSubMenuList",
dataType : 'text',
async : false
}).responseText;
resultStringX = $.trim(resultStringX);
var o = JSON.parse(resultStringX);
var idArray = new Array();
var nameArray = new Array();
idArray = o.result.subMenuId;
nameArray = o.result.subMenuName;
var tableObj = $("#tableId").val();
var colCount = 0;
var trObj = document.createElement("tr");
for (var i = 0; i < idArray.length; i++) {
var tdObj = document.createElement("td");
var inputElem = document.createElement("input");
inputElem.type = "checkbox";
inputElem.setAttribute("id", "id_"+i);
inputElem.setAttribute("value", idArray[i]);
inputElem.style.marginTop = "-1px";
var spanObj = document.createElement("span");
spanObj.innerHTML = nameArray[i];
tdObj.appendChild(inputElem);
tdObj.appendChild(spanObj);
trObj.appendChild(tdObj);
colCount++;
if (colCount == 5) {
tableObj.appendChild(trObj);
trObj = "";
trObj = document.createElement("tr");
colCount = 0;
}
if (idArray.length < 5) {
if ((idArray.length - 1) == i) {
tableObj.appendChild(trObj);
}
}
}
if(idArray.length/5>0){
tableObj.appendChild(trObj);
}
document.getElementById("subMenuCount").value=idArray.length;
}
am not getting output..
i want to load menu n sub-menu from the database
what is error am nt able to get pls help me
how to solve this.
what i have to do..
what is the error
in another jsp page i created "tableid" so there i defined td
tableObj is not a DOM element. It is the value of $("#tableId").val(). Probably you need to create it also as a DOM element:
var tableObj = document.createElement("table");
...

Categories