Search code examples
jqueryhtmltablesorter

Editable widget not responsive in jQuery tablesorter


I'm following along almost exactly with the editable widget example from jQuery tablesorter. The table sort functionality works, but the editable functionality does not (in Chrome or Firefox):

https://jsfiddle.net/uofekcrw/1/

Using:

  • jquery.tablesorter/2.31.1/css/theme.default.min.css
  • jquery-3.3.1.min.js
  • jquery.tablesorter/2.31.1/js/jquery.tablesorter.js
  • jquery.tablesorter/2.31.1/js/jquery.tablesorter.widgets.js

in that order. Am I missing a script here?


HTML:

<!doctype html>
<html lang="en">
<head>
  <title>tablesorter example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

  <!-- load jQuery and tablesorter scripts -->
  <!-- widgets required for editable mode (I think) -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.1/css/theme.blue.min.css" integrity="sha256-Xj5kQBWJMyOV0+sPr+wIBUHXdoZ00TPgT+RuiyOXtzo=" crossorigin="anonymous" />
  <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.1/js/jquery.tablesorter.js" integrity="sha256-vtbCELc4mfidIiNdxWDVPvAK5AI86PbpSotyWoGUyxE=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.1/js/jquery.tablesorter.widgets.js" integrity="sha256-46l1q40VwOPnofvWNG4vQuFjxEnidAIBBn75kgKnI6c=" crossorigin="anonymous"></script>

  <style>
    .tablesorter tbody > tr > td > div[contenteditable=true]:focus {
      outline: #08f 1px solid;
      background: #eee;
      resize: none;
    }
    td.no-edit, span.no-edit {
      background-color: rgba(230,191,153,0.5);
    }
    .focused {
      color: blue;
    }
    td.editable_updated {
      background-color: green;
      color: white;
    }
  </style>
</head>

<body>

  <table id="table" class="tablesorter">
    <thead>
      <tr>
        <th>First Name</th>
        <th>Last Name</th>
        <th>Age</th>
        <th>Total</th>
        <th>Discount</th>
        <th>Date</th>
      </tr>
    </thead>
    <tbody>
      <tr id="db-row-344">
        <td class="no-edit">Peter</td>
        <td>Parker</td>
        <td>28</td>
        <td>$9.99</td>
        <td>20%</td>
        <td>Jul 6, 2006 8:14 AM</td>
      </tr>
      <tr id="db-row-884">
        <td>John</td>
        <td>Hood</td>
        <td>33</td>
        <td>$19.99</td>
        <td>25%</td>
        <td>Dec 10, 2002 5:14 AM</td>
      </tr>
      <tr id="db-row-234">
        <td>Clark</td>
        <td>Kent</td>
        <td>18</td>
        <td>$15.89</td>
        <td>44%</td>
        <td>Jan 12, 2003 11:14 AM</td>
      </tr>
      <tr id="db-row-756">
        <td>Bruce</td>
        <td>Almighty</td>
        <td>45</td>
        <td>$153.19</td>
        <td>44%</td>
        <td>Jan 18, 2001 9:12 AM</td>
      </tr>
      <tr id="db-row-232">
        <td>Bruce</td>
        <td>Evans</td>
        <td>22</td>
        <td>$13.19</td>
        <td>11%</td>
        <td>Jan 18, 2007 9:12 AM</td>
      </tr>
    </tbody>
  </table>

  <script>

$(function() {

  $("#table")
    .tablesorter({
      theme : 'blue',

      widgets: ['editable'],
      widgetOptions: {
        editable_columns       : [0,1,2],       // or "0-2" (v2.14.2); point to the columns to make editable (zero-based index)
        editable_enterToAccept : true,          // press enter to accept content, or click outside if false
        editable_autoAccept    : true,          // accepts any changes made to the table cell automatically (v2.17.6)
        editable_autoResort    : false,         // auto resort after the content has changed.
        editable_validate      : null,          // return a valid string: function(text, original, columnIndex) { return text; }
        editable_focused       : function(txt, columnIndex, $element) {
          // $element is the div, not the td
          // to get the td, use $element.closest('td')
          $element.addClass('focused');
        },
        editable_blur          : function(txt, columnIndex, $element) {
          // $element is the div, not the td
          // to get the td, use $element.closest('td')
          $element.removeClass('focused');
        },
        editable_selectAll     : function(txt, columnIndex, $element) {
          // note $element is the div inside of the table cell, so use $element.closest('td') to get the cell
          // only select everthing within the element when the content starts with the letter "B"
          return /^b/i.test(txt) && columnIndex === 0;
        },
        editable_wrapContent   : '<div>',       // wrap all editable cell content... makes this widget work in IE, and with autocomplete
        editable_trimContent   : true,          // trim content ( removes outer tabs & carriage returns )
        editable_noEdit        : 'no-edit',     // class name of cell that is not editable
        editable_editComplete  : 'editComplete' // event fired after the table content has been edited
      }
    })
    // config event variable new in v2.17.6
    .children('tbody').on('editComplete', 'td', function(event, config) {
      var $this = $(this),
        newContent = $this.text(),
        cellIndex = this.cellIndex, // there shouldn't be any colspans in the tbody
        rowIndex = $this.closest('tr').attr('id'); // data-row-index stored in row id

      // Do whatever you want here to indicate
      // that the content was updated
      $this.addClass( 'editable_updated' ); // green background + white text
      setTimeout(function() {
        $this.removeClass( 'editable_updated' );
      }, 500);

      /*
      $.post("mysite.php", {
        "row"     : rowIndex,
        "cell"    : cellIndex,
        "content" : newContent
      });
      */
    });

});

</script>
</body>
</html>

Solution

  • Quick fix: the editable functionality needs widget-editable.min.js, not just jquery.tablesorter.widgets.js. For confirmation of that, have a look at the example source underlying page HTML.

    Adding:

      <script
        src="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.1/js/widgets/widget-editable.min.js"
        integrity="sha256-s3IhRQ3CEMOyD3EBcKmhdZwkrQXtPA8Z8Lz8sEmjCX8="
        crossorigin="anonymous">
      </script>
    

    Fixed things here.

    Updated JSFiddle:

    https://jsfiddle.net/n7hjow82/