Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Page 1 of 2 12 LastLast
Results 1 to 15 of 23
  1. #1
    Regular Coder
    Join Date
    Jan 2013
    Location
    Sunnyvale, CA
    Posts
    110
    Thanks
    7
    Thanked 7 Times in 7 Posts

    Question jQuery's .html() is not returning TR, TD

    So... apparently document fragments won't accept rows and cells independently... I'm keeping this post simple:

    Rows of data are retrieved from an ajax call in the form of a string.

    The string is split into an array, and its elements are intended to be embedded in table rows, whose template is in variable snip.row.

    For the purpose of this thread, the table is static in the page, defined completely with thead + tr and th elements, tbody is empty, tfoot will remain empty.

    At page load, script reads a template for the table's rows and stores it in memory (aforementioned snips.row variable):
    Code:
    var snips.row = $('#myRow')[0].outerHMTL;
    I expect to get: (added single quotes and multiple lines for your easy reading)

    Code:
    snips.row == '<tr>' + 
            '<td><span class="name" onclick="Load(this)"></span></td>' +
            '<td><span class="updated"></span></td>' +
            '<td><span class="new" onclick="New(this)"></span></td>' +
            '<td><span class="delete" title="Delete"></span></td>' +
        '</tr>'
    but what I actually see when I alert('snips.row = ' + snips.row) is:

    Code:
    snips.row == '<span class="name" onclick="Load(this)"></span>' +
            '<span class="updated"></span>' +
            '<span class="new" onclick="New(this)"></span>' + 
            '<span class="delete" title="Delete"></span>'
    I'm seeking an easy solution that enables me to populate my rows dynamically with retrieved data and append the rows to the table's body, and prefer not to build each row with script in a loop (despite that it most likely performs faster). (Basically, I'm sacrificing performance for readability).

    Any suggestions? What do y'all do when you want to achieve this?
    Last edited by sbhmf; 04-04-2014 at 03:47 PM.

  • #2
    Senior Coder xelawho's Avatar
    Join Date
    Nov 2010
    Posts
    2,980
    Thanks
    56
    Thanked 557 Times in 554 Posts
    this:
    Code:
    var snips.row = $('#myRow')[0].outerHMTL;
    is such a weird mix of vanilla and jQuery that it seems to be asking for trouble

    I don't know if it gets you any closer to a solution to your larger problem, but what's wrong with this?
    Code:
    var snips.row=document.getElementById("myRow").outerHTML;

  • #3
    Regular Coder
    Join Date
    Jan 2013
    Location
    Sunnyvale, CA
    Posts
    110
    Thanks
    7
    Thanked 7 Times in 7 Posts
    It's the same thing, but in jQuery notation (shorthand for .get(0). Also recommended in "Learning jQuery" (forward by John Resig), 3rd edition, PackT publishing, page 44.). From the perspective of performance, yours is better because it will process faster.

    Client devices are quite fast these days, and the performance hit is minimal when assessed against the added value of readability. I want my code to read like a book!

    I believe that the real issue rests with the manner in which document fragments are processed. There are various ways of instantiating a document fragment, from the basic document.createDocumentFragment('<whatever element you want>') to $('<equivalent of the same>'). In my code I use the latter.

    I load data from the DB at runtime (via AJAX), and need to dynamically create a row for each item of data received. I don't know how many rows will be required until the data are received. I prefer to have a predetermined snippet of html code that contains all elements and their static attributes and values in memory, and simply plug the snippet in with each iteration and apply its datum as I loop through the data received. I feel it is more elegant and more readable that way despite the performance cost.

    (To minimize performance cost, I concatenate all the rows in a document fragment that has not been attached to the document's body, and I append it only after it is complete. See http://ejohn.org/blog/dom-documentfragments/)

    I have already changed my code to build a string commencing with the table element and add rows dynamically in a 'do' loop, and although it will execute faster is a mess to read. THERE MUST BE A MORE ELEGANT SOLUTION [without over-engineering it] THAN THIS!!!

    XML data islands would offer a viable option if only they were cross-browser supported. My doctype is XHTML, so there's no chance of trying an HTML5 data bind.
    Last edited by sbhmf; 04-04-2014 at 06:02 PM. Reason: fixed typos

  • #4
    Senior Coder xelawho's Avatar
    Join Date
    Nov 2010
    Posts
    2,980
    Thanks
    56
    Thanked 557 Times in 554 Posts
    Code:
    var snips.row = $('#myRow')[0].outerHMTL;
    var snips.row=document.getElementById("myRow").outerHTML;
    Are not not the same thing at all if you understand what they're doing.

    In plain English, the first one is saying "take this DOM element, turn it into a jQuery Object, then immediately convert it back into a DOM element so we can get its outerHTML"

    sorry, weird. you will have to work very hard to convince me otherwise.

    there is surely a more elegant solution to what you are doing than building a table (really? a table?) out of a string in a do loop, but I suspect your "readability" concerns may be your largest obstacle here.

  • #5
    Supreme Master coder! glenngv's Avatar
    Join Date
    Jun 2002
    Location
    Philippines
    Posts
    11,068
    Thanks
    0
    Thanked 256 Times in 252 Posts
    Quote Originally Posted by xelawho View Post

    In plain English, the first one is saying "take this DOM element, turn it into a jQuery Object, then immediately convert it back into a DOM element so we can get its outerHTML"

    sorry, weird. you will have to work very hard to convince me otherwise.
    That is inaccurate. The code is saying, "Take this CSS id selector, turn it into a jQuery object, then convert it into a DOM element so we can get its outerHTML".

    jQuery does not actually convert it into a DOM element because inside the jQuery object is the DOM element(s) that matched the selector.


    There is actually another way of doing that without converting the jQuery object into a DOM element:

    Code:
    var snips.row = $('#myRow').prop('outerHMTL');
    Last edited by glenngv; 04-04-2014 at 06:38 PM.
    Glenn
    ____________________________________

    My Blog
    Tower of Hanoi Android app (FREE!)
    Tower of Hanoi Leaderboard
    Samegame Facebook App
    vBulletin Plugins
    ____________________________________

  • #6
    Senior Coder xelawho's Avatar
    Join Date
    Nov 2010
    Posts
    2,980
    Thanks
    56
    Thanked 557 Times in 554 Posts
    Interesting. But isn't a CSS id selector just a pointer to a DOM element?

  • #7
    Supreme Master coder! glenngv's Avatar
    Join Date
    Jun 2002
    Location
    Philippines
    Posts
    11,068
    Thanks
    0
    Thanked 256 Times in 252 Posts
    @sbhmf, can you post a simple demo page here or on jsfiddle?
    Glenn
    ____________________________________

    My Blog
    Tower of Hanoi Android app (FREE!)
    Tower of Hanoi Leaderboard
    Samegame Facebook App
    vBulletin Plugins
    ____________________________________

  • #8
    Supreme Master coder! glenngv's Avatar
    Join Date
    Jun 2002
    Location
    Philippines
    Posts
    11,068
    Thanks
    0
    Thanked 256 Times in 252 Posts
    Quote Originally Posted by xelawho View Post
    Interesting. But isn't a CSS id selector just a pointer to a DOM element?
    But it's still a string not a DOM element.

    Code:
    "#myRow" !== document.getElementById('myRow')
    Glenn
    ____________________________________

    My Blog
    Tower of Hanoi Android app (FREE!)
    Tower of Hanoi Leaderboard
    Samegame Facebook App
    vBulletin Plugins
    ____________________________________

  • #9
    Senior Coder xelawho's Avatar
    Join Date
    Nov 2010
    Posts
    2,980
    Thanks
    56
    Thanked 557 Times in 554 Posts
    well sure, but the point is that you're just getting jQuery to run around in circles behind the scenes when you could be doing it up front in vanilla...
    For id selectors, jQuery uses the JavaScript function document.getElementById()
    ID Selector (ÔÇť#idÔÇŁ) | jQuery API Documentation

  • #10
    Regular Coder
    Join Date
    Jan 2013
    Location
    Sunnyvale, CA
    Posts
    110
    Thanks
    7
    Thanked 7 Times in 7 Posts
    I stand corrected. Thank you. (I have not tested it myself, but I do believe that accessing the outerHTML via jQuery takes a performance hit.)

    Still, and back to my issue at hand, whether the data is converted into an object or not (lol...), it still strips the table-row and table-data elements.

    Binding data to tables is standard, so why the amazement?
    Last edited by sbhmf; 04-04-2014 at 07:00 PM.

  • #11
    Supreme Master coder! glenngv's Avatar
    Join Date
    Jun 2002
    Location
    Philippines
    Posts
    11,068
    Thanks
    0
    Thanked 256 Times in 252 Posts
    Quote Originally Posted by xelawho View Post
    well sure, but the point is that you're just getting jQuery to run around in circles behind the scenes when you could be doing it up front in vanilla...

    ID Selector (Ô€œ#idÔ€Ł) | jQuery API Documentation
    Agreed. We all know that vanilla Javascript runs faster than jQuery. My only point here is the inaccuracy of your statement, "take this DOM element, turn it into a jQuery Object, then immediately convert it back into a DOM element so we can get its outerHTML".
    Glenn
    ____________________________________

    My Blog
    Tower of Hanoi Android app (FREE!)
    Tower of Hanoi Leaderboard
    Samegame Facebook App
    vBulletin Plugins
    ____________________________________

  • #12
    Senior Coder xelawho's Avatar
    Join Date
    Nov 2010
    Posts
    2,980
    Thanks
    56
    Thanked 557 Times in 554 Posts
    Quote Originally Posted by sbhmf View Post
    it still strips the table-row and table-data elements.
    I don't see that on a simple test using either method - maybe as glenn says it's time to post more code

    Code:
    <body>
    <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
    <table style="width:300px">
    <tr id="myRow">
      <td><span>Jill</span></td>
      <td><span>Smith</span></td> 
      <td><span>50</span></td>
    </tr>
    <tr>
      <td><span>Eve</span></td>
      <td><span>Jackson</span></td> 
      <td><span>94</span></td>
    </tr>
    </table>
    <script type="text/javascript">
    var row1=$('#myRow')[0].outerHTML;
    var row2=$('#myRow')[0].innerHTML;
    var row3=document.getElementById("myRow").outerHTML;
    alert("jQuery outer: "+row1);
    alert("jQuery inner: "+row2);
    alert("vanilla outer: "+row3);
    </script>
    
    </body>

  • #13
    Senior Coder xelawho's Avatar
    Join Date
    Nov 2010
    Posts
    2,980
    Thanks
    56
    Thanked 557 Times in 554 Posts
    Quote Originally Posted by glenngv View Post
    My only point here is the inaccuracy of your statement, "take this DOM element, turn it into a jQuery Object, then immediately convert it back into a DOM element so we can get its outerHTML".
    I think we may be splitting hairs now (in case we weren't splitting them before ).

    But if document.getElementById returns a dom element, then obviously $('#myRow')[0] gets a dom element (using document.getElementById), turns it into a jquery object then turns it back into a dom element, no?

  • #14
    Supreme Master coder! glenngv's Avatar
    Join Date
    Jun 2002
    Location
    Philippines
    Posts
    11,068
    Thanks
    0
    Thanked 256 Times in 252 Posts
    Quote Originally Posted by xelawho View Post
    I think we may be splitting hairs now (in case we weren't splitting them before ).

    But if document.getElementById returns a dom element, then obviously $('#myRow')[0] gets a dom element (using document.getElementById), turns it into a jquery object then turns it back into a dom element, no?
    "turns it back" is not the appropriate phrase. jQuery object stores the matched DOM reference in an array-like structure. So when doing $()[], jQuery simply accesses the stored DOM reference.
    Glenn
    ____________________________________

    My Blog
    Tower of Hanoi Android app (FREE!)
    Tower of Hanoi Leaderboard
    Samegame Facebook App
    vBulletin Plugins
    ____________________________________

  • #15
    Regular Coder
    Join Date
    Jan 2013
    Location
    Sunnyvale, CA
    Posts
    110
    Thanks
    7
    Thanked 7 Times in 7 Posts
    Here's the test code to replicate the issue. Compare content of both DIVs. What's going on?:

    Create a text document on the server [Test.txt] with the following content:
    Code:
    <div id="test">
        <tr>
            <td>
                <span class="Filename" onclick="LoadFile(this)">FileName.txt</span>
            </td>
            <td>
                <span class="Updated">11/20/2012</span>
            </td>
            <td>
                <span class="Delete" title="Delete file"><input type="button" value="Delete" /></span>
            </td>
            <td>
                <span class="Edit" title="Edit file"><input type="button" value="Edit" /></span>
            </td>
        </tr>
    </div>
    Create your HTML page with the following content:
    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Test Missing TR and TDs</title>
        <script src="JS/jquery-1.7.1.js" type="text/javascript" language="javascript"></script>
        <script type="text/javascript" language="javascript">
        function CreateDoc(Value) {
            /*Instantiations and initializations:*/
            var val = '', xhr = (window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
            
            /*Retrieve item:*/
            xhr.open("GET", Value, false);
            xhr.send();
            val = xhr.responseText;
    
            /*Clean-up:*/
            xhr = null;
    
            return val;
        }
        function Load(){
            var doc = CreateDoc('Text/Test.txt');
            document.getElementsByTagName('div')[0].innerHTML = '<xmp>' + doc + '</xmp>';
            $('div').eq(1).html('<xmp>' + $(doc)[0].outerHTML + '</xmp>');
            
            /*Clean-up:*/
            doc = null;
        }
        </script>
    </head>
    <body onload="Load()">
        <div></div>
        <br /><br />
        <div></div>
    </body>
    </html>


  •  
    Page 1 of 2 12 LastLast

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •