1. #1
    Sencha - Desktop Packager Dev Team jarrednicholls's Avatar
    Join Date
    Mar 2007
    Location
    Frederick, MD
    Posts
    1,747
    Vote Rating
    7
    jarrednicholls will become famous soon enough jarrednicholls will become famous soon enough

      0  

    Default Bug in DomHelper/Template - inserting table rows

    Bug in DomHelper/Template - inserting table rows


    Hey Jack,

    My buddy Aaron and I found a bug tonight when trying to do an insertBefore on a template of a table row into a table. Here was the problem code:

    Code:
    if (table.tBodies[0].rows[0]) { 
          tpl.insertBefore(table.tBodies[0].rows[0], {profilename: 'My Profile', id: id}); 
       } else { 
          tpl.append(table.tBodies[0], {profilename: 'My Profile', id: id}); 
       }
    The template is of a tr element. So intuitively, one would think "if I want to insert my tr template before another tr, I would pass in that specific tr as the element to the insertBefore function". This yields a wicked bug in the insertHtml function of the DomHelper class:

    Code:
    var insertIntoTable = function(tag, where, el, html){
    
            if(!tempTableEl){
    
                tempTableEl = document.createElement('div');
    
            }
    
            var node;
    
            if(tag == 'table' || tag == 'tbody'){
    
               tempTableEl.innerHTML = '<table><tbody>'+html+'</tbody></table>';
    
               node = tempTableEl.firstChild.firstChild.firstChild;
    
            }else{
    
               tempTableEl.innerHTML = '<table><tbody><tr>'+html+'</tr></tbody></table>';
    
               node = tempTableEl.firstChild.firstChild.firstChild.firstChild;
    
            }
    
            if(where == 'beforebegin'){
    
                el.parentNode.insertBefore(node, el);
    
                return node;
    
            }else if(where == 'afterbegin'){
    
                el.insertBefore(node, el.firstChild);
    
                return node;
    
            }else if(where == 'beforeend'){
    
                el.appendChild(node);
    
                return node;
    
            }else if(where == 'afterend'){
    
                el.parentNode.insertBefore(node, el.nextSibling);
    
                return node;
    
            }
    
        }
    As you know, the insertIntoTable function is called by the insertHtml function because the passed element has the tr tagName. In the code above, you see that if the tagName is NOT table or tbody, then this code runs:

    Code:
    else{
    
               tempTableEl.innerHTML = '<table><tbody><tr>'+html+'</tr></tbody></table>';
    
               node = tempTableEl.firstChild.firstChild.firstChild.firstChild;
    
            }
    This is problematic because our template is a tr element. And a tr element being put into a tr element doesn't work! :-) So the natural thing to do is pass in the tbody element, riiight?

    Code:
    if (table.tBodies[0].rows[0]) { 
          tpl.insertBefore(table.tBodies[0], {profilename: 'My Profile', id: id}); 
       } else { 
          tpl.append(table.tBodies[0], {profilename: 'My Profile', id: id}); 
       }
    Ok, so this makes it so our tr template gets put into a tbody in your tempTableEl code in the insertIntoTable function. Good. But this still isn't good, because the insertBefore function uses the 'beforebegin' where clause, which runs this code:

    Code:
    if(where == 'beforebegin'){
    
                el.parentNode.insertBefore(node, el);
    
                return node;
    
            }
    Not good. Our tr is being put into the table before the tbody element. Well ! We're close though. Here was the final fix, going straight through to the DomHelper since there was no wrapper for the 'afterbegin' where clause:

    Code:
    if (table.tBodies[0].rows[0]) { 
          YAHOO.ext.DomHelper.insertHtml('afterbegin', table.tBodies[0], tpl.applyTemplate({profilename: 'My Profile', id: id}));
       } else { 
          tpl.append(table.tBodies[0], {profilename: 'My Profile', id: id}); 
       }
    Great, that works, because the afterbegin runs this code:

    Code:
    else if(where == 'afterbegin'){
    
                el.insertBefore(node, el.firstChild);
    
                return node;
    
            }
    Perfect! So you see, having a tr template and trying to do an insertBefore another row intuitively would seem to work just fine, but it does not. Can you put this on your low priority to-do list?

    Thanks for all the hard work Jack!

    EDIT: This isn't so reliable in IE either. But perhaps you can test a bit and find a good solution to such a problem. We all appreciate it!

  2. #2
    Sencha User jack.slocum's Avatar
    Join Date
    Mar 2007
    Location
    Tampa, FL
    Posts
    6,955
    Vote Rating
    16
    jack.slocum will become famous soon enough

      0  

    Default


    Inserting into tables and selects is always a nightmare in IE. I will go through that code very soon and give it an upgrade. Sorry about the lost time.

Similar Threads

  1. Ext.DomHelper.Template: one template, ten YUI grids
    By moraes in forum Community Discussion
    Replies: 11
    Last Post: 18 Dec 2012, 4:55 AM
  2. DomHelper bug inserting before/after a table element.
    By Animal in forum Ext 2.x: Help & Discussion
    Replies: 7
    Last Post: 6 Mar 2007, 2:39 AM
  3. Ext.DomHelper.Template or Ext.Template?
    By mystix in forum Ext 2.x: Help & Discussion
    Replies: 4
    Last Post: 1 Mar 2007, 3:05 PM
  4. Faulty DomHelper.Template behaviour while adding table rows
    By manugoel2003 in forum Ext 1.x: Help & Discussion
    Replies: 9
    Last Post: 20 Jan 2007, 1:37 AM
  5. [OPEN] DomHelper.Template.compile
    By Animal in forum Ext 1.x: Bugs
    Replies: 1
    Last Post: 26 Oct 2006, 7:17 AM

Thread Participants: 1