views:

376

answers:

4

Hi,
I'm not a good programmer and I just started using jQuery. I need a table sorter that can expand and collapse rows. My code is below. I've spent lots of time trying to improve its execution time. In IE it takes lots of time. I'd appreciate your suggestions.

$(document).ready(function() {
  $('table.sortable').each(function() {
    var $table = $(this);
    var myData = new Array(), myData1 = new Array();
    var rows = $table.find('tbody > tr').get();
    var rowCount = 0;
    $.each(rows, function(index, row){ //arrange rows in 2 dimention array
      if(($(row).children('td').eq(0).attr('class').indexOf('collapse') != -1 || $(row).children('td').eq(0).attr('class').indexOf('expand') != -1)){   
        myData.push(myData1);
        myData1 = [];
      }
      myData1.push(row);    
      rowCount++;
      if(rowCount == $(rows).length){ // to assign last group of rows
        myData.push(myData1);
        myData1 = [];
      }
    });
    $table.find('th').each(function(column) {
      var findSortKey;
      if ($(this).is('.sort-alpha')) {
        findSortKey = function($cell) { 
          return $cell.find('.sort-key').text().toUpperCase() +
            ' ' + $cell.text().toUpperCase();
        };
      }
      else if ($(this).is('.sort-numeric')) {
        findSortKey = function($cell) {
          var key = parseFloat($cell.text().replace(/,/g,''));
          return isNaN(key) ? 0 : key;
        };
      }
      if (findSortKey) {
        $(this).addClass('header').click(function() {
          var newDirection = 1;
          if ($(this).is('.headerSortUp')) {
            newDirection = -1;
          }
          var expand = $table.find('tbody > tr > td.expand').get().length;
          if(expand > 0){
            $.each(myData, function(index, row) {
              $.each(row, function(index1, row2) {
                row2.sortKey = findSortKey($(row2).children('td').eq(column));
              });
            });
            $.each(myData, function(index, row) {
              row.sort(function(a, b) {
                if($(a).children('td').eq(0).attr('class').indexOf('collapse') == -1 && $(a).children('td').eq(0).attr('class').indexOf('expand') == -1 && $(b).children('td').eq(0).attr('class').indexOf('collapse') == -1 && $(b).children('td').eq(0).attr('class').indexOf('expand') == -1 ){
                  return ((a.sortKey < b.sortKey) ? -newDirection : ((a.sortKey > b.sortKey) ? newDirection : 0));
                }
                if(navigator.userAgent.toLowerCase().indexOf('chrome') > -1){
                  return -1; // hack for google chromo
                }
                return 0;
              });
            });
          }else{
            $.each(myData, function(index, row) {
              row.sortKey = findSortKey($(row[0]).children('td').eq(column));
            });
            myData.sort(function(a, b) {
              if (a.sortKey < b.sortKey) return -newDirection;
              if (a.sortKey > b.sortKey) return newDirection;
              return 0;
            });
          }
          // alternate rows goes here and updating table 
          var alt = true;
          var altSub = true;
          $.each(myData, function(index, row) {
            var noRow = $(row).length;
            for (var i=0; i < noRow; i++){
              if($(row[0]).attr('id') == $(row[i]).attr('id')){
                if(alt == true){
                  $(row[0]).removeClass("odd").addClass("even");
                  alt = !alt;
                  altSub =true;
                }else if( alt == false){
                  $(row[0]).removeClass("even").addClass("odd");
                  alt = !alt;
                  altSub = true;
                }
              }else{
                if(altSub == true){
                  $(row[i]).removeClass("alt_row_sub").addClass("alt_row_sub2");
                  altSub = !altSub;
                }else if( altSub == false){
                  $(row[i]).removeClass("alt_row_sub2").addClass("alt_row_sub");
                  altSub = !altSub;
                }
              }
            }
            $table.children('tbody').append(row);
            row.sortKey = null;
          });
          $table.find('th').removeClass('headerSortUp')
            .removeClass('headerSortDown');
          var $sortHead = $table.find('th').filter(':nth-child('
            + (column + 1) + ')');
          if (newDirection == 1) {
            $sortHead.addClass('headerSortUp');
          } else {
            $sortHead.addClass('headerSortDown');
          }
        });
      }
    });
  });
});

image below gives some idea. this wil sort group of rows. table image

A: 

As a start, I would not trying to sort mydata with JavaScript at client-side, but I would to do it a server side. JavaScript is not made for performance and it blocks your browser when it is processing things.

Michael
I agree with your point, but the thing is if i use tablesorter jquery plugin, its performance is excellent. I guess the problem with my code is the way of DOM modification.
vinay
@Michael, got to disagree, there's good reasons you may wish to sort things client side. With improved JavaScript speed and libraries there's many cases where it can be optimum over a round trip to server.
Pool
I've sorted quite a bit of data in JavaScript in the blink of the eye. In my experience it's an order of magnitude faster to sort on the client then to ask the server to sort and get the info back.
Nosredna
Michael
+2  A: 

I'm not entirely sure what you're trying to do, but if you're trying to sort tables, have you considered using this jQuery plugin: http://tablesorter.com/docs/ ?

EDIT: having seen your screenshot (I presume your link should be to: http://www.freeimagehosting.net/uploads/dc95537e24.gif), I see what you're trying to do. This isn't something I've seen in jQuery, but it's something that ExtJS handles very well: http://extjs.com/deploy/dev/examples/grid/grouping.html - that may not be very helpful to you though, sorry.

Joe Freeman
Thanks for your response. I already tried this plugin, it will sort all rows irrespective of which group it belongs.
vinay
A: 

Another option to improve performance of operations like sorting data client side is to use the HTML Bridge and interop with a non-visual Silverlight 2 component. That way you can use managed code (C#) to do the calculations client side.

Offcourse you would have to provide a (slower) JavaScript alternative to users who does not have Silverlight 2 installed. Look at this as "progressive enhancement" of performance (use Silverlight if available, if not use JavaScript).

Jonas Follesø
A: 

Below image is screen shot of the table
demo image

vinay
It's too small to see what you require.
Pool
Just edit your original post, do not post images as a reply.
dalbaeb