Isaac
asked on
TR appendChid() rendering problem
I have the following piece of code that is needed to build and add rows under the right headings in an html table.
It needs to look like this
but it looks like this
var mileStoneHtml="";
var typeArray = [];
var headingName = "";
for(var i =0; i < data.d.results.length; i++)
{
headingName = data.d.results[i].Milestone_x0020_Type;
if (typeArray.indexOf(headingName) === -1){
typeArray.push(headingName);
tableRow = document.createElement("tr");
tableRow.id=headingName;
tableRow.style.backgroundColor = "#EEEEEE";
tableCol = document.createElement("td");
tableCol.colSpan = 5;
tableCol.textContent = headingName;
tableRow.appendChild(tableCol);
console.log(tableRow);
tbl = document.getElementById("tblMilestone");
console.log(tbl);
console.dir(tbl);
tbl.appendChild(tableRow);
}
mileStoneHtml = "<tr>"+
"<td>"+data.d.results[i].MilestoneDescription+"</td>"+
"<td>"+data.d.results[i].Planned_x0020_Date+"</td>"+
"<td>"+data.d.results[i].Revised_x0020_Date+"</td>"+
"<td>"+data.d.results[i].Actual_x0020_Date+"</td>"+
"<td>"+data.d.results[i].Milestone_x0020_Type+"</td>"+
"</tr>";
var newRow = $("#"+headingName).append(mileStoneHtml);
console.log(newRow);
// document.querySelector("#tblMilestone").appendChild(mileStoneHtml);
}
It needs to look like this
but it looks like this
ASKER
That's great Julian. Thanks but I had to forego using handlebars because when I moved it from my personal site to the clients test environment, it worked until I added handlebar helper functions. It gave me the following error:
SCRIPT5022: Error: Missing helper: "formatHtml"
formatHtml is a function used to no escape html so it can render my data as html.
I also have one for 'formatDate' as well and the same error would show for that too.
Here are my helpers that I added to my code in include files.
Here's the error I see through the deveoloper tool. It points to a line in handlebars.
Here's how I use formatHtml
On my site, I was using ie 10 and it worked even though the error still showed. My client uses ie 11, so I'm not sure if that is the reason.
So, I had to redo the code without handlebars and that's why I created this question to add a table row. If you know of a solution to fix the handlebars error, that would be great. I would rather use that solution since it's 95% done.
Thanks!
SCRIPT5022: Error: Missing helper: "formatHtml"
formatHtml is a function used to no escape html so it can render my data as html.
I also have one for 'formatDate' as well and the same error would show for that too.
Here are my helpers that I added to my code in include files.
Handlebars.registerHelper("formatHtml", function(property) {
return new Handlebars.SafeString(property);
});
Handlebars.registerHelper("formatDate", function(property) {
return moment(property).format("L");
});
Here's the error I see through the deveoloper tool. It points to a line in handlebars.
Here's how I use formatHtml
<tr>
<td><b>Project Scope:</b></td><td> {{formatHtml Project_x0020_Scope}} </td>
</tr>
On my site, I was using ie 10 and it worked even though the error still showed. My client uses ie 11, so I'm not sure if that is the reason.
So, I had to redo the code without handlebars and that's why I created this question to add a table row. If you know of a solution to fix the handlebars error, that would be great. I would rather use that solution since it's 95% done.
Thanks!
try simplified version
var mileStoneHtml="";
var typeArray = [];
var headingName = "";
for(var i =0; i < data.d.results.length; i++)
{
headingName = data.d.results[i].Milestone_x0020_Type;
if (typeArray.indexOf(headingName) === -1){
typeArray.push(headingName);
mileStoneHeadHtml = "<tr><td colspan='5' id='" + headingName + "'>" + headingName + "</td></tr>"
$("#tblMilestone").append(mileStoneHtml);
}
mileStoneHtml = "<tr>"+
"<td>"+data.d.results[i].MilestoneDescription+"</td>"+
"<td>"+data.d.results[i].Planned_x0020_Date+"</td>"+
"<td>"+data.d.results[i].Revised_x0020_Date+"</td>"+
"<td>"+data.d.results[i].Actual_x0020_Date+"</td>"+
"<td>"+data.d.results[i].Milestone_x0020_Type+"</td>"+
"</tr>";
$("#tblMilestone").append(mileStoneHtml);
}
and if you will not use those rows later, you dont need to put id to those sections... Line 12 I mean...
ASKER
Your code added the 1 row and left out the heading
ASKER
Correction. All three rows showed but not the headings as in the image in my initial questions. sorry about that
did you check my simplified version ID: 42190774?
ASKER
That's what I'm using
function complete(data) {
var mileStoneHtml="";
var typeArray = [];
var headingName = "";
for(var i =0; i < data.d.results.length; i++)
{
headingName = data.d.results[i].Milestone_x0020_Type;
if (typeArray.indexOf(headingName) === -1){
typeArray.push(headingName);
mileStoneHeadHtml = "<tr><td colspan='5' id='" + headingName + "' style='background-color:#eeeeee'>" + headingName + "</td></tr>";
console.dir(mileStoneHeadHtml);
$("#tblMilestone").append(mileStoneHtml);
/*tableRow = document.createElement("tr");
tableRow.id=headingName;
tableRow.style.backgroundColor = "#EEEEEE";
tableCol = document.createElement("td");
tableCol.colSpan = 5;
tableCol.textContent = headingName;
tableRow.appendChild(tableCol);
console.log(tableRow);
tbl = document.getElementById("tblMilestone");
console.log(tbl);
console.dir(tbl);
tbl.appendChild(tableRow);*/
}
mileStoneHtml = "<tr>"+
"<td>"+data.d.results[i].MilestoneDescription+"</td>"+
"<td>"+data.d.results[i].Planned_x0020_Date+"</td>"+
"<td>"+data.d.results[i].Revised_x0020_Date+"</td>"+
"<td>"+data.d.results[i].Actual_x0020_Date+"</td>"+
"<td>"+data.d.results[i].Milestone_x0020_Type+"</td>"+
"</tr>";
$("#tblMilestone").append(mileStoneHtml);// document.querySelector("#tblMilestone").appendChild(mileStoneHtml);
}
}
sorry you should use
tbody
$("#tblMilestone").append( mileStoneH tml);
>>>
$("#tblMilestone tbody").append(mileStoneHt ml);
tbody
$("#tblMilestone").append(
>>>
$("#tblMilestone tbody").append(mileStoneHt
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
That didn't work.
function complete(data) {
var mileStoneHtml="";
var typeArray = [];
var headingName = "";
for(var i =0; i < data.d.results.length; i++)
{
headingName = data.d.results[i].Milestone_x0020_Type;
if (typeArray.indexOf(headingName) === -1){
typeArray.push(headingName);
mileStoneHeadHtml = "<tr><td colspan='5' id='" + headingName + "' style='background-color:#eeeeee'>" + headingName + "</td></tr>";
console.dir(mileStoneHeadHtml);
$("#tblMilestone tbody").append(mileStoneHtml);
/*tableRow = document.createElement("tr");
tableRow.id=headingName;
tableRow.style.backgroundColor = "#EEEEEE";
tableCol = document.createElement("td");
tableCol.colSpan = 5;
tableCol.textContent = headingName;
tableRow.appendChild(tableCol);
console.log(tableRow);
tbl = document.getElementById("tblMilestone");
console.log(tbl);
console.dir(tbl);
tbl.appendChild(tableRow);*/
}
mileStoneHtml = "<tr>"+
"<td>"+data.d.results[i].MilestoneDescription+"</td>"+
"<td>"+data.d.results[i].Planned_x0020_Date+"</td>"+
"<td>"+data.d.results[i].Revised_x0020_Date+"</td>"+
"<td>"+data.d.results[i].Actual_x0020_Date+"</td>"+
"<td>"+data.d.results[i].Milestone_x0020_Type+"</td>"+
"</tr>";
$("#tblMilestone tbody").append(mileStoneHtml);// document.querySelector("#tblMilestone").appendChild(mileStoneHtml);
}
}
ASKER
ASKER
It worked! Thanks!
It was mileStoneHeadHtml and not mileStoneHtml
It was mileStoneHeadHtml and not mileStoneHtml
So, I had to redo the code without handlebars and that's why I created this question to add a table row.I am very confused - I gave you a working sample that does exactly what you want without handlebars which is much simpler than the accepted version.
@Julian
Accepted answer is actually ID: 42190774 + ID: 42190790 + ID: 42190815
same method is used to add header and detail rows, ie
see demo https://jsfiddle.net/fvkpex5h/
Accepted answer is actually ID: 42190774 + ID: 42190790 + ID: 42190815
same method is used to add header and detail rows, ie
...
if (typeArray.indexOf(headingName) === -1){
mileStoneHeadHtml = "...";
$("#tblMilestone tbody").append(mileStoneHeadHtml);
}
mileStoneHtml = "...";
$("#tblMilestone tbody").append(mileStoneHtml);
see demo https://jsfiddle.net/fvkpex5h/
ASKER
@Julian,
My apologies. I thought you were referring back to my handlebars question when you said "'Here is a slightly different take on this building on your earlier question". That's my misunderstanding.
My apologies. I thought you were referring back to my handlebars question when you said "'Here is a slightly different take on this building on your earlier question". That's my misunderstanding.
Yes I was referring to the solution I offered you in that question - but updated it to the new requirements.
The sample I posted was a modification from handle bars to normal JavaScript and makes use of the insertRow() and insertCell() methods to create the new row.
The accepted solution will work - but is not optimal in my view.
The sample I posted was a modification from handle bars to normal JavaScript and makes use of the insertRow() and insertCell() methods to create the new row.
The accepted solution will work - but is not optimal in my view.
@Huseyin,
42190667 was posted first, was correct according to requirements and made use of correct JavaScript methods for adding cells and rows.
42190667 was posted first, was correct according to requirements and made use of correct JavaScript methods for adding cells and rows.
@Julian
he is already using
and no need to use any other method for headers...
Thats why I wiped out all those tiny commands and used the same jQuery method for divisions as well...
and optimal means what? slow? who cares, we are not dealing with millions of operations here, just a few...
and it is not noticeable even if you write the most inefficient code here...
he is already using
$("#tblMilestone").append(mileStoneHtml);
and no need to use any other method for headers...
Thats why I wiped out all those tiny commands and used the same jQuery method for divisions as well...
and optimal means what? slow? who cares, we are not dealing with millions of operations here, just a few...
and it is not noticeable even if you write the most inefficient code here...
like the discussion between
vs using string concat vs stringbuilder in .net!
I made a demo of this for millions of operations and difference is not noticeable :)
so, simple is the best... as I always say...
and I found a demo, results saying even classical way is better :)
vs using string concat vs stringbuilder in .net!
I made a demo of this for millions of operations and difference is not noticeable :)
so, simple is the best... as I always say...
and I found a demo, results saying even classical way is better :)
using System;
using System.Diagnostics;
using System.Text;
class Test
{
static readonly string[] Bits = {
"small string",
"string which is a bit longer",
"stirng which is longer again to force yet another copy with any luck"
};
static readonly int ExpectedLength = string.Join("", Bits).Length;
static void Main()
{
Time(StringBuilderTest);
Time(ConcatenateTest);
}
static void Time(Action action)
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
// Make sure it's JITted
action();
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < 10000000; i++)
{
action();
}
sw.Stop();
Console.WriteLine("{0}: {1} millis", action.Method.Name,
(long) sw.Elapsed.TotalMilliseconds);
}
static void ConcatenateTest()
{
string x = "";
foreach (string bit in Bits)
{
x += bit;
}
// Force a validation to prevent dodgy optimizations
if (x.Length != ExpectedLength)
{
throw new Exception("Eek!");
}
}
static void StringBuilderTest()
{
StringBuilder builder = new StringBuilder();
foreach (string bit in Bits)
{
builder.Append(bit);
}
string x = builder.ToString();
// Force a validation to prevent dodgy optimizations
if (x.Length != ExpectedLength)
{
throw new Exception("Eek!");
}
}
}
StringBuilderTest: 2245 millis
ConcatenateTest: 989 millis
who cares, we are not dealing with millions of operations here, just a few...Not much one can say to that really
Open in new window
Working sample here