2

I've built some ajax that is returning part of a product catalog, and I'm trying to output the xml to the document, and so far, here is what I have:

    $("#catalog").append("<table><tr><th></th><th>Item Name</th><th>Price</th><th>Description</th></tr>");
    $(data).find("item").each(function() {
        $("#catalog").append("<tr>"+
            "<td style='valign:top'><img src='"+$(this).find("["link").text()+"' /></td>"+
            "<td>"+$(this).find("title").text()+"</td>"+
            "<td>"+$(this).find("price").text()+"</td>"+
            "<td style='valign:top'>"+$(this).find("description").text()+"</td>"+
            "</tr>"
        );
    });
    $("#catalog").append("</table>");

I would expect this to write the table's start to the document, then each of the data rows, and finally the </table> at the end. Instead, when I view source on the page I get this...

<div id="catalog">
    <table>
        <tr>
            <th></th>
            <th>Item Name</th>
            <th>Price</th>
            <th>Description</th>
        </tr>
    </table>
    <tr>
        <td style="valign:top"><img src="http://image1.jpg"></td>
        <td>Item1</td>
        <td>Price1</td>
        <td style="valign:top">Description1</td>
    </tr>
    <tr>
        <td style="valign:top"><img src="http://image2.jpg"></td>
        <td>Item2</td>
        <td>Price2</td>
        <td style="valign:top">Description2</td>
    </tr>
    <tr>
        <td style="valign:top"><img src="http://image3.jpg"></td>
        <td>Item3</td>
        <td>Price3</td>
        <td style="valign:top">Description3</td>
    </tr>
</div>

Note how the data is being added after the end of the table even though the .append("</table>") line is AFTER the .each().

This leads me to believe that code is not being executed in order, and that the .each() function is demonstating some concurrency. This confuses me as the jquery api doesn't mention callbacks, so I find myself at a bit of a loss as to what exactly is happening and what I should do to get this to display properly. Any help would be much appreciated.

2 Answers 2

5

change

$(data).find("item").each(function() {
    $("#catalog").append(...

to

$(data).find("item").each(function() {
    $("#catalog table").append(...

No concurrency issue, you are appending the rows to the parent div and not the table.

Another Note: You don't need to append that last table, just put it in your initial append,

$("#catalog").append("<table><tr><th></th><th>Item Name</th><th>Price</th><th>Description</th></tr></table>");
Sign up to request clarification or add additional context in comments.

3 Comments

He means change it in the function passed to each(), not the first one
This is working superbly, but I'm still trying to make sure I understand exactly what is going on, so tell me if this sounds right (or close enough to it). When I run $("#catalog").append("&lt;table&gt;") it adds the opening to tag to the catalog div. The browser then sees an open tag without a close, and adds the closing tag. This causes further calls to $("#catalog").append() to put that under the end of the table. The table closing tag added at the end is finally discarded by the browser as being extraneous. In php, I built html top down, but in js I need to build it from the outside in?
@Mike Correct ish, in php, you are creating a string that is being sent to the browser, however when working with the DOM, you are manipulating Objects, so when adding a table, a table object gets created, then a table row is added to it as a child and so on.
0

Here is the cleaner way to do it> I am assuming the "link, title, price and description" are classes which you have used in the find selector.

var markUp = [];
markup.push("<table><tr><th></th><th>Item Name</th><th>Price</th><th>Description</th></tr>");
var $this;
    $(data).find("item").each(function() {
        $this = $(this);
         markup.push("<tr>");
         markup.push("<td style='valign:top'><img src='"+$this.find(".link").text()+"' /></td>");
            markup.push("<td>"+$this.find(".title").text()+"</td>");
            markup.push("<td>"+$this.find(".price").text()+"</td>";
            markup.push("<td style='valign:top'>"+$this.find(".description").text()+"</td>");
            markup.push("</tr>");
    });
markup.push("</table>");

    $("#catalog").append(markup.join(''));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.