Search code examples
jqueryasp.nethtmlclone

jquery clone with HTML template


I have seen a few tutorials on jQuery templates , which as far as I understand is outdataed , so I am trying to use .Clone I got it to work fine when I am only showing one result, but when I want to show an entire list of results it is not working, I am sure because of my bad jQuery. I want to clone the entire .template class fill it from each member of the response array , then add each newly cloned template to #fillresultsdiv , if anyone can help find what I'm doing wrong

here is jQuery:

                 success: function (msg) {
                    var events = [];
                    var obj = $.parseJSON(msg.d);
                    $(obj.res).each(function () {
                        var newRow = $('.template').clone()
                        newRow.$('.day').text($(this).attr('day')),
                            newRow.$('.dayofweek').text($(this).attr('dayofweek')),
                            newRow.$('.month').text($(this).attr('month')),
                            newRow.$('.title').text($(this).attr('title')),
                            newRow.$('.time').text($(this).attr('time')),
                        newRow.$('.venue').text($(this).attr('venue')),
                        newRow.$('.description').text($(this).attr('description'))
                        $('#fillresultsdiv').append(newRow);

Here is a sample response :

   d: "{"res":[{"day":"26","dayofweek":"Tue","month":"Jun","title":"Glen Hansard","venue":"Vic Theatre","time":"7:00 PM","ticketurl":"http://seatgeek.com/glen-hansard-t

and here is my template HTML:

    <div class="Template">
      <div class="accordian_head1">
        <div class="date_container">
          <a class="day"></a><br/><br/>
          <a class="dayofweek"></a><br/>
          <a class="month"></a>
        </div>
        <div class="title_container">
          <a class="title">Title</a>
          <a class="venue"><br/></a><a class="time"></a>
        </div>
        <div class="links">
          <a href=" + dr(36).ToString() + ?aid=854">Buy Tickets</a><br/>
          <a href="javascript:void(0)" onclick="fnAddToCalendar({ 'eventID' : '  dr(0).ToString() + '});">Watch</a><br/>
        <a href="#">Email</a><br/>
        <a href=""Calendar.aspx"">Calendar</a><br/>
    </div>
  </div>
  <div class="accordian_body1new"><a class="description"></a>
  </div>

This is all #fillresultsdiv is

     <div id="fillresultsdiv"></div> 

Solution

  • // Parse the entire string, because `msg` is not an object,
    // so you can't use `msg.d`
    var obj = $.parseJSON( msg );
    
    $( obj.d.res ).each( function() {
        var newRow = $( '.template' ).clone();
    
        // Now loop through the object
        for ( var prop in this ) {
            if ( this.hasOwnProperty( prop ) ) {
    
                // Lucky for you, the keys match the classes :)
                $( '.' + prop, newRow ).text( this[ prop ] );
            }
        }
        $( '#fillresultsdiv' ).append( newRow );
    } );
    

    But you should definitely use a DocumentFragment to speed up the DOM manipulation and append everything at once. Because remember: the DOM is effin slow.

    var obj = $.parseJSON( msg );
    
    // Create a DocumentFragment
    var el = document.createDocumentFragment();
    $( obj.d.res ).each( function() {
        var newRow = $( '.template' ).clone();
        for ( var prop in this ) {
            if ( this.hasOwnProperty( prop ) ) {
                $( '.' + prop, newRow ).text( this[ prop ] );
            }
        }
    
        // Append to the DocumentFragment
        $( el ).append( newRow );
    } );
    
    // And append the DocumentFragment to the DIV
    $( '#fillresultsdiv' ).append( el );