Billy Bobby
Billy Bobby

Reputation: 519

Sorting issue with plain text and html in the same column using Handsontable

I'm having a problem sorting a column which contains plain text as well as html like an anchor tag. The sorting seems to be occurring on the value stored in the data source array rather than the displayed value. The cells containing an anchor tag are always sorted above the plain text cells.

Below is a JSFiddle with an example. What I would like is for the third column to sort alphabetically the names regardless of whether the cell contains an anchor tag or plain text.

Example: http://jsfiddle.net/5sL2jkqt/

{ data: 2, renderer: "html" }

I tried applying a custom cell renderer on the third column but that did not help. Any suggestions on how to get around this would be much appreciated!

Upvotes: 3

Views: 465

Answers (2)

Billy Bobby
Billy Bobby

Reputation: 519

What I did to get around this was to add the following function to the handsontable.full.js

  // Strip out all tags not in the allowed parameter
  function stripTags(input, allowed) {

      if (!input) {
          return "";
      } else if (!isNaN(input)) {
          return input;
      }

      // making sure the allowed arg is a string containing only tags in lowercase (<a><c>)
      allowed = (((allowed || "") + "").toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join("");


      var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
          commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;


      return input.replace(commentsAndPhpTags, "").replace(tags, function ($0, $1) {

          return allowed.indexOf("<" + $1.toLowerCase() + ">") > -1 ? $0 : "";

      });


  };

I then called the stripTags function in the native handsontable function this.sort which adds the content you are sorting into the array this.sortIndex like the following:

this.sortIndex.push([i, stripTags(instance.getDataAtCell(i, this.sortColumn + colOffset), "")]);

Not 100% ideal but worked like a charm. It strips out HTML and sorts on what is left over.

Can also be found on GitHub

Upvotes: 1

ZekeDroid
ZekeDroid

Reputation: 7209

Unfortunately the sorting plugin will always sort on the value rather than what's being displayed. You can, however, implement your own sorting. In this case, it's your best bet.

What you'd do is disable sorting in HOT, then on click of the title, just like with HOT sorting, trigger your sorting function.

This one should act on the data object itself. Make sure to check which header was clicked so that you can translate it into an index. The rest should be straight forward:

Using something like data.sort(function(item1, item2) { //logic }), you can now sort your data array based on whatever characteristic you want. It seems like the easiest way would be to sort based on column index 1 values so you could do:

// item1 is a row and item2 is the row right after it
data.sort(function(item1, item2) {
    return item1[1] > item2[1] ? 1 : -1; // returning 1 makes item1 greater
}
hotInstance.render(); // remember to re-render when done

This would be the easiest way. It also gives you more flexibility down the line. Good luck.

Upvotes: 0

Related Questions