LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-14-2020, 08:54 AM   #1
GPGAgent
Member
 
Registered: Oct 2018
Location: Cornwall UK
Distribution: Mint
Posts: 375

Rep: Reputation: 41
Question Javascript Sort HTML Table Columns - Asc/Desc Indicators


I have two examples of Javascript that sorts a column of a table, one is
very concise but doesn't show the sort order, the other is very long but
does show the sort order. I thought it would be simple to lift the
arrowhead code and put it into the nice concise bit of code but it
defeats me, maybe someone can point me in the right direction - no pun
intended!

With Arrowheads - using ascii codes 25b2 and 25bc

Code:
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>TestSortArrows - html</title>
    
  <script>
 function sortTable(Table, col, dir) {
    var sortClass, i;

    sortTable.sortCol = -1;
    sortClass = Table.className.match(/js-sort-\d+/);
    if (null != sortClass) {
        sortTable.sortCol = sortClass[0].replace(/js-sort-/, '');
        Table.className = Table.className.replace(new RegExp(' ?' + sortClass[0] + '\\b'), '');
    }
    if ('undefined' === typeof col) {
        col = sortTable.sortCol;
    }

    if ('undefined' !== typeof dir) {
        sortTable.sortDir = dir == -1 || dir == 'desc' ? -1 : 1;
    } else {
        sortClass = Table.className.match(/js-sort-(a|de)sc/);
        if (null != sortClass && sortTable.sortCol == col) {
            sortTable.sortDir = 'js-sort-asc' == sortClass[0] ? -1 : 1;
        } else {
            sortTable.sortDir = 1;
        }
    }
    Table.className = Table.className.replace(/ ?js-sort-(a|de)sc/g, '');

    Table.className += ' js-sort-' + col;
    sortTable.sortCol = col;

    Table.className += ' js-sort-' + (sortTable.sortDir == -1 ? 'desc' : 'asc');

    if (col < Table.tHead.rows[Table.tHead.rows.length - 1].cells.length) {
        sortClass = Table.tHead.rows[Table.tHead.rows.length - 1].cells[col].className.match(/js-sort-[-\w]+/);
    }
    for (i = 0; i < Table.tHead.rows[Table.tHead.rows.length - 1].cells.length; i++) {
        if (col == Table.tHead.rows[Table.tHead.rows.length - 1].cells[i].getAttribute('data-js-sort-colNum')) {
            sortClass = Table.tHead.rows[Table.tHead.rows.length - 1].cells[i].className.match(/js-sort-[-\w]+/);
        }
    }
    if (null != sortClass) {
        sortTable.sortFunc = sortClass[0].replace(/js-sort-/, '');
    } else {
        sortTable.sortFunc = 'string';
    }
    Table.querySelectorAll('.js-sort-active').forEach(function(Node) {
        Node.className = Node.className.replace(/ ?js-sort-active\b/, '');
    });
    Table.querySelectorAll('[data-js-sort-colNum="' + col + '"]:not(:empty)').forEach(function(Node) {
        Node.className += ' js-sort-active';
    });

    var rows = [],
        TBody = Table.tBodies[0];

    for (i = 0; i < TBody.rows.length; i++) {
        rows[i] = TBody.rows[i];
    }
    if ('none' != sortTable.sortFunc) {
        rows.sort(sortTable.compareRow);
    }

    while (TBody.firstChild) {
        TBody.removeChild(TBody.firstChild);
    }
    for (i = 0; i < rows.length; i++) {
        TBody.appendChild(rows[i]);
    }
}

sortTable.compareRow = function(RowA, RowB) {
    var valA, valB;
    if ('function' != typeof sortTable[sortTable.sortFunc]) {
        sortTable.sortFunc = 'string';
    }
    valA = sortTable[sortTable.sortFunc](RowA.cells[sortTable.sortCol]);
    valB = sortTable[sortTable.sortFunc](RowB.cells[sortTable.sortCol]);

    return valA == valB ? 0 : sortTable.sortDir * (valA > valB ? 1 : -1);
};

sortTable.stripTags = function(html) {
    return html.replace(/<\/?[a-z][a-z0-9]*\b[^>]*>/gi, '');
};

sortTable.date = function(Cell) {
    // If okDate library is available, Use it for advanced Date processing
    if (okDate) {
        var Date = okDate(sortTable.stripTags(Cell.innerHTML));
        return Date ? Date.getTime() : 0;
    } else {
        return (new Date(sortTable.stripTags(Cell.innerHTML))).getTime() || 0;
    }
};

sortTable.number = function(Cell) {
    return Number(sortTable.stripTags(Cell.innerHTML).replace(/[^-\d.]/g, ''));
};

sortTable.string = function(Cell) {
    return sortTable.stripTags(Cell.innerHTML).toLowerCase();
};

sortTable.raw = function(Cell) {
    return Cell.innerHTML;
};

sortTable.last = function(Cell) {
    return sortTable.stripTags(Cell.innerHTML).split(' ').pop().toLowerCase();
};

sortTable.input = function(Cell) {
    for (var i = 0; i < Cell.children.length; i++) {
        if ('object' == typeof Cell.children[i]
            && 'undefined' != typeof Cell.children[i].value
        ) {
            return Cell.children[i].value.toLowerCase();
        }
    }

    return sortTable.string(Cell);
};

sortTable.none = function(Cell) {
    return null;
};

sortTable.getClickHandler = function(Table, col) {
    return function() {
        sortTable(Table, col);
    };
};

sortTable.init = function() {
    var THead, Tables, Handler;
    if (document.querySelectorAll) {
        Tables = document.querySelectorAll('table.js-sort-table');
    } else {
        Tables = document.getElementsByTagName('table');
    }

    for (var i = 0; i < Tables.length; i++) {
        if (!document.querySelectorAll && null === Tables[i].className.match(/\bjs-sort-table\b/)) {
            continue;
        }

        if (Tables[i].attributes['data-js-sort-table']) {
            continue;
        }

        if (!Tables[i].tHead) {
            THead = document.createElement('thead');
            THead.appendChild(Tables[i].rows[0]);
            Tables[i].insertBefore(THead, Tables[i].children[0]);
        } else {
            THead = Tables[i].tHead;
        }

        for (var rowNum = 0; rowNum < THead.rows.length; rowNum++) {
            for (var cellNum = 0, colNum = 0; cellNum < THead.rows[rowNum].cells.length; cellNum++) {
                THead.rows[rowNum].cells[cellNum].setAttribute('data-js-sort-colNum', colNum);
                Handler = sortTable.getClickHandler(Tables[i], colNum);
                window.addEventListener
                    ? THead.rows[rowNum].cells[cellNum].addEventListener('click', Handler)
                    : window.attachEvent && THead.rows[rowNum].cells[cellNum].attachEvent('onclick', Handler);
                colNum += THead.rows[rowNum].cells[cellNum].colSpan;
            }
        }

        Tables[i].setAttribute('data-js-sort-table', 'true')
    }

    var element = document.createElement('style');
    document.head.insertBefore(element, document.head.childNodes[0]);
    var sheet = element.sheet;
//
// Set up and down arrows using ascii codes 25b2 and 25bc
//
    sheet.insertRule('table.js-sort-asc thead tr > .js-sort-active:not(.js-sort-none):after {content: "\\25b2";font-size: 0.7em;padding-left: 3px;line-height: 0.7em;}', 0);
    sheet.insertRule('table.js-sort-desc thead tr > .js-sort-active:not(.js-sort-none):after {content: "\\25bc";font-size: 0.7em;padding-left: 3px;line-height: 0.7em;}', 0);
};

// Run sortTable.init() when the page loads
window.addEventListener
    ? window.addEventListener('load', sortTable.init, false)
    : window.attachEvent && window.attachEvent('onload', sortTable.init)
    ;

if (typeof NodeList.prototype.forEach !== "function") {
    NodeList.prototype.forEach = Array.prototype.forEach;
}
  </script>  

  </head>
<body>

  <H3>Test Sorting table - TestSortArrows.html</h3>
<!---  <table border=1 cellspacing=0> --->
<table class="js-sort-table"  border=1 cellspacing=0> <!--- id="demo1" --->

  <thead>
    <tr>
      <th>Asset No</th>
      <th>Description</th>
      <th>Location</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>JKEL03001234</td><td>Emergency Light</td><td>Rm 35</td>
    </tr>
    <tr>
      <td>JKEL03001239</td><td>Emergency Light</td><td>Rm 36</td>
    </tr>
    <tr>
      <td>JKEP01001234</td><td>Emergency Power Off</td><td>Rm 37</td>
    </tr>
    <tr>
      <td>JKED03001234</td><td>Emergency Door</td><td>Rm 38</td>
    </tr>
  </tbody>
</table>
</body>
</html>
And the without arrowheads example - I know what to insert. But I don't know how or where exactly.

Code:
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>TestNoSortArrows</title>
    
  <script>
  function sortTable(table, col, reverse) {
    var tb = table.tBodies[0], // use `<tbody>` to ignore `<thead>` and `<tfoot>` rows
        tr = Array.prototype.slice.call(tb.rows, 0), // put rows into array
        i;
    reverse = -((+reverse) || -1);
    tr = tr.sort(function (a, b) { // sort rows
        return reverse // `-1 *` if want opposite order
            * (a.cells[col].textContent.trim() // using `.textContent.trim()` for test
                .localeCompare(b.cells[col].textContent.trim())
               );
    });
    for(i = 0; i < tr.length; ++i) tb.appendChild(tr[i]); // append each row in order
}

function makeSortable(table) {
    var th = table.tHead, i;
    th && (th = th.rows[0]) && (th = th.cells);
    if (th) i = th.length;
    else return; // if no `<thead>` then do nothing
    while (--i >= 0) (function (i) {
        var dir = 1;
        th[i].addEventListener('click', function () {sortTable(table, i, (dir = 1 - dir))});
    }(i));
}

function makeAllSortable(parent) {
    parent = parent || document.body;
    var t = parent.getElementsByTagName('table'), i = t.length;
    while (--i >= 0) makeSortable(t[i]);
}

    window.onload = function () {makeAllSortable();};
  </script>  

  </head>
<body>

  <H3>Test Sorting table - TestNoSortArrows.html</h3>
<!---  <table border=1 cellspacing=0> --->
<table class="js-sort-table" id="demo1" border=1 cellspacing=0>

  <thead>
    <tr>
      <th>Asset No</th>
      <th>Description</th>
      <th>Location</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>JKEL03001234</td><td>Emergency Light</td><td>Rm 35</td>
    </tr>
    <tr>
      <td>JKEL03001239</td><td>Emergency Light</td><td>Rm 36</td>
    </tr>
    <tr>
      <td>JKEP01001234</td><td>Emergency Power Off</td><td>Rm 37</td>
    </tr>
    <tr>
      <td>JKED03001234</td><td>Emergency Door</td><td>Rm 38</td>
    </tr>
  </tbody>
</table>
</body>
</html>
Thanks folks
 
Old 06-15-2020, 01:19 PM   #2
GPGAgent
Member
 
Registered: Oct 2018
Location: Cornwall UK
Distribution: Mint
Posts: 375

Original Poster
Rep: Reputation: 41
I solved this - here is the full improved code, to be honest I did have help
Code:
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>TestNoSortArrows</title>


<script>
    function sortTable(table, col, reverse) {
        var tb = table.tBodies[0], // use `<tbody>` to ignore `<thead>` and `<tfoot>` rows
            tr = Array.prototype.slice.call(tb.rows, 0), // put rows into array
            i;
        reverse = -((+reverse) || -1);
        var sortingClass = '';

        // define class for arrowheads
        if (reverse == 1) sortingClass = 'js-sort-desc';
        else sortingClass = 'js-sort-asc';
        var trHead = table.tHead.rows[0];
        // remove all classes for arrowheads
        for (i = 0; i < trHead.cells.length; i++) {
            trHead.cells[i].classList.remove('js-sort-asc');
            trHead.cells[i].classList.remove('js-sort-desc');
        }
        // set class for current arrowhead
        table.tHead.rows[0].cells[col].classList.add(sortingClass);

        tr = tr.sort(function (a, b) { // sort rows
            return reverse // `-1 *` if want opposite order
                * (a.cells[col].textContent.trim() // using `.textContent.trim()` for test
                    .localeCompare(b.cells[col].textContent.trim())
                );
        });
        for (i = 0; i < tr.length; ++i) tb.appendChild(tr[i]); // append each row in order
    }

    function makeSortable(table) {
        var th = table.tHead, i;
        th && (th = th.rows[0]) && (th = th.cells);
        if (th) i = th.length;
        else return; // if no `<thead>` then do nothing
        while (--i >= 0) (function (i) {
            var dir = 1;
            th[i].addEventListener('click', function () { sortTable(table, i, (dir = 1 - dir)) });
        }(i));

        //
        // Inserted from the Arrowhead script
        //
        var element = document.createElement('style');
        document.head.insertBefore(element, document.head.childNodes[0]);
        var sheet = element.sheet;
        //
        // Set up and down arrows using ascii codes 25b2 and 25bc - but it doesn't work
        //
        // sheet.insertRule('table.js-sort-asc thead tr > .js-sort-active:not(.js-sort-none):after {content: "\\25b2";font-size: 0.7em;padding-left: 3px;line-height: 0.7em;}', 0);
        // sheet.insertRule('table.js-sort-desc thead tr > .js-sort-active:not(.js-sort-none):after {content: "\\25bc";font-size: 0.7em;padding-left: 3px;line-height: 0.7em;}', 1);
        sheet.insertRule('table thead tr > th.js-sort-asc:after {content: "\\25b2";font-size: 0.7em;padding-left: 3px;line-height: 0.7em;}', 0);
        sheet.insertRule('table thead tr > th.js-sort-desc:after {content: "\\25bc";font-size: 0.7em;padding-left: 3px;line-height: 0.7em;}', 1);

        //
        // Inserted from the Arrowhead script
        //

    }

    function makeAllSortable(parent) {
        parent = parent || document.body;
        var t = parent.getElementsByTagName('table'), i = t.length;
        while (--i >= 0) makeSortable(t[i]);
    }
    window.onload = function () { makeAllSortable(); };
</script>

</head>

<body>
    <H3>Test Sorting table - TestNoSortArrows.html</h3>
    <!---  <table border=1 cellspacing=0> --->
    <table class="js-sort-table" border=1 cellspacing=0>
        <!--  id="demo1" -->

    <thead>
        <tr>
            <th>Asset No</th>
            <th>Description</th>
            <th>Location</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>JKEL03001234</td>
            <td>Emergency Light</td>
            <td>Rm 35</td>
        </tr>
        <tr>
            <td>JKEL03001239</td>
            <td>Emergency Light</td>
            <td>Rm 36</td>
        </tr>
        <tr>
            <td>JKEP01001234</td>
            <td>Emergency Power Off</td>
            <td>Rm 37</td>
        </tr>
        <tr>
            <td>JKED03001234</td>
            <td>Emergency Door</td>
            <td>Rm 38</td>
        </tr>
    </tbody>
</table>
</body>

Cheers folks

</html>
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Javascript Sort Table Columns GPGAgent Programming 3 04-22-2020 07:49 AM
Why does open office table only show 16 of 21 columns in table format columns? 1sweetwater! Linux - Software 1 12-03-2014 01:19 PM
[SOLVED] AWK: add columns while keep format for other columns cristalp Programming 3 10-13-2011 06:14 AM
Is there a way to find the size of an html table (javascript?) BrianK Programming 7 10-06-2007 05:03 PM
changing an HTML table with javascript eantoranz Programming 2 10-29-2004 12:21 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:06 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration