سؤال

I am attempting to work with the TableSorter jQuery plugin to build a table completely on the fly (headers and data).

As is the case with most web applications, the user inputs some data/criteria, clicks a button, and data is returned. I build a table to hold the data, which the user can sort. I had that working fine, however, it was decided that we need the users to be able to specify what columns of data they would like and in what order those columns should be.

The data retrieval is completely done. I make a javascript/jQuery call from the aspx page to the aspx.vb code-behind via a web method. The code behind interacts with a DLL which passes its information back in a datatable. I build a string from the datatable to pass back to the javascript/jQuery code. In the javascript the string is split into a string array.

Here is how I was building the table previously (before the requirements of user specified columns and column order):

HTML:

<table id="mytable" class="tablesorter" border="1">
       <thead title="Click to sort">
        <tr>
        <th style="color:#A7C942;" title="Click for default order"><div class="1"></div></th>
        <th><div id="div1" class="2">Column2</div></th>
        <th><div class="3">Column3</div></th>
        <th><div class="4">Column4</div></th>
        <th><div class="5">Column5</div></th>
        <th><div class="6">Column6</div></th>
        <th><div class="7">Column7</div></th>
        <th><div class="8">Column8</div></th>
        <th><div class="9">Column9</div></th>
        <th><div class="10">Column10</div></th>
        <th><div class="11">Column11</div></th>
        <th><div class="12">Column12</div></th>
        <th><div class="13">Column13</div></th>
        <th><div class="14">Column14</div></th>
        <th><div class="15">Column15</div></th>
        <th><div class="16">Column16</div></th>
        <th><div class="17">Column17</div></th>
        </tr>
        </thead>
           <tbody>

           </tbody>
       </table>

Javascript:

var table = '';

for (var i = 1; i <= NumberOfRecords; i++) { //for each record
   if (i % 2 == 0) { table += '<tr class="even">'; } else {
       table += '<tr>';
   }


   table += '<td><div class="1"><img src="/resources/ic_menu_search.png" alt="" height="20" width="20" style="cursor: pointer;" id="' + i + '" ></img></div></td>';
   table += '<td><div class="2">' + TableResults[((i - 1) * 459) + 1] + '</div></td>';
   table += '<td><div class="3">' + TableResults[((i - 1) * 459) + 4] + '</div></td>';
   table += '<td><div class="4">' + TableResults[((i - 1) * 459) + 5] + '</div></td>';
   table += '<td><div class="5">' + TableResults[((i - 1) * 459) + 6] + '</div></td>';
   table += '<td><div class="6">' + TableResults[((i - 1) * 459) + 9] + '</div></td>';
   table += '<td><div class="7">' + "$" + TableResults[((i - 1) * 459) + 12] + ".00" + '</div></td>';
   table += '<td><div class="8">' + TableResults[((i - 1) * 459) + 15] + '</div></td>';
   table += '<td><div class="9">' + TableResults[((i - 1) * 459) + 16] + '</div></td>';
   table += '<td><div class="10">' + TableResults[((i - 1) * 459) + 37] + '</div></td>';
   table += '<td><div class="11">' + TableResults[((i - 1) * 459) + 38] + '</div></td>';
   table += '<td><div class="12">' + TableResults[((i - 1) * 459) + 39] + "%" + '</div></td>';
   table += '<td><div class="13">' + TableResults[((i - 1) * 459) + 45] + '</div></td>';
   table += '<td><div class="14">' + TableResults[((i - 1) * 459) + 66] + '</div></td>';
   table += '<td><div class="15">' + TableResults[((i - 1) * 459) + 78] + '</div></td>';
   table += '<td><div class="16">' + "$" + TableResults[((i - 1) * 459) + 81] + ".00" + '</div></td>';
   table += '<td><div class="17">' + TableResults[((i - 1) * 459) + 109] + '</div></td>';
   table += '</tr>';


  } 



$('#mytable').append(table);

TableSorter:

$('#mytable').tablesorter({
              theme: 'default',
              widgets: ['zebra', 'reorder'],
              widgetOptions: {
                  reorder_axis: 'x', // 'x' or 'xy'
                  reorder_delay: 300,
                  reorder_helperClass: 'tablesorter-reorder-helper',
                  reorder_helperBar: 'tablesorter-reorder-helper-bar',
                  reorder_noReorder: 'reorder-false',
                  reorder_blocked: 'reorder-block-left reorder-block-end',
                  reorder_complete: null // callback
              }

          })

I set div classes for each because the header and data weren't lining up properly since they were being created at different times. This works fine, but since the user needs to be able to determine the columns that they see and in what order, I'm going to have to approach it a bit differently. I came across the Build Table widget for TableSorter and attempted to implement it as follows:

HTML:

   <div id="mytable">
   </div>

Javascript (first two columns will be static, the rest will be set by the user on a setup screen):

   var table = [];

   table += '[ [' + ['', 'Column2', 'Column3', 'Column4', 'Column5', 'Column6', 'Column7', 'Column8', 'Column9', 'Column10', 'Column11', 'Column12', 'Column13', 'Column14', 'Column15', 'Column16', 'Column17'] + '],';

   for (var i = 1; i <= NumberOfRecords; i++) { //for each record
      table += '[' + [i, TableResults[((i - 1) * 459) + 1], TableResults[((i - 1) * 459) + 4], TableResults[((i - 1) * 459) + 5], TableResults[((i - 1) * 459) + 6], TableResults[((i - 1) * 459) + 9], TableResults[((i - 1) * 459) + 12], TableResults[((i - 1) * 459) + 15], TableResults[((i - 1) * 459) + 16], TableResults[((i - 1) * 459) + 37], TableResults[((i - 1) * 459) + 38], TableResults[((i - 1) * 459) + 39], TableResults[((i - 1) * 459) + 45], TableResults[((i - 1) * 459) + 66], TableResults[((i - 1) * 459) + 78], TableResults[((i - 1) * 459) + 81], TableResults[((i - 1) * 459) + 109]] + ']';

      if (i != NumberOfRecords) {
          table += ',';
      }
   }

   table += '];'

TableSorter:

   $('#mytable').tablesorter({
              theme: 'default',
              widgets: ['zebra', 'reorder', 'stickyHeaders'],//, 'resizable'],
              widgetOptions: {
                  build_source: table,
                  build_headers: {
                      rows: 1,
                      classes: [],
                      text: [],
                      widths : ['3%', '8%', '7%', '7%', '7%', '7%', '6%', '7%', '7%', '7%', '7%', '7%', '7%', '7%', '6%']
                  }

              }

          })

However, this will do nothing. If I add the "$('#mytable').append(table);" it will append the text, but I still get no table. I've made sure the code for the Build Table widget is included in the project and if I set a breakpoint it is being hit on load.

The end goal is to read the user's column preference from a database (which will be easy) and use the selected columns to generate a table completely dynamically. Then that table needs to be sortable, have reorderable columns (which I also have a TableSorter widget for), and the columns need to be resizable (another TableSorter widget).

How do I build this table on the fly, being able to accomplish the above goals, and have the columns line up with the data? What am I doing wrong? Thanks in advance for any help you can provide!

هل كانت مفيدة؟

المحلول

To me it looks like the tbody of the table needs to be targeted.

Well, it appears that $('#mytable') is actually targeting a table element; and since the javascript doesn't have the thead or tbody elements, the append code should look like this:

$('#mytable tbody').append(table);

As for the modified header that the user builds, I don't see that code above.

If you want to use the build widget, the table array above should contain an array of row arrays, currently it is building an array of one large string. Try this instead (untested):

var table = [];
table.push(['', 'Column2', 'Column3', 'Column4', 'Column5', 'Column6', 'Column7', 'Column8', 'Column9', 'Column10', 'Column11', 'Column12', 'Column13', 'Column14', 'Column15', 'Column16', 'Column17']);

for (var i = 1; i <= NumberOfRecords; i++) { //for each record
    table.push([
        '<div class="1"><img src="/resources/ic_menu_search.png" alt="" height="20" width="20" style="cursor: pointer;" id="' + i + '" ></div>',
        '<div class="2">' + TableResults[((i - 1) * 459) + 1] + '</div>',
        '<div class="3">' + TableResults[((i - 1) * 459) + 4] + '</div>',
        '<div class="4">' + TableResults[((i - 1) * 459) + 5] + '</div>',
        '<div class="5">' + TableResults[((i - 1) * 459) + 6] + '</div>',
        '<div class="6">' + TableResults[((i - 1) * 459) + 9] + '</div>',
        '<div class="7">$' + TableResults[((i - 1) * 459) + 12] + '.00</div>',
        '<div class="8">' + TableResults[((i - 1) * 459) + 15] + '</div>',
        '<div class="9">' + TableResults[((i - 1) * 459) + 16] + '</div>',
        '<div class="10">' + TableResults[((i - 1) * 459) + 37] + '</div>',
        '<div class="11">' + TableResults[((i - 1) * 459) + 38] + '</div>',
        '<div class="12">' + TableResults[((i - 1) * 459) + 39] + '%</div>',
        '<div class="13">' + TableResults[((i - 1) * 459) + 45] + '</div>',
        '<div class="14">' + TableResults[((i - 1) * 459) + 66] + '</div>',
        '<div class="15">' + TableResults[((i - 1) * 459) + 78] + '</div>',
        '<div class="16">$' + TableResults[((i - 1) * 459) + 81] + '.00</div>',
        '<div class="17">' + TableResults[((i - 1) * 459) + 109] + '</div>'
    ]);
}

$('#myTable').tablesorter({
    theme: 'default',
    widgets: ['zebra', 'stickyHeaders'],
    widgetOptions : {
        build_source : table,
        build_headers : {
            rows    : 1,
            classes : [],
            text    : [],
            widths : ['3%', '8%', '7%', '7%', '7%', '7%', '6%', '7%', '7%', '7%', '7%', '7%', '7%', '7%', '6%']
        },
        build_footers : {
            rows    : 0
        }
    }
});

Lastly, I wouldn't recommend using the reorder widget as it still in beta and has some unresolved issues before it will be production-ready. If you need to add, remove or update the table after a column has changed, use the updateAll option.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top