[Pkg-javascript-commits] [libjs-jquery-stupidtable] 01/06: New upstream version 1.1.2+dfsg

Sergio Durigan Junior sergiodj-guest at moszumanska.debian.org
Fri Aug 25 03:25:22 UTC 2017


This is an automated email from the git hooks/post-receive script.

sergiodj-guest pushed a commit to branch master
in repository libjs-jquery-stupidtable.

commit dea8af32a308fc9fef2d1af55b20ffe2680420ef
Author: Sergio Durigan Junior <sergiodj at sergiodj.net>
Date:   Thu Aug 24 23:02:41 2017 -0400

    New upstream version 1.1.2+dfsg
---
 CHANGELOG.md                   |  42 ++++++
 README.md                      | 125 ++++++++++++++++++
 bower.json                     |   4 +-
 examples/basic.html            |   2 +-
 examples/multicolumn-sort.html | 119 +++++++++++++++++
 examples/with-settings.html    | 123 +++++++++++++++++
 stupidtable.js                 | 294 ++++++++++++++++++++++++++++++-----------
 tests/test-min.html            | 149 ++++++++++++++++++++-
 tests/test.html                | 149 ++++++++++++++++++++-
 tests/tests.js                 | 278 +++++++++++++++++++++++++++++++++++---
 10 files changed, 1188 insertions(+), 97 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..99e2ea4
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,42 @@
+v1.1.2 (Released 07/11/2017)
+----------------------------
+
+Added multicolumn sort capabilities. See [examples/multicolumn-sort.html](https://rawgit.com/joequery/Stupid-Table-Plugin/master/examples/multicolumn-sort.html).
+
+v1.1.1 (Released 07/02/2017)
+----------------------------
+
+Updated internal representation of tables.
+Added `will_manually_build_table` setting.
+
+v1.1.0 (Released 06/28/2017)
+----------------------------
+
+We are introducing an implementation of settings for StupidTable. The first
+setting is `should_redraw`. This setting allows you to specify a function that
+can conditionally prevent the table from redrawing after a sort.
+
+v1.0.7 (Released 06/25/2017)
+----------------------------
+
+A `<th>` element can now be provided with a `data-sort-onload=yes` attribute.
+Once `$table.stupidtable()` is called the table will immediately be sorted by
+the column with the `data-sort-onload=yes` attribute if one is found.
+Resolves [Issue #180](https://github.com/joequery/Stupid-Table-Plugin/issues/180) and [Issue #126](https://github.com/joequery/Stupid-Table-Plugin/issues/126).
+
+v1.0.6 (Released 06/24/2017)
+----------------------------
+
+Fixed [Issue #183](https://github.com/joequery/Stupid-Table-Plugin/issues/183)
+that prevented consecutive calls to `$th.stupidsort()` from running when the
+same sort direction was specified.
+
+v1.0.5 (Released 06/10/2017)
+----------------------------
+
+before/aftertablesort callbacks can access the column header element via `data.$th`.
+
+v1.0.4 (Released 06/10/2017)
+----------------------------
+
+Force a stable sort to circumvent [unstable sorting implementations](https://stackoverflow.com/questions/3026281/array-sort-sorting-stability-in-different-browsers).
diff --git a/README.md b/README.md
index 0785fe6..e8e21fd 100644
--- a/README.md
+++ b/README.md
@@ -112,6 +112,52 @@ or "desc" first.
       </thead>
     </table>
 
+Sorting a column on load
+------------------------
+
+If you want a specific column to be sorted immediately after
+`$table.stupidtable()` is called, you can provide a `data-sort-onload=yes`
+attribute.
+
+    <table>
+      <thead>
+        <tr>
+            <th data-sort="float" data-sort-onload=yes>float</th>
+            ...
+        </tr>
+      </thead>
+    </table>
+
+Multicolumn sorting
+-------------------
+
+A multicolumn sort allows you to define secondary columns to sort by in the
+event of a tie with two elements in the sorted column. See [examples/multicolumn-sort.html](https://rawgit.com/joequery/Stupid-Table-Plugin/master/examples/multicolumn-sort.html).
+Specify a comma-separated list of th identifiers in a `data-sort-multicolumn`
+attribute on a `<th>` element. An identifier can be an integer (which represents
+the index of the th element of the multicolumn target) or a string (which
+represents the id of the th element of the multicolumn target).
+
+  <table>
+    <thead>
+      <tr>
+        <th id="int-column" data-sort="int" data-sort-multicolumn="1,string-column">int</th>
+        <th id="float-column" data-sort="float" data-sort-multicolumn="string-column,int-column">float</th>
+        <th id="string-column" data-sort="string" data-sort-multicolumn="1,0">string</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>1</td>
+        <td>10.0</td>
+        <td>a</td>
+      </tr>
+      <tr>
+        <td>1</td>
+        <td>10.0</td>
+        <td>a</td>
+      </tr>
+
 Sorting a column programatically
 --------------------------------
 
@@ -156,6 +202,7 @@ bind on `aftertablesort`.
     table.bind('aftertablesort', function (event, data) {
         // data.column - the index of the column sorted after a click
         // data.direction - the sorting direction (either asc or desc)
+        // data.$th - the th element (in jQuery wrapper)
         // $(this) - this table object
 
         console.log("The sorting direction: " + data.direction);
@@ -220,6 +267,84 @@ we do the following:
 This extracts the integers from the cell and compares them in the style
 that sort functions use.
 
+StupidTable Settings
+--------------------
+
+As of 1.1.0 settings have been introduced. Settings are defined like so:
+
+    var $table = $("#mytable");
+    $table.stupidtable_settings({
+        // Settings for this table specified here
+    });
+    $table.stupidtable();
+
+Listed below are the available settings.
+
+### will_manually_build_table
+
+(Introduced in verison 1.1.1)
+
+Options:
+
+* `true`
+* `false` (default)
+
+By default, every time a column is sorted, stupidtable reads the DOM to extract
+all the values from the table. For tables that will not change or for very large
+tables, this behavior may be suboptimal.  To modify this behavior, set the
+`will_manually_build_table` setting to `true`. However, you will be responsible
+for informing stupidtable that the table has been modified by calling
+`$table.stupidtable_build()`.
+
+    var $table = $("#mytable");
+    $table.stupidtable_settings({
+        will_manually_build_table: true
+    });
+    $table.stupidtable();
+
+    // Make some modification to the table, such as deleting a row
+    ...
+    ...
+
+    // Since will_manually_build_table is true, we must build the table in order
+    // for future sorts to properly handle our modifications.
+    $table.stupidtable_build();
+
+### should_redraw
+
+(Introduced in verison 1.1.0)
+
+The `should_redraw` setting allows you to specify a function that determines
+whether or not the table should be redrawn after it has been internally sorted.
+
+The `should_redraw` function takes a `sort_info` object as an argument. The
+object keys available are:
+
+*  `column` - An array representing the sorted column. Each element of the array is of the form `[sort_val, $tr, index]`
+*  `sort_dir` - `"asc"` or `"desc"`
+*  `$th` - The jquery object of the `<th>` element that was clicked
+*  `th_index` - The index of the `<th>` element that was cliked
+*  `$table` - The jquery object of the `<table>` that contains the `<th>` that was clicked
+*  `datatype` - The datatype of the column
+*  `compare_fn` - The sort/compare function associated with the `<th>` clicked.
+
+**Example**: If you want to prevent stupidtable from redrawing the table if the
+column sorted has all identical values, you would do the following:
+
+    var $table = $("#mytable");
+    $table.stupidtable_settings({
+        should_redraw: function(sort_info){
+          var sorted_column = sort_info.column;
+          var first_val = sorted_column[0];
+          var last_val = sorted_column[sorted_column.length - 1][0];
+
+          // If first and last element of the sorted column are the same, we
+          // can assume all elements are the same.
+          return sort_info.compare_fn(first_val, last_val) !== 0;
+        }
+    });
+    $table.stupidtable();
+
 License
 -------
 
diff --git a/bower.json b/bower.json
index cd99d03..77d9d30 100644
--- a/bower.json
+++ b/bower.json
@@ -1,12 +1,12 @@
 {
   "name": "jquery-stupid-table",
-  "version": "1.0.2",
+  "version": "1.1.2",
   "homepage": "https://github.com/joequery/Stupid-Table-Plugin",
   "authors": [
     "Joseph McCullough"
   ],
   "description": "A stupidly small and simple jQuery table sorter plugin",
-  "main": "stupidtable.min.js",
+  "main": "stupidtable.js",
   "dependencies": {
     "jquery": ">= 1.7.0"
   },
diff --git a/examples/basic.html b/examples/basic.html
index 4cf7f97..c7f8146 100644
--- a/examples/basic.html
+++ b/examples/basic.html
@@ -41,7 +41,7 @@
       <tr>
         <th data-sort="int">int</th>
         <th data-sort="float">float</th>
-        <th data-sort="string">string</th>
+        <th data-sort="string" data-sort-onload="yes">string</th>
       </tr>
     </thead>
     <tbody>
diff --git a/examples/multicolumn-sort.html b/examples/multicolumn-sort.html
new file mode 100644
index 0000000..17d6026
--- /dev/null
+++ b/examples/multicolumn-sort.html
@@ -0,0 +1,119 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Stupid jQuery table sort</title>
+  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
+  <script src="../stupidtable.js?dev"></script>
+  <script>
+    $(function(){
+        $("table").stupidtable();
+    });
+  </script>
+  <style type="text/css">
+    table {
+      border-collapse: collapse;
+    }
+    th, td {
+      padding: 5px 10px;
+      border: 1px solid #999;
+    }
+    th {
+      background-color: #eee;
+    }
+    th[data-sort]{
+      cursor:pointer;
+    }
+    tr.awesome{
+      color: red;
+    }
+  </style>
+  </style>
+</head>
+
+<body>
+
+  <h1>Multicolumn sort</h1>
+
+  <p>This example shows how to perform a multicolumn sort. A multicolumn sort
+  allows you to define what column to sort by in the event of a tie with two
+  elements in the initial column sorted.</p>
+
+  <table>
+    <thead>
+      <tr>
+        <th id="int-column" data-sort="int" data-sort-multicolumn="1,string-column">int</th>
+        <th id="float-column" data-sort="float" data-sort-multicolumn="string-column,int-column">float</th>
+        <th id="string-column" data-sort="string" data-sort-multicolumn="1,0">string</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>1</td>
+        <td>10.0</td>
+        <td>a</td>
+      </tr>
+      <tr>
+        <td>1</td>
+        <td>10.0</td>
+        <td>a</td>
+      </tr>
+      <tr>
+        <td>2</td>
+        <td>10.0</td>
+        <td>b</td>
+      </tr>
+      <tr>
+        <td>0</td>
+        <td>20.0</td>
+        <td>c</td>
+      </tr>
+      <tr>
+        <td>1</td>
+        <td>30.0</td>
+        <td>b</td>
+      </tr>
+      <tr>
+        <td>2</td>
+        <td>30.0</td>
+        <td>a</td>
+      </tr>
+      <tr>
+        <td>0</td>
+        <td>10.0</td>
+        <td>b</td>
+      </tr>
+      <tr>
+        <td>0</td>
+        <td>20.0</td>
+        <td>a</td>
+      </tr>
+      <tr>
+        <td>0</td>
+        <td>10.0</td>
+        <td>c</td>
+      </tr>
+      <tr>
+        <td>1</td>
+        <td>20.0</td>
+        <td>a</td>
+      </tr>
+      <tr>
+        <td>2</td>
+        <td>10.0</td>
+        <td>b</td>
+      </tr>
+      <tr>
+        <td>3</td>
+        <td>30.0</td>
+        <td>a</td>
+      </tr>
+      <tr>
+        <td>2</td>
+        <td>30.0</td>
+        <td>b</td>
+      </tr>
+    </tbody>
+  </table>
+
+</body>
+</html>
diff --git a/examples/with-settings.html b/examples/with-settings.html
new file mode 100644
index 0000000..d138898
--- /dev/null
+++ b/examples/with-settings.html
@@ -0,0 +1,123 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Stupid jQuery table sort</title>
+  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
+  <script src="../stupidtable.js?dev"></script>
+  <script>
+    // ======================================================
+    // Example 1
+    // ======================================================
+    $(function(){
+        var $table = $("#example-1");
+        $table.stupidtable_settings({
+            should_redraw: function(sort_info){
+              var sorted_column = sort_info.column;
+              var first_val = sorted_column[0];
+              var last_val = sorted_column[sorted_column.length - 1][0];
+
+              // If first and last element of the sorted column are the same, we
+              // can assume all elements are the same.
+              return sort_info.compare_fn(first_val, last_val) !== 0;
+            }
+        });
+        $table.stupidtable();
+    });
+
+  </script>
+  <style type="text/css">
+    table {
+      border-collapse: collapse;
+    }
+    th, td {
+      padding: 5px 10px;
+      border: 1px solid #999;
+    }
+    th {
+      background-color: #eee;
+    }
+    th[data-sort]{
+      cursor:pointer;
+    }
+    tr.awesome{
+      color: red;
+    }
+  </style>
+  </style>
+</head>
+
+<body>
+
+  <h1>StupidTable with settings</h1>
+
+  <p>This page shows how specific behaviors can be introduced by providing
+  settings to StupidTable. View the source of this page to see the settings in
+  use.</p>
+
+  <hr/>
+
+  <h2>Example 1</h2>
+
+  <p> This table does not redraw when attempting to sort a column that has identical values in all rows. </p>
+
+  <table id='example-1'>
+    <thead>
+      <tr>
+        <th data-sort="int">int</th>
+        <th data-sort="float">float</th>
+        <th data-sort="string" data-sort-onload="yes">string</th>
+        <th data-sort="int">int (identical)</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>15</td>
+        <td>-.18</td>
+        <td>banana</td>
+        <td>99</td>
+      </tr>
+      <tr class="awesome">
+        <td>95</td>
+        <td>36</td>
+        <td>coke</td>
+        <td>99</td>
+      </tr>
+      <tr>
+        <td>2</td>
+        <td>-152.5</td>
+        <td>apple</td>
+        <td>99</td>
+      </tr>
+      <tr>
+        <td>-53</td>
+        <td>88.5</td>
+        <td>zebra</td>
+        <td>99</td>
+      </tr>
+      <tr>
+        <td>195</td>
+        <td>-858</td>
+        <td>orange</td>
+        <td>99</td>
+      </tr>
+    </tbody>
+  </table>
+
+<pre><code>
+var $table = $("#example-1");
+$table.stupidtable_settings({
+    should_redraw: function(sort_info){
+      var sorted_column = sort_info.column;
+      var first_val = sorted_column[0];
+      var last_val = sorted_column[sorted_column.length - 1][0];
+
+      // If first and last element of the sorted column are the same, we
+      // can assume all elements are the same.
+      return sort_info.compare_fn(first_val, last_val) !== 0;
+    }
+});
+$table.stupidtable();
+</code></pre>
+
+</body>
+</html>
diff --git a/stupidtable.js b/stupidtable.js
index 7821a37..8db085e 100644
--- a/stupidtable.js
+++ b/stupidtable.js
@@ -7,10 +7,53 @@
       sortFns = sortFns || {};
       sortFns = $.extend({}, $.fn.stupidtable.default_sort_fns, sortFns);
       $table.data('sortFns', sortFns);
+      $table.stupidtable_build();
 
       $table.on("click.stupidtable", "thead th", function() {
           $(this).stupidsort();
       });
+
+      // Sort th immediately if data-sort-onload="yes" is specified. Limit to
+      // the first one found - only one default sort column makes sense anyway.
+      var $th_onload_sort = $table.find("th[data-sort-onload=yes]").eq(0);
+      $th_onload_sort.stupidsort();
+    });
+  };
+
+  // ------------------------------------------------------------------
+  // Default settings
+  // ------------------------------------------------------------------
+  $.fn.stupidtable.default_settings = {
+    should_redraw: function(sort_info){
+      return true;
+    },
+    will_manually_build_table: false
+  };
+  $.fn.stupidtable.dir = {ASC: "asc", DESC: "desc"};
+  $.fn.stupidtable.default_sort_fns = {
+    "int": function(a, b) {
+      return parseInt(a, 10) - parseInt(b, 10);
+    },
+    "float": function(a, b) {
+      return parseFloat(a) - parseFloat(b);
+    },
+    "string": function(a, b) {
+      return a.toString().localeCompare(b.toString());
+    },
+    "string-ins": function(a, b) {
+      a = a.toString().toLocaleLowerCase();
+      b = b.toString().toLocaleLowerCase();
+      return a.localeCompare(b);
+    }
+  };
+
+  // Allow specification of settings on a per-table basis. Call on a table
+  // jquery object. Call *before* calling .stuidtable();
+  $.fn.stupidtable_settings = function(settings) {
+    return this.each(function() {
+      var $table = $(this);
+      var final_settings = $.extend({}, $.fn.stupidtable.default_settings, settings);
+      $table.stupidtable.settings = final_settings;
     });
   };
 
@@ -19,9 +62,6 @@
   // Call on a table header.
   $.fn.stupidsort = function(force_direction){
     var $this_th = $(this);
-    var th_index = 0; // we'll increment this soon
-    var dir = $.fn.stupidtable.dir;
-    var $table = $this_th.closest("table");
     var datatype = $this_th.data("sort") || null;
 
     // No datatype? Nothing to do.
@@ -29,30 +69,27 @@
       return;
     }
 
-    // Account for colspans
-    $this_th.parents("tr").find("th").slice(0, $(this).index()).each(function() {
-      var cols = $(this).attr("colspan") || 1;
-      th_index += parseInt(cols,10);
-    });
+    var dir = $.fn.stupidtable.dir;
+    var $table = $this_th.closest("table");
 
-    var sort_dir;
-    if(arguments.length == 1){
-        sort_dir = force_direction;
-    }
-    else{
-        sort_dir = force_direction || $this_th.data("sort-default") || dir.ASC;
-        if ($this_th.data("sort-dir"))
-           sort_dir = $this_th.data("sort-dir") === dir.ASC ? dir.DESC : dir.ASC;
-    }
+    var sort_info = {
+        $th: $this_th,
+        $table: $table,
+        datatype: datatype
+    };
 
-    // Bail if already sorted in this direction
-    if ($this_th.data("sort-dir") === sort_dir) {
-      return;
+
+    // Bring in default settings if none provided
+    if(!$table.stupidtable.settings){
+        $table.stupidtable.settings = $.extend({}, $.fn.stupidtable.default_settings);
     }
-    // Go ahead and set sort-dir.  If immediately subsequent calls have same sort-dir they will bail
-    $this_th.data("sort-dir", sort_dir);
 
-    $table.trigger("beforetablesort", {column: th_index, direction: sort_dir});
+    sort_info.compare_fn = $table.data('sortFns')[datatype];
+    sort_info.th_index = calculateTHIndex(sort_info);
+    sort_info.sort_dir = calculateSortDir(force_direction, sort_info);
+
+    $this_th.data("sort-dir", sort_info.sort_dir);
+    $table.trigger("beforetablesort", {column: sort_info.th_index, direction: sort_info.sort_dir, $th: $this_th});
 
     // More reliable method of forcing a redraw
     $table.css("display");
@@ -60,47 +97,22 @@
     // Run sorting asynchronously on a timout to force browser redraw after
     // `beforetablesort` callback. Also avoids locking up the browser too much.
     setTimeout(function() {
-      // Gather the elements for this column
-      var column = [];
-      var sortFns = $table.data('sortFns');
-      var sortMethod = sortFns[datatype];
-      var trs = $table.children("tbody").children("tr");
+      if(!$table.stupidtable.settings.will_manually_build_table){
+        $table.stupidtable_build();
+      }
+      var table_structure = sortTable(sort_info);
+      var trs = getTableRowsFromTableStructure(table_structure, sort_info);
 
-      // Extract the data for the column that needs to be sorted and pair it up
-      // with the TR itself into a tuple. This way sorting the values will
-      // incidentally sort the trs.
-      trs.each(function(index,tr) {
-        var $e = $(tr).children().eq(th_index);
-        var sort_val = $e.data("sort-value");
-
-        // Store and read from the .data cache for display text only sorts
-        // instead of looking through the DOM every time
-        if(typeof(sort_val) === "undefined"){
-          var txt = $e.text();
-          $e.data('sort-value', txt);
-          sort_val = txt;
-        }
-        column.push([sort_val, tr]);
-      });
-
-      // Sort by the data-order-by value
-      column.sort(function(a, b) { return sortMethod(a[0], b[0]); });
-      if (sort_dir != dir.ASC)
-        column.reverse();
-
-      // Replace the content of tbody with the sorted rows. Strangely
-      // enough, .append accomplishes this for us.
-      trs = $.map(column, function(kv) { return kv[1]; });
+      if(!$table.stupidtable.settings.should_redraw(sort_info)){
+        return;
+      }
       $table.children("tbody").append(trs);
 
-      // Reset siblings
-      $table.find("th").data("sort-dir", null).removeClass("sorting-desc sorting-asc");
-      $this_th.data("sort-dir", sort_dir).addClass("sorting-"+sort_dir);
-
-      $table.trigger("aftertablesort", {column: th_index, direction: sort_dir});
+      updateElementData(sort_info);
+      $table.trigger("aftertablesort", {column: sort_info.th_index, direction: sort_info.sort_dir, $th: $this_th});
       $table.css("display");
-    }, 10);
 
+    }, 10);
     return $this_th;
   };
 
@@ -118,24 +130,152 @@
     return $this_td;
   };
 
-  // ------------------------------------------------------------------
-  // Default settings
-  // ------------------------------------------------------------------
-  $.fn.stupidtable.dir = {ASC: "asc", DESC: "desc"};
-  $.fn.stupidtable.default_sort_fns = {
-    "int": function(a, b) {
-      return parseInt(a, 10) - parseInt(b, 10);
-    },
-    "float": function(a, b) {
-      return parseFloat(a) - parseFloat(b);
-    },
-    "string": function(a, b) {
-      return a.localeCompare(b);
-    },
-    "string-ins": function(a, b) {
-      a = a.toLocaleLowerCase();
-      b = b.toLocaleLowerCase();
-      return a.localeCompare(b);
+
+  $.fn.stupidtable_build = function(){
+    return this.each(function() {
+      var $table = $(this);
+      var table_structure = [];
+      var trs = $table.children("tbody").children("tr");
+      trs.each(function(index,tr) {
+
+        // ====================================================================
+        // Transfer to using internal table structure
+        // ====================================================================
+        var ele = {
+            $tr: $(tr),
+            columns: [],
+            index: index
+        };
+
+        $(tr).children('td').each(function(idx, td){
+            var sort_val = $(td).data("sort-value");
+
+            // Store and read from the .data cache for display text only sorts
+            // instead of looking through the DOM every time
+            if(typeof(sort_val) === "undefined"){
+              var txt = $(td).text();
+              $(td).data('sort-value', txt);
+              sort_val = txt;
+            }
+            ele.columns.push(sort_val);
+        });
+        table_structure.push(ele);
+      });
+      $table.data('stupidsort_internaltable', table_structure);
+    });
+  };
+
+  // ====================================================================
+  // Private functions
+  // ====================================================================
+  var sortTable = function(sort_info){
+    var table_structure = sort_info.$table.data('stupidsort_internaltable');
+    var th_index = sort_info.th_index;
+    var $th = sort_info.$th;
+
+    var multicolumn_target_str = $th.data('sort-multicolumn');
+    var multicolumn_targets;
+    if(multicolumn_target_str){
+        multicolumn_targets = multicolumn_target_str.split(',');
+    }
+    else{
+        multicolumn_targets = [];
     }
+    var multicolumn_th_targets = $.map(multicolumn_targets, function(identifier, i){
+        return get_th(sort_info.$table, identifier);
+    });
+
+    table_structure.sort(function(e1, e2){
+      var multicolumns = multicolumn_th_targets.slice(0); // shallow copy
+      var diff = sort_info.compare_fn(e1.columns[th_index], e2.columns[th_index]);
+      while(diff === 0 && multicolumns.length){
+          var multicolumn = multicolumns[0];
+          var datatype = multicolumn.$e.data("sort");
+          var multiCloumnSortMethod = sort_info.$table.data('sortFns')[datatype];
+          diff = multiCloumnSortMethod(e1.columns[multicolumn.index], e2.columns[multicolumn.index]);
+          multicolumns.shift();
+      }
+      // Sort by position in the table if values are the same. This enforces a
+      // stable sort across all browsers. See https://bugs.chromium.org/p/v8/issues/detail?id=90
+      if (diff === 0)
+        return e1.index - e2.index;
+      else
+        return diff;
+
+    });
+
+    if (sort_info.sort_dir != $.fn.stupidtable.dir.ASC){
+      table_structure.reverse();
+    }
+      return table_structure;
   };
+
+  var get_th = function($table, identifier){
+      // identifier can be a th id or a th index number;
+      var $table_ths = $table.find('th');
+      var index = parseInt(identifier, 10);
+      var $th;
+      if(!index && index !== 0){
+          $th = $table_ths.siblings('#' + identifier);
+          index = $table_ths.index($th);
+      }
+      else{
+          $th = $table_ths.eq(index);
+      }
+      return {index: index, $e: $th};
+  };
+
+  var getTableRowsFromTableStructure = function(table_structure, sort_info){
+    // Gather individual column for callbacks
+    var column = $.map(table_structure, function(ele, i){
+        return [[ele.columns[sort_info.th_index], ele.$tr, i]];
+    });
+
+    /* Side effect */
+    sort_info.column = column;
+
+    // Replace the content of tbody with the sorted rows. Strangely
+    // enough, .append accomplishes this for us.
+    return $.map(table_structure, function(ele) { return ele.$tr; });
+
+  };
+
+  var updateElementData = function(sort_info){
+    var $table = sort_info.$table;
+    var $this_th = sort_info.$th;
+    var sort_dir = $this_th.data('sort-dir');
+    var th_index = sort_info.th_index;
+
+
+    // Reset siblings
+    $table.find("th").data("sort-dir", null).removeClass("sorting-desc sorting-asc");
+    $this_th.data("sort-dir", sort_dir).addClass("sorting-"+sort_dir);
+  };
+
+  var calculateSortDir = function(force_direction, sort_info){
+    var sort_dir;
+    var $this_th = sort_info.$th;
+    var dir = $.fn.stupidtable.dir;
+
+    if(!!force_direction){
+        sort_dir = force_direction;
+    }
+    else{
+        sort_dir = force_direction || $this_th.data("sort-default") || dir.ASC;
+        if ($this_th.data("sort-dir"))
+           sort_dir = $this_th.data("sort-dir") === dir.ASC ? dir.DESC : dir.ASC;
+    }
+    return sort_dir;
+  };
+
+  var calculateTHIndex = function(sort_info){
+    var th_index = 0;
+    var base_index = sort_info.$th.index();
+    sort_info.$th.parents("tr").find("th").slice(0, base_index).each(function() {
+      var cols = $(this).attr("colspan") || 1;
+      th_index += parseInt(cols,10);
+    });
+    return th_index;
+  };
+
 })(jQuery);
diff --git a/tests/test-min.html b/tests/test-min.html
index 4f66396..611a50c 100644
--- a/tests/test-min.html
+++ b/tests/test-min.html
@@ -43,7 +43,47 @@
                     <td>coke</td>
                 </tr>
                 <tr>
-                    <td>2</td>
+                    <td data-sort-value=2>2</td>
+                    <td>-152.5</td>
+                    <td>apple</td>
+                </tr>
+                <tr>
+                    <td>-53</td>
+                    <td>88.5</td>
+                    <td>zebra</td>
+                </tr>
+                <tr>
+                    <td>195</td>
+                    <td>-858</td>
+                    <td>orange</td>
+                </tr>
+            </tbody>
+        </table>
+    </div>
+
+    <div class="tablewrap">
+        <h2>Basic Onload Table</h2>
+        <table id="basic-onload">
+            <thead>
+                <tr>
+                    <th data-sort="int">int</th>
+                    <th data-sort="float">float</th>
+                    <th data-sort="string" data-sort-onload="yes">string</th>
+                </tr>
+            </thead>
+            <tbody>
+                <tr>
+                    <td>15</td>
+                    <td>-.18</td>
+                    <td>banana</td>
+                </tr>
+                <tr class="awesome">
+                    <td>95</td>
+                    <td>36</td>
+                    <td>coke</td>
+                </tr>
+                <tr>
+                    <td data-sort-value=2>2</td>
                     <td>-152.5</td>
                     <td>apple</td>
                 </tr>
@@ -188,6 +228,113 @@
         </table>
     </div>
 
+    <div class="tablewrap">
+        <h2>Stability Testing Table</h2>
+        <table id="stability-test">
+        <thead>
+        <tr>
+            <th>(Unsortable) Index</th>
+            <th data-sort="string-ins">Key</th>
+        </tr>
+        </thead>
+            <tbody>
+                <tr><td>0</td><td>A</td></tr>
+                <tr><td>1</td><td>A</td></tr>
+                <tr><td>2</td><td>A</td></tr>
+                <tr><td>3</td><td>A</td></tr>
+                <tr><td>4</td><td>A</td></tr>
+                <tr><td>5</td><td>A</td></tr>
+                <tr><td>6</td><td>A</td></tr>
+                <tr><td>7</td><td>A</td></tr>
+                <tr><td>8</td><td>A</td></tr>
+                <tr><td>9</td><td>A</td></tr>
+                <tr><td>10</td><td>A</td></tr>
+            </tbody>
+        </table>
+    </div>
+
+    <div class=tablewrap">
+      <h2>Multicolumn sort</h2>
+      <table id='multicolumn-sort-test'>
+        <thead>
+          <tr>
+            <th id="int-column" data-sort="int" data-sort-multicolumn="1,string-column">int</th>
+            <th id="float-column" data-sort="float" data-sort-multicolumn="string-column,int-column">float</th>
+            <th id="string-column" data-sort="string" data-sort-multicolumn="1,0">string</th>
+          </tr>
+        </thead>
+        <tbody>
+          <tr>
+            <td>1</td>
+            <td>10.0</td>
+            <td>a</td>
+          </tr>
+          <tr>
+            <td>1</td>
+            <td>10.0</td>
+            <td>a</td>
+          </tr>
+          <tr>
+            <td>2</td>
+            <td>10.0</td>
+            <td>b</td>
+          </tr>
+          <tr>
+            <td>0</td>
+            <td>20.0</td>
+            <td>c</td>
+          </tr>
+          <tr>
+            <td>1</td>
+            <td>30.0</td>
+            <td>b</td>
+          </tr>
+          <tr>
+            <td>2</td>
+            <td>30.0</td>
+            <td>a</td>
+          </tr>
+          <tr>
+            <td>0</td>
+            <td>10.0</td>
+            <td>b</td>
+          </tr>
+          <tr>
+            <td>0</td>
+            <td>20.0</td>
+            <td>a</td>
+          </tr>
+          <tr>
+            <td>0</td>
+            <td>10.0</td>
+            <td>c</td>
+          </tr>
+          <tr>
+            <td>1</td>
+            <td>20.0</td>
+            <td>a</td>
+          </tr>
+          <tr>
+            <td>2</td>
+            <td>10.0</td>
+            <td>b</td>
+          </tr>
+          <tr>
+            <td>3</td>
+            <td>30.0</td>
+            <td>a</td>
+          </tr>
+          <tr>
+            <td>2</td>
+            <td>30.0</td>
+            <td>b</td>
+          </tr>
+        </tbody>
+      </table>
+    </div>
+
+
+
 </div><!--qunit-fixture-->
 </body>
 </html>
diff --git a/tests/test.html b/tests/test.html
index 469eb10..424f848 100644
--- a/tests/test.html
+++ b/tests/test.html
@@ -43,7 +43,47 @@
                     <td>coke</td>
                 </tr>
                 <tr>
-                    <td>2</td>
+                    <td data-sort-value=2>2</td>
+                    <td>-152.5</td>
+                    <td>apple</td>
+                </tr>
+                <tr>
+                    <td>-53</td>
+                    <td>88.5</td>
+                    <td>zebra</td>
+                </tr>
+                <tr>
+                    <td>195</td>
+                    <td>-858</td>
+                    <td>orange</td>
+                </tr>
+            </tbody>
+        </table>
+    </div>
+
+    <div class="tablewrap">
+        <h2>Basic Onload Table</h2>
+        <table id="basic-onload">
+            <thead>
+                <tr>
+                    <th data-sort="int">int</th>
+                    <th data-sort="float">float</th>
+                    <th data-sort="string" data-sort-onload="yes">string</th>
+                </tr>
+            </thead>
+            <tbody>
+                <tr>
+                    <td>15</td>
+                    <td>-.18</td>
+                    <td>banana</td>
+                </tr>
+                <tr class="awesome">
+                    <td>95</td>
+                    <td>36</td>
+                    <td>coke</td>
+                </tr>
+                <tr>
+                    <td data-sort-value=2>2</td>
                     <td>-152.5</td>
                     <td>apple</td>
                 </tr>
@@ -188,6 +228,113 @@
         </table>
     </div>
 
+    <div class="tablewrap">
+        <h2>Stability Testing Table</h2>
+        <table id="stability-test">
+        <thead>
+        <tr>
+            <th>(Unsortable) Index</th>
+            <th data-sort="string-ins">Key</th>
+        </tr>
+        </thead>
+            <tbody>
+                <tr><td>0</td><td>A</td></tr>
+                <tr><td>1</td><td>A</td></tr>
+                <tr><td>2</td><td>A</td></tr>
+                <tr><td>3</td><td>A</td></tr>
+                <tr><td>4</td><td>A</td></tr>
+                <tr><td>5</td><td>A</td></tr>
+                <tr><td>6</td><td>A</td></tr>
+                <tr><td>7</td><td>A</td></tr>
+                <tr><td>8</td><td>A</td></tr>
+                <tr><td>9</td><td>A</td></tr>
+                <tr><td>10</td><td>A</td></tr>
+            </tbody>
+        </table>
+    </div>
+
+    <div class=tablewrap">
+      <h2>Multicolumn sort</h2>
+      <table id='multicolumn-sort-test'>
+        <thead>
+          <tr>
+            <th id="int-column" data-sort="int" data-sort-multicolumn="1,string-column">int</th>
+            <th id="float-column" data-sort="float" data-sort-multicolumn="string-column,int-column">float</th>
+            <th id="string-column" data-sort="string" data-sort-multicolumn="1,0">string</th>
+          </tr>
+        </thead>
+        <tbody>
+          <tr>
+            <td>1</td>
+            <td>10.0</td>
+            <td>a</td>
+          </tr>
+          <tr>
+            <td>1</td>
+            <td>10.0</td>
+            <td>a</td>
+          </tr>
+          <tr>
+            <td>2</td>
+            <td>10.0</td>
+            <td>b</td>
+          </tr>
+          <tr>
+            <td>0</td>
+            <td>20.0</td>
+            <td>c</td>
+          </tr>
+          <tr>
+            <td>1</td>
+            <td>30.0</td>
+            <td>b</td>
+          </tr>
+          <tr>
+            <td>2</td>
+            <td>30.0</td>
+            <td>a</td>
+          </tr>
+          <tr>
+            <td>0</td>
+            <td>10.0</td>
+            <td>b</td>
+          </tr>
+          <tr>
+            <td>0</td>
+            <td>20.0</td>
+            <td>a</td>
+          </tr>
+          <tr>
+            <td>0</td>
+            <td>10.0</td>
+            <td>c</td>
+          </tr>
+          <tr>
+            <td>1</td>
+            <td>20.0</td>
+            <td>a</td>
+          </tr>
+          <tr>
+            <td>2</td>
+            <td>10.0</td>
+            <td>b</td>
+          </tr>
+          <tr>
+            <td>3</td>
+            <td>30.0</td>
+            <td>a</td>
+          </tr>
+          <tr>
+            <td>2</td>
+            <td>30.0</td>
+            <td>b</td>
+          </tr>
+        </tbody>
+      </table>
+    </div>
+
+
+
 </div><!--qunit-fixture-->
 </body>
 </html>
diff --git a/tests/tests.js b/tests/tests.js
index 3084e14..8e0daf8 100644
--- a/tests/tests.js
+++ b/tests/tests.js
@@ -69,6 +69,8 @@ QUnit.done(function(){
     $("#basic").stupidtable();
     $("#basic-colspan").stupidtable();
     $("#complex-colspan").stupidtable();
+    $("#stability-test").stupidtable();
+    $("#multicolumn-sort-test").stupidtable();
     $("#qunit-fixture").removeClass("test-hidden");
 });
 
@@ -595,31 +597,277 @@ asyncTest("Basic individual column sort - force direction", function(){
     });
 });
 
-asyncTest("No events fired if column sort - force direction doesn't change", function() {
-        var FLOAT_COLUMN = 1;
-    var $table = $("#complex");
+asyncTest("Sort Stability Testing - 1", function(){
+    // Not all browsers implement stable sorting. View the following for more
+    // information:
+    // http://ofb.net/~sethml/is-sort-stable.html
+    // http://codecoding.com/beware-chrome-array-sort-implementation-is-unstable/
+    var INDEX_COLUMN = 0;
+    var LETTER_COLUMN = 1;
+    var $table = $("#stability-test");
     var $table_cols = $table.find("th");
 
-    // Specify a sorting direction
-    $table_cols.eq(FLOAT_COLUMN).data('sort-default', 'desc');
     $table.stupidtable();
+    $table_cols.eq(LETTER_COLUMN).click();
+
+    test_table_state(function(){
+        var expected = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];
+        var vals = get_column_elements($table, INDEX_COLUMN);
+        ok(_.isEqual(vals, expected));
+    });
+});
+
+asyncTest("Sort Stability Testing - 2", function(){
+    // Not all browsers implement stable sorting. View the following for more
+    // information:
+    // http://ofb.net/~sethml/is-sort-stable.html
+    // http://codecoding.com/beware-chrome-array-sort-implementation-is-unstable/
+    var INDEX_COLUMN = 0;
+    var LETTER_COLUMN = 1;
+    var $table = $("#stability-test");
+    var $table_cols = $table.find("th");
+
+    $table.stupidtable();
+    $table_cols.eq(LETTER_COLUMN).doubleclick();
+
+    test_table_state(function(){
+        var expected = ["10", "9", "8", "7", "6", "5", "4", "3", "2", "1", "0"];
+        var vals = get_column_elements($table, INDEX_COLUMN);
+        ok(_.isEqual(vals, expected));
+    });
+});
+
+asyncTest("$th passed to after/before tablesort event handlers", function(){
+    var INT_COLUMN = 0;
+    var $table = $("#basic");
+    var $table_cols = $table.find("th");
+    var $th_objs = [];
+
+    $table.stupidtable();
+    var $int_header = $table_cols.eq(INT_COLUMN)
 
-    var beforeCalls = 0;
-    $table.bind('beforetablesort', function(){
-        beforeCalls++;
+    $table.bind('beforetablesort', function(e, data){
+        $th_objs.push(data.$th);
     });
     var afterCalls = 0;
-    $table.bind('aftertablesort', function(){
-        afterCalls++;
+    $table.bind('aftertablesort', function(e, data){
+        $th_objs.push(data.$th);
     });
 
-    $table_cols.eq(FLOAT_COLUMN).stupidsort('asc');
-    $table_cols.eq(FLOAT_COLUMN).stupidsort('asc');
-    $table_cols.eq(FLOAT_COLUMN).stupidsort('asc');
+    $int_header.click();
+
+    var get_raw_elements = function(arr){
+        return _.map(arr, function(el){
+            return el[0];
+        });
+    };
+
+    test_table_state(function(){
+        var expected = get_raw_elements([$int_header, $int_header]);
+        var raw_th_objs = get_raw_elements($th_objs);
+        ok(_.isEqual(raw_th_objs, expected));
+    });
+});
+
+asyncTest("consective calls to stupidsort in same direction should work (issue #183) ", function(){
+    var INT_COLUMN = 0;
+    var $table = $("#basic");
+    var $table_cols = $table.find("th");
+    var $int_col = $table_cols.eq(INT_COLUMN);
+    var $e_td = $table.find("[data-sort-value=2]");
+
+    $table.stupidtable();
+    $table_cols.eq(INT_COLUMN).stupidsort($.fn.stupidtable.dir.ASC);
+
+    // Verify we have td with the value 2 in the INT column.
+    ok(_.isEqual($e_td.text(), "2"));
+
+    setTimeout(function(){
+        var newval = -100;
+        $e_td.updateSortVal(newval);
+        $e_td.text(newval);
+
+        $table_cols.eq(INT_COLUMN).stupidsort($.fn.stupidtable.dir.ASC);
+
+
+        test_table_state(function(){
+            var expected = ["-100", "-53", "15", "95", "195"];
+            var vals = get_column_elements($table, INT_COLUMN);
+            ok(_.isEqual(vals, expected));
+        });
+
+    }, window.WAIT_TIME_MS);
+});
+
+asyncTest("table sorts column onload when specified (issue #180) ", function(){
+    var STRING_COLUMN = 2;
+    var $table = $("#basic-onload");
+    var $table_cols = $table.find("th");
+    var $str_col = $table_cols.eq(STRING_COLUMN);
+
+    $table.stupidtable();
+
+    test_table_state(function(){
+        var expected = ["apple", "banana", "coke", "orange", "zebra"];
+        var vals = get_column_elements($table, STRING_COLUMN);
+        ok(_.isEqual(vals, expected));
+    });
+});
+
+asyncTest("test should_redraw setting", function(){
+    var INT_COLUMN = 0;
+    var $table = $("#basic");
+    var $table_cols = $table.find("th");
+
+    $table.stupidtable_settings({
+        should_redraw: function(sort_info){
+            return false;
+        }
+    });
+    $table.stupidtable();
+    $table_cols.eq(INT_COLUMN).click();
+
+    test_table_state(function(){
+        // Redrawing will never occur so we should expect the initial order to
+        // be the current column order.
+        var expected = ["15", "95", "2", "-53", "195"];
+        var vals = get_column_elements($table, INT_COLUMN);
+        ok(_.isEqual(vals, expected));
+    });
+});
+
+asyncTest("test will_manually_build_table setting - 1", function(){
+    var INT_COLUMN = 0;
+    var $table = $("#basic");
+    var $table_cols = $table.find("th");
+    var $int_column = $table_cols.eq(INT_COLUMN);
+    var $first_int_td = $table.find("tbody tr td").first();
+
+    $table.stupidtable_settings({
+        will_manually_build_table: true
+    });
+    $table.stupidtable();
+    ok(_.isEqual($first_int_td.text(), "15"));
+
+    $first_int_td.updateSortVal(200);
+    $first_int_td.text("200");
+    $int_column.click();
+
+    test_table_state(function(){
+        // Since we didn't manually build the table after updating the value, we
+        // shouldn't expect the table to sort correctly. 200 will still function
+        // as 15
+        var expected = ["-53", "2", "200", "95", "195"];
+        var vals = get_column_elements($table, INT_COLUMN);
+        ok(_.isEqual(vals, expected));
+    });
+});
+
+asyncTest("test will_manually_build_table setting - 2", function(){
+    var INT_COLUMN = 0;
+    var $table = $("#basic");
+    var $table_cols = $table.find("th");
+    var $int_column = $table_cols.eq(INT_COLUMN);
+    var $first_int_td = $table.find("tbody tr td").first();
+
+    $table.stupidtable_settings({
+        will_manually_build_table: true
+    });
+    $table.stupidtable();
+    ok(_.isEqual($first_int_td.text(), "15"));
+
+    $first_int_td.updateSortVal(200);
+    $first_int_td.text("200");
+
+    // Rebuild the table
+    $table.stupidtable_build();
+    $int_column.click();
+
+    test_table_state(function(){
+        // Since we didn't manually build the table after updating the value, we
+        // shouldn't expect the table to sort correctly. 200 will still function
+        // as 15
+        var expected = ["-53", "2", "95", "195", "200"];
+        var vals = get_column_elements($table, INT_COLUMN);
+        ok(_.isEqual(vals, expected));
+    });
+});
+
+asyncTest("test will_manually_build_table setting - 3", function(){
+    var INT_COLUMN = 0;
+    var $table = $("#basic");
+    var $table_cols = $table.find("th");
+    var $int_column = $table_cols.eq(INT_COLUMN);
+    var $first_int_td = $table.find("tbody tr td").first();
+
+    $table.stupidtable_settings({
+        will_manually_build_table: false
+    });
+    $table.stupidtable();
+    ok(_.isEqual($first_int_td.text(), "15"));
+
+    $first_int_td.updateSortVal(200);
+    $first_int_td.text("200");
+    $int_column.click();
+
+    test_table_state(function(){
+        // Since we didn't manually build the table after updating the value, we
+        // shouldn't expect the table to sort correctly. 200 will still function
+        // as 15
+        var expected = ["-53", "2", "95", "195", "200"];
+        var vals = get_column_elements($table, INT_COLUMN);
+        ok(_.isEqual(vals, expected));
+    });
+});
+
+test("Multicolumn table initial order", function(){
+    var INT_COLUMN = 0;
+    var FLOAT_COLUMN = 1;
+    var STRING_COLUMN = 2;
+    var expected;
+    var vals;
+
+    var $table = $("#multicolumn-sort-test");
+
+    expected = ["1", "1", "2", "0", "1", "2", "0", "0", "0", "1", "2", "3", "2"];
+    vals = get_column_elements($table, INT_COLUMN);
+    ok(_.isEqual(vals, expected));
+
+    expected = ["10.0", "10.0", "10.0", "20.0", "30.0", "30.0", "10.0", "20.0", "10.0", "20.0", "10.0", "30.0", "30.0"];
+    vals = get_column_elements($table, FLOAT_COLUMN);
+    ok(_.isEqual(vals, expected));
+
+    expected = ["a", "a", "b", "c", "b", "a", "b", "a", "c", "a", "b", "a", "b"];
+    vals = get_column_elements($table, STRING_COLUMN);
+    ok(_.isEqual(vals, expected));
+
+});
+
+asyncTest("Basic multicolumn sort", function(){
+    var INT_COLUMN = 0;
+    var FLOAT_COLUMN = 1;
+    var STRING_COLUMN = 2;
+    var $table = $("#multicolumn-sort-test");
+    var $table_cols = $table.find("th");
+
+    $table.stupidtable();
+    $table_cols.eq(INT_COLUMN).click();
 
     test_table_state(function(){
-        ok(_.isEqual(beforeCalls, 1));
-        ok(_.isEqual(afterCalls, 1));
+        var expected;
+        var vals;
+
+        expected = ["0", "0", "0", "0", "1", "1", "1", "1", "2", "2", "2", "2", "3"];
+        vals = get_column_elements($table, INT_COLUMN);
+        ok(_.isEqual(vals, expected));
+
+        expected = ["10.0", "10.0", "20.0", "20.0", "10.0", "10.0", "20.0", "30.0", "10.0", "10.0", "30.0", "30.0", "30.0"];
+        vals = get_column_elements($table, FLOAT_COLUMN);
+        ok(_.isEqual(vals, expected));
+
+        expected = ["b", "c", "a", "c", "a", "a", "a", "b", "b", "b", "a", "b", "a"];
+        vals = get_column_elements($table, STRING_COLUMN);
+        ok(_.isEqual(vals, expected));
     });
 });
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/libjs-jquery-stupidtable.git



More information about the Pkg-javascript-commits mailing list