Cannot pass array parameter (building out html with string) - Unexpected identifier - javascript

I have modified my previous code to allow for a data array to be passed to a different function. Everything is working until I add this data array.
Currently what works (old version) is only passing the this operator and an ID.
Below in my code you will see that I build out the HTML along with a table and pass the html to be appended at a later time.
You can see that I am building a table with a delete button. It all works well, except now that I am passing the data array it is telling me "Unexpected identifier"
I have tested it with passing getDeleteItems(this,ID,ID) and it works fine
but getDeleteItems(this,ID,data) does not.
Below is my code, and you can see I am passing an array (that works throughout my code and other functions (including this one already!))
I am just stuck now and can't seem to see past this, maybe some fresh eyes can help!
Thanks!
function mouseOverTable(ID,parent,data)
{
// ID is in the first column (0)
// Type is in the second column (1)
// Title is in the third column (2)
// popup_ItemClicked()
var family = findFamily(ID,parent,data)
var sHTML = "";
sHTML += "<table class="+"table table-hover id='relationshipTable'"+">";
sHTML += "<thead>";
sHTML += "<tr>";
sHTML += "<th>"+"Select Item"+"</th>";
sHTML += "<th>"+"ID"+"</th>";
sHTML += "<th>"+"Content Name"+"</th>";
sHTML += "<th>"+"Type"+"</th>";
sHTML += "<th>"+"Status"+"</th>";
sHTML += "<th>"+"Date"+"</th>";
sHTML += "</tr>";
sHTML += "</thead>";
sHTML += "<tbody>";
//displays if it's a article.. blog ... etc..
for(var i = 0; i<family.length;i++)
{
sHTML += "<tr id='relationshipRow"+family[i].ID+"'>";
sHTML += "<td><input type = 'checkbox' value = '"+family[i].ID+"'></input></td>";
sHTML += "<td>"+family[i].ID+"</td>";
sHTML += "<td>"+family[i].Title+"</td>";
//shows the date that the contentitem was created
sHTML += "<td>" + family[i].Type +"</td>";
sHTML += "<td>" + family[i].Status +"</td>";
sHTML += "<td>" + (family[i].Date) +"</td>";
sHTML += "</tr>";
}
sHTML += "</tbody>";
sHTML += "</table>";
//console.log(data)
sHTML += "<input type = 'Button' id ='DeleteItems' value = 'Delete Selected' onclick='javascript: getDeleteItems(this,";
sHTML += ID;
sHTML += ",";
sHTML += data;
sHTML += ");'></input>";
return sHTML;
}
I just looked at console and the element tabs in chrome: it looks like for some reason it is parsing the object as such
onclick="javascript: getDeleteItems(this,791,[object Object],[object Object],[object Object],.... and this goes on...

Your error in the onclick="javascript: getDeleteItems
the third parameter expected to be an array you missed {} for the array objects.
So you must call getDeleteItems function like this
onclick="javascript: getDeleteItems(this,791,{[object Object],[object Object],[object Object]})"

As #Fatehi mentioned, the following lines are giving the error
sHTML += "<input type = 'Button' id ='DeleteItems' value = 'Delete Selected' onclick='javascript: getDeleteItems(this,";
sHTML += ID;
sHTML += ",";
sHTML += data;
sHTML += ");'></input>";
I believe that adding the curly braces wont fix your issue since that data variable is a parameter of the function and his value it's not global and the scope when you send it to the DOM is for global variables. You should better use data attributes for each value and then you could access them like this:
<input data-test="test" onclick="console.log(this.attributes['data-test'].value)">

So I figured out this puzzle. I had the following functions 1) that called mouseover, the mouseover function, then the delete function. Before I was creating a delete button in mouseover(and I still am). However I made mouseover return 2 items now, one that returns the html for the table and the other that returns a tableid. I also removed the findfamily function in mouseover and moved it up to where it was being called from, then passed that as the data.
functionThatCalledMouseOver(ID,parent,data){
// below have variables defining row family =findparent etc...
row.child(mouseOverTable(ID,parent,findParent)[0]).show();
//now create onclick even passing fullData
$('#'+DeleteItems).on('click',function(){
getDeleteItems(this,ID,data);
});
}
My ultimate goal was the following: I had some sharepoint list items I was deleting from a table. Usually when I create charts tables etc, I will do a call and store all data locally in an array. The array is what created the table I was making. So in theory after the table data is deleted from sharepoint, it is still in my local array.
The problem with this was that when I removed the elements (visually showing they were deleted), it I hid the children of the parent in the main table I created, then clicked to show it again, it would show the deleted items since it was not server information and just a local array.
For future people reading this, I tried my original method with turning the object into a JSON string, then using the escape function. So... escape(JSON.stringify(data)).. this got passed to the delete function. This does work for appearances only. Once decoded on the getDeleteItems function it is separate data from the original data I was trying to delete. So in my case this wouldn't work.
however, moving everything to the function that originally called the mouseover was the way to go. It allowed me to get to the object I needed to remove items from.

Related

Why can't I add to innerHTML? [duplicate]

document.getElementById("outputDiv").innerHTML = "";
document.getElementById("outputDiv").innerHTML += "<table border=1 width=100%><tr>";
for(j=1;j<=10;j++)
{
document.getElementById("outputDiv").innerHTML += "<td align=center>"+String.fromCharCode(j+64)+"</td>";
}
document.getElementById("outputDiv").innerHTML += "</tr></table>";
I want to draw a table using Javascript.
So I wrote the code like above.
I think it draw one row that has 10 columns, but it doesn't work.
Anyone know about this problem???
I ran into this problem years ago, too.
The problem is that when you use the innerHTML property to add HTML, after each update, the underlying engine will close unclosed tag (and fix other bad HTML) for you. So after the second line, the <table> and <tr> tags are automatically closed and all content after that will just be written outside the table.
Method 1
(The easy way)
Use a string to store the HTML for the whole table and update it all at once.
var HTML = "<table border=1 width=100%><tr>";
for(j=1;j<=10;j++)
{
HTML += "<td align=center>"+String.fromCharCode(j+64)+"</td>";
}
HTML += "</tr></table>";
document.getElementById("outputDiv").innerHTML = HTML;
​
Fiddle
Method 2
(The better way)
Use DOM functions
var table = document.createElement('table');
table.setAttribute('border','1');
table.setAttribute('width','100%')
var row = table.insertRow(0);
for(j=1; j<=10; j++){
var text = document.createTextNode(String.fromCharCode(j+64));
var cell = row.insertCell(j-1);
cell.setAttribute('align','center')
cell.appendChild(text);
}
document.getElementById("outputDiv").appendChild(table);
Fiddle
Method 2 enhanced
(The yet better way)
Use CSS instead of HTML attributes. The latter is generally depreciated as of latest specs.
A great resource to start learning CSS is the Mozilla Developer Network
Fiddle
Method 3
(The long way, but the best in the long-run)
Use jQuery.
$('<table>').append('<tr>').appendTo('#outputDiv');
for(j=1; j<=10; j++)
$('<td>').text(String.fromCharCode(j+64)).appendTo('tr');
Fiddle
I think the main problem is that your attributes are not quoted.
But it's almost always a bad idea to repeatedly update the content of a dom element in a loop—each time you update dom content it causes some internal work to be done by the browser to make sure the page layout is current.
I would build the html string up locally, then make one final update when done. (and of course make sure your attributes are quoted)
document.getElementById("outputDiv").innerHTML = "";
var newTable = "<table border='1' width='100%'><tr>";
for(j = 1; j <= 10; j++) { //opening braces should always be on the same line in JS
newTable += "<td align='center'>" + String.fromCharCode(j+64) + "</td>";
}
newTable += "</tr></table>";
document.getElementById("outputDiv").innerHTML = newTable;

Javascript autocloses HTML tags?

Why do these two functions give different results?
var table1 = document.getElementById("table1");
var table2 = document.getElementById("table2");
var register = [
{att1: 1, att2: 2, att3: 3},
{att1: 4, att2: 5, att3: 6},
{att1: 7, att2: 8, att3: 9}
];
//table1.innerHTML = "";
//table2.innerHTML = "";
function drawTable1() {
for (var i = 0; i < register.length; i++) {
table1.innerHTML += "<tr><td>" + register[i].att1 + "</td><td>" + register[i].att2 + "</td><td>" + register[i].att3 + "</td></tr>";
}
}
function drawTable2() {
for (var i = 0; i < register.length; i++) {
table2.innerHTML += "<tr>";
table2.innerHTML += "<td>" + register[i].att1 + "</td>";
table2.innerHTML += "<td>" + register[i].att2 + "</td>";
table2.innerHTML += "<td>" + register[i].att3 + "</td>";
table2.innerHTML += "</tr>";
}
}
drawTable1();
drawTable2();
table {
display: inline;
}
<body>
<table>
<thead>
<tr>
<th>Att1</th>
<th>Att2</th>
<th>Att3</th>
</tr>
</thead>
<tbody id="table1">
</tbody>
</table>
<table>
<thead>
<tr>
<th>Att1</th>
<th>Att2</th>
<th>Att3</th>
</tr>
</thead>
<tbody id="table2">
</tbody>
</table>
</body>
I'm just beginning with js, and I've noticed this thing. From a logical point of view i see no differences between the two functions, the second has just been broken up to make the code easier to read. It should simply be adding strings to a string, but it seems like at every operation the opened tags get closed by the program, resulting in a multitude of rows.
Why is this? How is this useful?
innerHTML isn't actually a string. It's an interface to the DOM (the elements on the page); reading from it generates a string version of what's currently there, and assigning a value to it modifies the tree.
It's impossible to have an unclosed <tr> element in the DOM -- when you perform an operation like table1.innerHTML += "<tr>", the browser sees the unclosed <tr> tag as invalid HTML and has to repair it by inserting a closing </tr>. When you later access innerHTML to perform another modification, you see the "repaired" version, not the value you initially assigned.
The easiest fix will be to build the entire table as a string, then assign to innerHTML all at once, e.g.
var html = "";
for (...) {
html += "<tr>";
html += "<td>example</td>";
html += "</tr>";
}
table1.innerHTML = html;
You may also want to investigate Javascript DOM methods to create HTML elements (like document.createElement()) as an alternative -- innerHTML is a clumsy interface.
Well the innerHTML content is — as the name implies — HTML and HTML is not just a string. I assume you know that browsers build a DOM out of it. Basically a tree out of nodes that know their tag, attributes, children etc.
Now you need this DOM to render anything. Sure, it is nearly impossible to get invalid html as non-html can just be interpreted as a mere string (which is valid html). However, the browser tries to fullfill the html standard as much as possible. Therefore it also generates missing end tags in order to produce well-formed html. (even when it is not in the html, he will implicitely generate them for the DOM and in some browsers you can see that in the HTML provided in the dev console).
So now you add a random <tr> attribute to your html like this table2.innerHTML += "<tr>". This would produce not-well-formed html. Therefore it should generate the missing end tag. Whether that is done while running the js-code or afterwards when refreshing the DOM, I don't know, but generally it helps generate well-formed HTML.
I'm sure you know how to circumvent that problem, but anyways: Instead of using an temporary string, you might want to look at document.createElement(). This is generally used to generate well-formed html in a non-confusing and safe (as in "something unexpected like above doesn't happen safe") way.

Why does the array repeat the entered data from first to last

I'm having trouble with my code. I build this code but there is an issue that I cannot resolve myself. The code should work like this: When entering multiple data (name & email) the datas repeat from top to last.
For example I enter 3 names & emails one by one. I want an output of
Fred fred#gmail.com
George george#gmail.com
Laila laila#gmail.com
But instead I get this results in my table:
Fred fred#gmail.com
Fred fred#gmail.com
George George#gmail.com
Fred fred#gmail.com
George George#gmail.com
Laila laila#gmail.com
In the clearAndSave method in the end when you call $("#output").append(html); you should call $("#output").empty(); first to clear the previous results.
Change the method like this:
function clearAndSave() {
//...
$("#output").empty();
$("#output").append(html);
}
If you want to presist your initial data, modify the clearAndSave method like this:
function clearAndSave() {
// Clear fields
nameInput.value = "";
emailInput.value = "";
var html = [];
console.log(arraypeaople);
for(i = 0; x <= arraypeaople.length - 1; i++){
// Mark added rows to be able to remove them later
html += "<tr class='added-row'>";
html += "<td>" + arraypeaople[i].name + "</td>";
html += "<td>" + arraypeaople[i].email + "</td>";
html += "</tr>";
}
// Remove just the added rows
$("#output").find(".added-row").remove();
$("#output").append(html);
}

Call a javascript function from anchor tag inside td inside javascript code

Only Basic javascript knowledge is required.If anyone knows please help me.
I don't know how to do it but i have tried it in many ways but still not able to pass the value.
Simply, i have a for loop and i have a td inside it. I want to call a javascript function from this td click but problem is i am unable to pass any parameter to this function.
the code is here :
function GetContractList(abc) {
var data = abc
for (var it in data) {
tab += "<tr>";
tab += "<td>" + data[it].ContractCode + "</td>";
if (data[it].ContractCode != "") {
var Contract = data[it].ContractCode;
tab += "<td><a onclick='Delete_User(Contract);'>View</td>";
// tab += "<td><a data=" + data[it].ContractCode + " href='javascript:Delete_User(this.data);'>View</td>";
}
else {
tab += "<td></td>";
}
As u can see, i have tried to pass parameter to Delete_User function but the syntax is somewhere broken.
tab += "<td><a onclick='Delete_User(Contract);'>View</td>";
this line gives error-- Contract is not defined.
"<td><a data=" + data[it].ContractCode + " href='javascript:Delete_User(this.data);'>View</td>".
This line also doesnot passes any value to the function.
Please someone help me out.
try:
var cont = data[it].ContractCode.replace(/"/g, '\\"');
tab += '<td><a onclick="Delete_User(\''+cont+'\');">View</td>";
first line encodes any double quotes
the second line inserts the contract as a parameter and adds single quotes around it
You need to escape the quote for the parameter of the function.
tab += '<td>View</td>';
// ^^ ^^
function Delete_User(id) {
console.log('Delete_User', id);
}
var cc = '4711abc',
tab = 'View';
document.write(tab);

Why can I not dynamically draw my table? How can I draw the table?

Readers,
Background:
I have an html page with a submit button on it. This button, when clicked goes to the servlet and fetches the first 10 rows of data from my database. I then get this data back to my javascript via an ajax call. That all works. I can see the data in json format in my javascript.
Problem:
After the data is returned, it goes to a method called generate the table. But the table never shows on my html page. I tried to follow this demo approach. How can I draw a table after this method is being called? The <p></p> approach in the demo didn't work in the link I provided either.
function createTable(result)
{
var length = result.jsonList.length;
var tablecontents = "";
console.log(length);
tablecontents="<table>";
for(var i = 0; i < length; i++)
{
tablecontents += "<tr>"
tablecontents += "<td>" + result.jsonList[i].Id + "</td>"
tablecontents += "</tr>"
console.log(result.jsonList[i].Id);
}
tablecontents="</table>";
document.getElementById("tablespace").innerHTML = tablecontents;
}
Okay, so the console.log part gives me the following output:
1
2
3
4
5
6
7
8
9
10
So I have the data. However, no database is being drawn on my htmlpage. Here is the relevant HTML code:
<body>
<form id = "submitTable" method="post">
<center><input id="getTable" type="button" value="Table"></center>
<div id="tablespace"></div>
</form>
</body>
I point out the button calls the ajax. There is no need to show you my ajax call because that works. It calls my createTable function when it gets the data back from the servlet. I know it is working because I can print the unique database id's with the console.log. However, the
document.getElementById("tablespace").innerHTML = tablecontents
is not working? Stranger is that when I run and view source on chrome. I see no error with the html. So I don't know what I am doing wrong?
tablecontents+="</table>" inplace of tablecontents="</table>"
Here's the problem:
tablecontents="</table>";
document.getElementById("tablespace").innerHTML = tablecontents;
You set "tablecontents" to be only the </table> tag. Should be:
tablecontents += "</table>"; // += not =
document.getElementById("tablespace").innerHTML = tablecontents;

Categories