Skip to content

Instantly share code, notes, and snippets.

@subtleGradient
Forked from stevesouders/activetable.js
Last active January 10, 2018 16:05

Revisions

  1. subtleGradient revised this gist Jan 10, 2018. 1 changed file with 3 additions and 2 deletions.
    5 changes: 3 additions & 2 deletions activetable.js
    Original file line number Diff line number Diff line change
    @@ -330,7 +330,6 @@ TS.hideSort = function(event) {
    return;
    }

    // Due to event bubbling, we have to make sure the mouse is actually outside of
    // the TH including the "sortlink"s. See http://www.quirksmode.org/js/events_mouse.html.
    var relTarget = (event.relatedTarget) ? event.relatedTarget : event.toElement;
    while ( target != relTarget && "sortlink" != relTarget.className && "BODY" != relTarget.nodeName ) {
    @@ -491,7 +490,9 @@ TS.getText = function(cell, sortType) {
    };

    TS._makeStringSortable = function(string){
    return String(string).trim().replace(/,/g, '');
    string = String(string).trim().replace(/,/g, '');
    if (+string == string) return +string;
    return string;
    };


  2. subtleGradient revised this gist Jan 10, 2018. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions activetable.js
    Original file line number Diff line number Diff line change
    @@ -26,6 +26,7 @@ function init() {
    var th = aThs[j];
    th.colnum = j;
    th.addEventListener("click", thClick, false);
    th.style.cssText += TS.TH_CSS;
    $(th).mouseenter( function(e) { thHover(this, e); } );
    $(th).mouseleave( function(e) { ATpopup.style.visibility = "hidden"; } );
    if ( aHidden[th.innerHTML] ) {
    @@ -272,6 +273,7 @@ You can add tablesort.js asynchronously this way:
    var TS = {};
    TS.bIE = ( -1 != navigator.userAgent.indexOf("MSIE"));

    TS.TH_CSS = "; position:sticky; top:0px;";

    TS.init = function() {
    var aTables = document.getElementsByTagName('table');
  3. subtleGradient revised this gist Jan 10, 2018. 1 changed file with 13 additions and 2 deletions.
    15 changes: 13 additions & 2 deletions activetable.js
    Original file line number Diff line number Diff line change
    @@ -488,12 +488,23 @@ TS.getText = function(cell, sortType) {
    return text;
    };

    TS._makeStringSortable = function(string){
    return String(string).trim().replace(/,/g, '');
    };


    TS.sortfuncAbc = function(a, b) {
    if ( a[0] == b[0] ) {
    return TS.realSortfuncAbc(
    TS._makeStringSortable(a[0]),
    TS._makeStringSortable(b[0])
    );
    };

    TS.realSortfuncAbc = function(a, b) {
    if ( a == b ) {
    return 0;
    }
    if ( a[0] < b[0] ) {
    if ( a < b ) {
    return -1;
    }

  4. @stevesouders stevesouders revised this gist Jul 16, 2013. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions activetable.js
    Original file line number Diff line number Diff line change
    @@ -411,6 +411,9 @@ TS.sort = function(elem, bCba) {

    // find the column #
    var aThs = table.getElementsByTagName('th');
    if ( 0 === aThs.length ) {
    aThs = table.getElementsByTagName('td');
    }
    var len = aThs.length;
    var iCol;
    var iTd = 0;
  5. @stevesouders stevesouders revised this gist Jul 16, 2013. 1 changed file with 35 additions and 16 deletions.
    51 changes: 35 additions & 16 deletions activetable.js
    Original file line number Diff line number Diff line change
    @@ -430,23 +430,38 @@ TS.sort = function(elem, bCba) {
    };


    TS.bIntColumn = true;

    TS.sortTable = function(table, iCol, bCba, sortType) {
    var row_array = [];
    var tbody = table.tBodies[0];
    var rows = tbody.rows;
    var len = rows.length;
    for ( var iRow=0; iRow < len; iRow++) {
    row_array.push( [ TS.getText(rows[iRow].cells[iCol], sortType), rows[iRow] ] );
    }
    var row_array = [];
    var tbody = table.tBodies[0];
    var rows = tbody.rows;
    var len = rows.length;
    TS.bIntColumn = true;
    for ( var iRow=0; iRow < len; iRow++) {
    var cell = rows[iRow].cells[iCol];
    var text = TS.getText(cell, sortType);
    row_array.push( [ text, rows[iRow] ] );
    }

    row_array.sort(bCba ? TS.sortfuncCba : TS.sortfuncAbc );
    len = row_array.length;
    for ( var iRow=0; iRow < len; iRow++ ) {
    var row = row_array[iRow][1];
    row.className = ( 0 === (iRow % 2) ? "odd" : "even" );
    tbody.appendChild(row);
    }
    delete row_array;
    if ( TS.bIntColumn && "sortnum" != sortType ) {
    sortType = "sortnum";
    row_array = [];
    for ( var iRow=0; iRow < len; iRow++) {
    var cell = rows[iRow].cells[iCol];
    var text = TS.getText(cell, sortType);
    row_array.push( [ text, rows[iRow] ] );
    }
    }

    row_array.sort(bCba ? TS.sortfuncCba : TS.sortfuncAbc );
    len = row_array.length;
    for ( var iRow=0; iRow < len; iRow++ ) {
    var row = row_array[iRow][1];
    row.className = ( 0 === (iRow % 2) ? "odd" : "even" );
    tbody.appendChild(row);
    }
    delete row_array;
    };


    @@ -459,8 +474,12 @@ TS.getText = function(cell, sortType) {
    ( "undefined" != typeof(cell.innerText) ? cell.innerText :
    ( "undefined" != typeof(cell.text) ? cell.text : cell.innerHTML ) ) );

    var numtext = Number(text);
    if ( "sortnum" === sortType ) {
    text = parseInt(text);
    text = numtext;
    }
    else if ( text != numtext ) {
    TS.bIntColumn = false;
    }

    return text;
  6. @stevesouders stevesouders revised this gist Jul 16, 2013. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions activetable.js
    Original file line number Diff line number Diff line change
    @@ -160,6 +160,9 @@ function hideColumn(th, bUnhide) {
    for ( var i = 1; i < table.rows.length; i++ ) {
    var row = table.rows[i];
    var aTds = row.getElementsByTagName("td");
    if ( 0 === aTds.length ) {
    aTds = row.getElementsByTagName("th"); // we might have ANOTHER row of THs
    }
    if ( aTds.length >= th.colnum + 1 ) {
    var td = aTds[th.colnum];
    td.style.display = ( bUnhide ? "" : "none" );
  7. @stevesouders stevesouders revised this gist Jul 16, 2013. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion activetable.js
    Original file line number Diff line number Diff line change
    @@ -14,7 +14,6 @@ function init() {
    var table = getRowTable(hrow);
    if ( ! table ) {
    dprint("ERROR: Could not find parent table.");
    CVSNO = hrow; return;
    continue;
    }
    table.tablesort = true;
  8. @stevesouders stevesouders revised this gist Jul 16, 2013. 1 changed file with 97 additions and 49 deletions.
    146 changes: 97 additions & 49 deletions activetable.js
    Original file line number Diff line number Diff line change
    @@ -1,24 +1,25 @@
    // ActiveTable - a bookmarklet to make tables sortable and editable

    function init() {
    var aTheads = document.getElementsByTagName("thead");
    var numThead = aTheads.length;
    var aHrows = getHrows();
    var numHrows = aHrows.length;

    var aHidden = getHiddenColumns();
    ATpopup = document.createElement("div");
    ATpopup.style.cssText = "position: absolute; visibility: hidden; padding: 0; font-family: Arial; background-color: rgba(255, 255, 255, 0.9); border-radius: .5em; text-align: center; box-shadow: .05em .05em .5em #00C;";
    ATpopup.innerHTML = "<a href='sort' title='sort' onclick='sortColumn(); return false'><img border=0 src='http://stevesouders.com/images/sort_up_down.png' style='padding-top: 0.2em;'></a><br><a href='hide' style='color: #C00; font-family: monospace; font-size: 1.5em; text-decoration: none;' title='hide' onclick='hideColumn(); return false'>x</a>"; // TODO - use protocol-less URL for img

    for ( var i = 0; i < numThead; i++ ) {
    thead = aTheads[i];
    var table = thead.parentNode;
    table.tablesort = true;
    if ( "table" !== table.tagName.toLowerCase() ) {
    for ( var i = 0; i < numHrows; i++ ) {
    hrow = aHrows[i];
    var table = getRowTable(hrow);
    if ( ! table ) {
    dprint("ERROR: Could not find parent table.");
    CVSNO = hrow; return;
    continue;
    }
    table.tablesort = true;

    aThs = thead.getElementsByTagName("th");
    aThs = getColumns(hrow);
    var numTh = aThs.length;
    var bConfirmed = false;
    var bHide = false;
    @@ -38,13 +39,59 @@ function init() {
    }
    }
    }
    feedback(thead);
    feedback(hrow);
    }

    TS.init();
    }


    // Find the column header rows from every table in the page.
    function getHrows() {
    // Many tables do NOT have a THEAD element. So we search every table and see
    // if the first row contains TH elements.
    var aTables = document.getElementsByTagName("table");
    var numTables = aTables.length;
    var aHrows = [];
    for ( var i = 0; i < numTables; i++ ) {
    var table = aTables[i];
    var row1 = table.getElementsByTagName("tr")[0]; // should we worry about a table with zero TRs?
    //if ( row1 && row1.getElementsByTagName("th").length > 0 ) {
    aHrows.push(row1);
    //}
    }

    return aHrows;
    }


    // A row could be inside THEAD or TBODY. Crawl the ancestors until we find the parent TABLE.
    function getRowTable(row) {
    if ( "table" == row.parentNode.tagName.toLowerCase() ) {
    return row.parentNode;
    }
    else if ( "table" == row.parentNode.parentNode.tagName.toLowerCase() ) {
    return row.parentNode.parentNode;
    }
    else if ( "table" == row.parentNode.parentNode.tagName.toLowerCase() ) {
    return row.parentNode.parentNode;
    }

    return null;
    }


    // Return an array of TH or TD elements from the TR.
    function getColumns(tr) {
    var aCols = tr.getElementsByTagName("th");
    if ( 0 === aCols.length ) {
    aCols = tr.getElementsByTagName("td");
    }

    return aCols;
    }


    function feedback(elem) {
    // overlay a transparent rectangular outline of same dimensions that fades
    var left = $(elem).offset().left,
    @@ -87,6 +134,7 @@ function thClick(e) {
    function sortColumn() {
    th = ATpopup.th;
    if ( ! th ) {
    dprint("ERROR: couldn't find column to sort.");
    return;
    }

    @@ -98,50 +146,50 @@ function sortColumn() {


    function hideColumn(th, bUnhide) {
    if ( ! th ) {
    th = ATpopup.th;
    }

    if ( "th" !== th.tagName.toLowerCase() ) {
    dprint("ERROR: hideColumn: not a TH");
    return;
    }

    th.style.display = ( bUnhide ? "" : "none" );
    th.activetable = true;
    var table = th.parentNode.parentNode.parentNode;
    for ( var i = 1; i < table.rows.length; i++ ) {
    var row = table.rows[i];
    var aTds = row.getElementsByTagName("td");
    if ( aTds.length >= th.colnum + 1 ) {
    var td = aTds[th.colnum];
    td.style.display = ( bUnhide ? "" : "none" );
    }
    }

    if ( th == ATpopup.parentNode ) {
    th.removeChild(ATpopup); // do this so that innerHTML is correct
    }
    saveHiddenColumn(th.innerHTML);
    if ( ! th ) {
    th = ATpopup.th;
    }

    if ( "th" !== th.tagName.toLowerCase() && "td" !== th.tagName.toLowerCase() ) {
    dprint("ERROR: hideColumn: not a TH nor TD.");
    return;
    }

    th.style.display = ( bUnhide ? "" : "none" );
    th.activetable = true;
    var table = getRowTable(th.parentNode);
    for ( var i = 1; i < table.rows.length; i++ ) {
    var row = table.rows[i];
    var aTds = row.getElementsByTagName("td");
    if ( aTds.length >= th.colnum + 1 ) {
    var td = aTds[th.colnum];
    td.style.display = ( bUnhide ? "" : "none" );
    }
    }

    if ( th == ATpopup.parentNode ) {
    th.removeChild(ATpopup); // do this so that innerHTML is correct
    }
    saveHiddenColumn(th.innerHTML);
    }


    function unhideColumns() {
    var aTheads = document.getElementsByTagName("thead");
    var numThead = aTheads.length;

    for ( var i = 0; i < numThead; i++ ) {
    thead = aTheads[i];
    aThs = thead.getElementsByTagName("th");
    var numTh = aThs.length;
    for ( var j = 0; j < numTh; j++ ) {
    var th = aThs[j];
    if ( th.activetable ) {
    hideColumn(th, true);
    }
    }
    }
    removeHiddenColumns();
    var aHrows = getHrows();
    var numHrows = aHrows.length;

    for ( var i = 0; i < numHrows; i++ ) {
    hrow = aHrows[i];
    aThs = getColumns(hrow);
    var numTh = aThs.length;
    for ( var j = 0; j < numTh; j++ ) {
    var th = aThs[j];
    if ( th.activetable ) {
    hideColumn(th, true);
    }
    }
    }
    removeHiddenColumns();
    }


  9. @stevesouders stevesouders revised this gist Jul 8, 2013. 1 changed file with 32 additions and 19 deletions.
    51 changes: 32 additions & 19 deletions activetable.js
    Original file line number Diff line number Diff line change
    @@ -1,11 +1,13 @@
    // ActiveTable - a bookmarklet to make tables sortable and editable

    function init() {
    var aTheads = document.getElementsByTagName("thead");
    var aTheads = document.getElementsByTagName("thead");
    var numThead = aTheads.length;

    var aHidden = getHiddenColumns();
    ATdiv = document.createElement("div");
    ATdiv.style.cssText = "position: absolute; visibility: hidden; padding: 0; font-family: Arial; background-color: rgba(255, 2255, 255, 0.9); border-radius: .5em; text-align: center; box-shadow: .05em .05em .5em #00C;";
    ATdiv.innerHTML = "<a href='sort' title='sort' onclick='sortColumn(); return false'><img border=0 src='http://stevesouders.com/images/sort_up_down.png' style='padding-top: 0.2em;'></a><br><a href='hide' style='color: #C00; font-family: monospace; font-size: 1.5em; text-decoration: none;' title='hide' onclick='hideColumn(); return false'>x</a>"; // TODO - use protocol-less URL for img
    ATpopup = document.createElement("div");
    ATpopup.style.cssText = "position: absolute; visibility: hidden; padding: 0; font-family: Arial; background-color: rgba(255, 255, 255, 0.9); border-radius: .5em; text-align: center; box-shadow: .05em .05em .5em #00C;";
    ATpopup.innerHTML = "<a href='sort' title='sort' onclick='sortColumn(); return false'><img border=0 src='http://stevesouders.com/images/sort_up_down.png' style='padding-top: 0.2em;'></a><br><a href='hide' style='color: #C00; font-family: monospace; font-size: 1.5em; text-decoration: none;' title='hide' onclick='hideColumn(); return false'>x</a>"; // TODO - use protocol-less URL for img

    for ( var i = 0; i < numThead; i++ ) {
    thead = aTheads[i];
    @@ -25,7 +27,7 @@ function init() {
    th.colnum = j;
    th.addEventListener("click", thClick, false);
    $(th).mouseenter( function(e) { thHover(this, e); } );
    $(th).mouseleave( function(e) { ATdiv.style.visibility = "hidden"; } );
    $(th).mouseleave( function(e) { ATpopup.style.visibility = "hidden"; } );
    if ( aHidden[th.innerHTML] ) {
    if ( ! bConfirmed ) {
    bHide = confirm("Hide previously hidden columns?");
    @@ -36,22 +38,35 @@ function init() {
    }
    }
    }
    thead.style.borderColor = "#CC0000"; // show indicator that table was activated
    thead.style.borderWidth = "2px"; // show indicator that table was activated
    feedback(thead);
    }

    TS.init();
    }


    var ATdiv, TH;
    function feedback(elem) {
    // overlay a transparent rectangular outline of same dimensions that fades
    var left = $(elem).offset().left,
    top = $(elem).offset().top,
    w = elem.clientWidth,
    h = elem.clientHeight;
    var div = document.createElement("div");
    div.style.cssText = "position: absolute; margin: 0; background-color: rgba(255, 255, 255, 0.0); box-shadow: .05em .05em .5em #00C; " +
    "left: " + left + "px; top: " + top + "px; width: " + w + "px; height: " + h + "px;";
    document.body.appendChild(div);
    $(div).fadeOut(3000);
    }


    var ATpopup, TH;
    function thHover(th, e) {
    TH = th;
    th.appendChild(ATdiv); // If you don't make the popup a child of the TH, then it'll flicker when you try to click on the popup's links.
    ATdiv.th = th; // use this later when we try to affect columns
    ATdiv.style.visibility = "visible";
    $(ATdiv).offset({left: parseInt( $(th).offset().left + th.clientWidth - ATdiv.clientWidth ),
    top: parseInt( $(th).offset().top + (th.clientHeight/2) - (ATdiv.clientHeight/2)) });
    th.appendChild(ATpopup); // If you don't make the popup a child of the TH, then it'll flicker when you try to click on the popup's links.
    ATpopup.th = th; // use this later when we try to affect columns
    ATpopup.style.visibility = "visible";
    $(ATpopup).offset({left: parseInt( $(th).offset().left + th.clientWidth - ATpopup.clientWidth ),
    top: parseInt( $(th).offset().top + (th.clientHeight/2) - (ATpopup.clientHeight/2)) });
    }


    @@ -70,7 +85,7 @@ function thClick(e) {


    function sortColumn() {
    th = ATdiv.th;
    th = ATpopup.th;
    if ( ! th ) {
    return;
    }
    @@ -84,7 +99,7 @@ function sortColumn() {

    function hideColumn(th, bUnhide) {
    if ( ! th ) {
    th = ATdiv.th;
    th = ATpopup.th;
    }

    if ( "th" !== th.tagName.toLowerCase() ) {
    @@ -104,8 +119,8 @@ function hideColumn(th, bUnhide) {
    }
    }

    if ( th == ATdiv.parentNode ) {
    th.removeChild(ATdiv); // do this so that innerHTML is correct
    if ( th == ATpopup.parentNode ) {
    th.removeChild(ATpopup); // do this so that innerHTML is correct
    }
    saveHiddenColumn(th.innerHTML);
    }
    @@ -166,8 +181,6 @@ function dprint(msg) {
    }




    /*! jQuery v1.10.1 | (c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license
    //@ sourceMappingURL=jquery.min.map
    */
  10. @stevesouders stevesouders revised this gist Jul 8, 2013. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion activetable.js
    Original file line number Diff line number Diff line change
    @@ -459,4 +459,4 @@ TS.findPos = function(obj) {


    init();
    dprint("ActiveTable loaded. Shift+click on a column header to hide the column. Alt+click to restore all columns.");
    dprint("ActiveTable loaded successfully. Hover over a column header to display the popup to sort or remove a column. Alt+click on any column header to restore all columns.");
  11. @stevesouders stevesouders created this gist Jul 8, 2013.
    462 changes: 462 additions & 0 deletions activetable.js
    462 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.