Table sort and filter

by Felipe Alfaro

HTML

<input id="testFilter">
<table id="tableExample" border="1" cellpadding="10">
<thead>
    <tr>
        <td>Fruit</td><th>Number</th><th>Letter</th><th>Date</th>
    </tr>
</thead>
<tbody>
    <tr>
        <td>Banana</td><td>05</td><td>g</td><td>2016/01/21</td>
    </tr>
    <tr>
        <td>Orange</td><td>01</td><td>e</td><td>2016/01/30</td>
    </tr>
    <tr>
        <td>Apple</td><td>00</td><td>u</td><td>2016/01/29</td>
    </tr>
    <tr>
        <td>Mango</td><td>10</td><td>x</td><td>2016/01/20</td>
    </tr>
</tbody>
</table>

CSS

th[data-sort],
td[data-sort]{
    position: relative;
    padding-right: 30px;
}
th[data-sort]:after,
td[data-sort]:after{
    content: '';
    display: block;
    position: absolute;
    width: 0;
    height: 0;
    border-style: solid;
    right: 10px;
    top: 50%;
    margin-top: -4px;
    -webkit-transition: 300ms;
    transition: 300ms;
}
th[data-sort='down']:after,
td[data-sort='down']:after{
    border-width: 0 4px 8px 4px;
    border-color: transparent transparent gray transparent;
}
th[data-sort='up']:after,
td[data-sort='up']:after{
    border-width: 8px 4px 0 4px;
    border-color: gray transparent transparent transparent;
}

JavaScript

Element.prototype.sortableTable = function(){
	var table = this,
    	thead = this.getElementsByTagName('thead')[0],
        tbody = this.getElementsByTagName('tbody')[0],
        allTh = thead.querySelectorAll('td,th'),
        trCollection = [],
        colIndex;
    Array.prototype.forEach.call(allTh,function(el){
    	el.style.cursor = 'pointer';
    	el.onclick = function(){
        	var currentTH = this;
            var allTr = tbody.getElementsByTagName('tr');
            Array.prototype.forEach.call(allTr,function(el){
                trCollection.push(el);
            });
            Array.prototype.forEach.call(allTh,function(el){
                if( el != currentTH ){
                	el.removeAttribute('data-sort');
                }
            });
            colIndex = currentTH.cellIndex;
            trCollection.sort(function(a,b){
                var indexedA = a.getElementsByTagName('td')[colIndex],
                    indexedB = b.getElementsByTagName('td')[colIndex];
                if( indexedA.innerHTML < indexedB.innerHTML ) return -1;
                if( indexedA.innerHTML > indexedB.innerHTML ) return 1;
                return 0;
            });
            if ( currentTH.hasAttribute('data-sort') ){
                if( currentTH.getAttribute('data-sort')=='up' ){
                    currentTH.setAttribute('data-sort','down');
                    trCollection.reverse();
                }else{
                    currentTH.setAttribute('data-sort','up');
                }
            }else{
                currentTH.setAttribute('data-sort','up');
            }
            tbody.innerHTML = '';
            Array.prototype.forEach.call(trCollection,function(el){
                tbody.appendChild(el);
            });
        };
    });
};
Element.prototype.filterTable = function(tableId){
	var _input = this,
    	_table = document.getElementById(tableId);
    function _filter(row) {
        var text = row.textContent.toLowerCase(),
       ...