Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 11 of 11
  1. #1
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts

    Sorting tables by date or number

    The following enables sorting of table columns by date or number by (optionally) clicking on the table headers. There is an amount of code to include but it boils down to the following (after the page has loaded):
    Code:
    <script type="text/javascript" src="sorttable.js"></script>
    <script type="text/javascript">
    function init() {
        AddSortToTables();
        AddSortByNumber('todos', 1);
        AddSortByDate('todos', 2, 'd m yyyy');
    }
    window.onload = init;
    </script>
    AddSortToTables() optionally adds the ability to sort in ascending and descending order by clicking the table headers, for any tables with class "sortIt".

    'todos' is the id for the table in my example, and the number 1 refers to the 2nd table-column. Sorting by number ignores pound/dollar signs, commas, extra text, to sort by the raw number that remains (it doesn't change the table-content!).

    To sort correctly by date you need to specify the column number (2 is the 3rd column) and the date-format that is used within this column. The date format can include slashes, commas, and can ignore extraneous text. 'mm' signifies that the month will use a leading zero, and similarly for 'dd'.

    For both AddSortByNumber and AddSortByDate you can supply an array of column numbers, rather than a single column number.

    The JS code includes definitions for $() and AddEvent(). You could remove $() if you've already attached jQuery, and replace AddEvent() if you already have your own version of this function that equalises addEventListener and attachEvent. Added: Actually, you can't just borrow $() from jQuery as the code stands currently - so this whole sequence is designed to work without jQuery.

    The code is more detailed than it might need to be as it includes the ability to sort other elements. For example, a DIV containing P-paragraphs, containing dates in SPAN elements:
    Code:
    AddSortByDate2('div_id', 'p', 'span', 2, 'dd/mm/yy');
    // then use, perhaps, a button:
    <button onclick="SortElements('div_id','p','span',2);">Sort by date.</button>
    // or use AddEvent to attach the event in JS.
    Last edited by AndrewGSW; 09-16-2012 at 08:07 PM.
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  • #2
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts

    Added attribution

    Here is my sample HTML document and I've attached a copy of this and the JS file.

    If you need any assistance or further information I will be happy to oblige.

    Andy.
    Code:
    <!DOCTYPE html>
    <html>
    <head>
    <title>Table Sorting</title>
    
    <style type="text/css">
    table#todos {
        width: 50%;
    }
    table#todos td+td, table#todos td+td+td {
        text-align: right;
    }
    </style>
    
    <script type="text/javascript" src="sorttable.js"></script>
    <script type="text/javascript">
    function init() {
        AddSortToTables();
        AddSortByNumber('todos', 1);
        AddSortByDate('todos', 2, 'd m yyyy');
    }
    window.onload = init;
    </script>
    </head>
    
    <body>	
    <table id="todos" class="sortIt" title="" summary="sorting">
    <thead>
        <tr>
            <th style="text-align:left">To Do</th>
            <th style="text-align:right">Priority</th>
            <th style="text-align:right">Target Date</th>
        </tr>
    </thead>
    <tbody>
        <tr><td>Learn JavaScript!</td><td>1</td><td>4 12 2012</td></tr>
        <tr><td>Write a book</td><td>3</td><td>6 12 2012</td></tr>
        <tr><td>Earn lots of money</td><td>1</td><td>12 12 2012</td></tr>
        <tr><td>Lose 2 pounds</td><td>4</td><td>5 12 2012</td></tr>
        <tr><td>Build a Website!</td><td>2</td><td>5 12 2012</td></tr>
        <tr><td>Work hard</td><td>5</td><td>1 12 2012</td></tr>
        <tr><td>Be good</td><td>200</td><td>1 2 2013</td></tr>
    </tbody>
    </table>
    
    </body>
    </html>
    The .js file is zipped. I could post the actual code but would need to split it over 2 or 3 posts - if requested.
    Attached Files Attached Files
    Last edited by AndrewGSW; 09-17-2012 at 04:24 AM. Reason: js modified to include months arrays
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  • #3
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts
    BTW The code includes a useful function StringToDate:

    Code:
    sNewDate = StringToDate("3 12 2012", "d mm yyyy");
    // can now be converted to a Date:
    dNewDate = new Date(sNewDate);
    It returns a string in the format YYYY/MM/DD which can then be converted to a Date. This would be useful if you use text fields to enter dates (although this is not generally advisable!).

    [It could be revised to return a Date directly from the function, rather than requiring the additional step - new Date().]
    Code:
    var StringToDate = function (sDate, sFormat, cutOff) {
        // Input: a date value as a string, it's format as a string e.g. 'dd-mmm-yy'
        // Optional: a cutoff (integer) for 2 digit years.
        // If no 'd' appears in the format string then the 1st of the month is assumed.
        // If the year is 20 and the cut-off is 30 then the value will be converted to 2020;
        // if the year is 40 then this will be converted to 1940.
        // If no cut-off is supplied then '20' will be pre-pended to the year (YY).
        // Output: a string in the format 'YYYY/MM/DD' or ''
        // Will not attempt to convert certain combinations e.g. DMM, MDD, DDM, YYYYD
        var sParsed, fndSingle;
        // sParsed will be constructed in the format 'YYYY/MM/DD'
        sDate = sDate.toString().toUpperCase();
        sFormat = sFormat.toUpperCase();
        
        if (sFormat.search(/MMMM|MMM/) + 1) {       // replace Mar/March with 03, etc.
            sDate = sDate.replace(new RegExp('(' + ShortMths.join('|') + ')[A-Z]*', 'gi'),
                function (m) {
                var i = ShortMths.indexOf(m.charAt(0).toUpperCase() + 
                    m.substr(1, 2).toLowerCase()) + 1;
                return ((i < 10) ? "0" + i : "" + i).toString();
            });
            sFormat = sFormat.replace(/MMMM|MMM/g, 'MM');
        }
        if (sFormat.search(/DDDD|DDD/) + 1) {       // replace Tue/Tuesday, etc. with ''
            sDate = sDate.replace(new RegExp('(' + ShortDays.join('|') + ')[A-Z]*', 'gi'), '');
            sFormat = sFormat.replace(/DDDD|DDD/g, '');
        }
        sDate = sDate.replace(/(^|\D)(\d)(?=\D|$)/g, function($0, $1, $2) {
            // single digits 2 with 02
            return $1 + '0' + $2;
        });
        sFormat = sFormat.replace(/(^|[^DMY])(D|M)(?=[^DMY]|$)/g, function($0, $1, $2){
            return $1 + $2 + $2;        // replace D or M with DD and MM
        });
        // are there still single Ds or Ms?
        fndSingle = sFormat.search(/(^|[^D])D([^D]|$)|(^|[^M])M([^M]|$)/)+1;
        if ( fndSingle ) return '';     // do not attempt to parse, for example, 'DMM'
        sFormat = sFormat.replace(/(^|[^Y])(YY)(?=[^Y]|$)/g, function($0, $1, $2, index){
            var tempDate = sDate.substr(0, index + 1);
            tempDate += (cutOff) ? ((parseInt(sDate.substr(index + 1, 2),10) > cutOff) ? 
                '19' : '20') : '20';
            tempDate += sDate.substr(index + 1);
            sDate = tempDate;
            return $1 + $2 + $2;
        });
        sParsed = ('YYYY/MM/DD').replace(/YYYY|MM|DD/g, function(m){
            return (sFormat.indexOf(m) + 1) ? sDate.substr(sFormat.indexOf(m), m.length) : '';
        });
        if (sParsed.charAt(0) == '/') {
            // if no year specified, assume the current year
            sParsed = (new Date().getFullYear()) + sParsed;
        }
        if (sParsed.charAt(sParsed.length - 1) == '/') {
            // if no date, assume the 1st of the month
            sParsed += '01';
        }
        return ( sParsed.length == 10 ) ? sParsed : ''; // should end up with 10 characters
    };
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  • #4
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts
    The StringToDate function requires the following arrays if you wish to use it separately:

    Code:
    var MonthNames = ["January", "February", "March", "April", "May", "June", "July", 
        "August", "September", "October", "November", "December"];
    var DayNames = [ "Sunday", "Monday", "Tueday", "Wednesday", "Thursday", 
        "Friday", "Saturday" ];
    var ShortMths = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", 
        "Sep", "Oct", "Nov", "Dec"];
    var ShortDays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  • #5
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts
    In the revised version (attached) I've renamed the dollar function $() to Dlr() to avoid any possible conflict with jQuery - a sensible precaution

    I'm particularly proud of my sorting approach so I've added the following attribution which I would prefer is kept please

    // Sort methods/algorithms attributed:
    // A Gibson http://andrew.dx.am
    It occurs to me that if I have a carousel made of an ol with li's containing an image, title, amount and, perhaps, a date in separate spans, then, using my code, I could sort the carousel at the touch of a button
    Attached Files Attached Files
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  • #6
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts

    Sort tables Part 1

    I've decided to also post the code from sorttable.js in separate posts, as I appreciate that some are uncomfortable opening zip files.
    Code:
    var MonthNames = ["January", "February", "March", "April", "May", "June", "July", 
        "August", "September", "October", "November", "December"];
    var DayNames = [ "Sunday", "Monday", "Tueday", "Wednesday", "Thursday", 
        "Friday", "Saturday" ];
    var ShortMths = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", 
        "Sep", "Oct", "Nov", "Dec"];
    var ShortDays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
      
    var Dlr = function () {
        // Example: var els = Dlr('obj1name',obj2,'obj2name');
        // Saves having to write getElementById repeatedly,
        // but could also be useful for grouping elements.
        var elements = {}, argLen, i, element; 
        for (i = 0, argLen = arguments.length; i < argLen; i++) {
            element = arguments[i];
            if (typeof element === 'string')
                element = document.getElementById(element);
            if (argLen === 1)
                return element;
            elements.push(element);
        }
        return elements;
    };
    var AddEvent = function (elem, eventType, func) {
        if ( elem.addEventListener )
            AddEvent = function (elem, eventType, func) {
                elem.addEventListener(eventType, func, false);
            };
        else if ( elem.attachEvent )
            AddEvent = function (elem, eventType, func) {
                elem.attachEvent('on' + eventType, func);
            };
        else
            AddEvent = function (elem, eventType, func) {
                elem['on' + eventType] = func;
            };
        AddEvent(elem, eventType, func);
    };
    
    // Sort methods/algorithms attributed:
    // A Gibson http://andrew.dx.am
    var SortTable = function (tbl, col) {
        // could be called directly
        SortElements(tbl, 'tr', 'td', col);
    };
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  • #7
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts

    Sort tables Part 2

    Code:
    var SortElements = function (parentEl, childTag, colTag, colIndex) {
        // example use: SortElements('table1','tr','td',2)
        // or SortElements('list1','li')
        // or SortElements('divName','p','span',3)
        var i, j, cTags = {}, startAt = 0,
            parent = Dlr(parentEl), childLen, aChild, elem,
            sortBy, content, elems = [], sortedLen, frag, hdrsLen, hdr;
        
        var AscText = function (a, b) {     // sort() by .data as text
            var x = a.data, y = b.data,
                xNum = parseFloat(x), yNum = parseFloat(y);
                // check if each begin with a number..
            if ( !isNaN(xNum) && !isNaN(yNum) && (xNum - yNum) )
                return xNum - yNum;
            return ((x < y) ? -1 : ((x > y) ? 1 : 0));
        };
        var DescText = function (a, b) {        // sort() by .data
            var x = a.data, y = b.data,
                xNum = parseFloat(x), yNum = parseFloat(y);
                // check if each begin with a number..
            if ( !isNaN(xNum) && !isNaN(yNum) && (yNum - xNum) )
                return yNum - xNum;
            return ((x > y) ? -1 : ((x < y) ? 1 : 0));
        };
        var AscNum = function (a, b) {  // used with dates as well
            return a.data - b.data;
        };
        var DescNum = function (a, b) {
            return b.data - a.data;
        };
        if (parent.nodeName.toLowerCase() == 'table') {
            if ( childTag == 'tr' ) {
                sortBy = parent.rows[0].cells[colIndex].sortBy || 'text';
            }
            parent = parent.tBodies[0] || parent;
            if ( parent.rows[0].cells[0].nodeName.toLowerCase() == 'th' ) {
                startAt = 1;
            }
        }
        cTags = parent.getElementsByTagName(childTag);
        if ( typeof colIndex == 'undefined' ) {
            sortBy = 'text';    // sort simple lists or paragraphs as text
        }
        for (i = startAt, childLen = cTags.length; i < childLen; i++) {
            // ..go forward examining each child
            aChild = cTags[i];
            elem = (colTag) ? aChild.getElementsByTagName(colTag)[colIndex] : aChild;
            if (elem) {
                if ( !sortBy ) {        // sorting non-table columns..
                    sortBy = (typeof elem.numberValue != 'undefined') ? 'number' : 
                        ((typeof elem.dateValue != 'undefined') ? 'date' : 'text');
                }
                switch (sortBy) {
                    // You can supply 'sort' attributes to enable sorting of numbers,etc.
                    // For example, <td sort='2011/02/12'> for a date.
                    case 'text':
                        content = (elem.getAttribute('sort') || 
                            elem.firstChild.nodeValue).toLowerCase();
                        break;
                    case 'number':
                        content = elem.numberValue;
                        break;
                    case 'date':
                        content = elem.dateValue;
                        break;
                    default:
                        content = (elem.getAttribute('sort') || 
                            elem.firstChild.nodeValue).toLowerCase();
                        break;
                }
                j = elems.length;
                if ( !aChild.id ) 
                    aChild.id = 'tempSortID' + j;
                elems[j] = { data: content, tempID: aChild.id };
            }
        }
        // The following will determine if the table/etc has already been sorted 
        // by the same column or tag. If so, it will sort in ascending or descending 
        // order. It creates custom element properties to the parent element to 
        // remember the previous sort details.
        if ( typeof colIndex == 'undefined' ) colIndex = 0;
        if ( parent.prevTag && parent.prevTag == ((typeof colTag == 'undefined') ? 
                childTag : colTag) ) {
            if (parent.prevCol == colIndex) {
                // sorting by the same column as previously
                parent.prevSort = (parent.prevSort == 'asc') ? 'desc' : 'asc';
            } else {                            // sorting by any other column
                parent.prevCol = colIndex;
                parent.prevSort = 'asc';
            }
        } else {
            // sorting for the 1st time or by a different tag
            parent.prevTag = ((typeof colTag == 'undefined') ? childTag : colTag);
            parent.prevCol = colIndex;
            parent.prevSort = 'asc';
        }
        if ( parent.prevSort === 'desc' ) {
            // 'desc' WILL BE the previous sort order..
            switch (sortBy) {
                case 'text': elems.sort(DescText); break;
                case 'number': elems.sort(DescNum); break;
                case 'date': elems.sort(DescNum); break;
                default: elems.sort(DescText); break;
            }
        } else {
            switch (sortBy) {
                case 'text': elems.sort(AscText); break;
                case 'number': elems.sort(AscNum); break;
                case 'date': elems.sort(AscNum); break;
                default: elems.sort(AscText); break;
            }
        }
        frag = document.createDocumentFragment();
        for (i = 0, sortedLen = elems.length; i < sortedLen; i++) {
            elem = Dlr(elems[i].tempID);
            frag.appendChild(elem);
            if ( (elem.id).substr(0,10) == 'tempSortID' )
                elem.removeAttribute('id');
        }
        parent.appendChild(frag);
        elems = null;
        return parent.prevSort;     // not currently used
    };
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  • #8
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts

    Sort tables Part 3 (final)

    Code:
    var AddSortToTables = function () {
        // ..if table has class-name 'sortIt'
        var tables = document.getElementsByTagName('table'), i, j, 
            tblLen, tbl, hdrs, hdrsLen;
        function PreserveSortScope(a,b,c,d) {
            return function () {    // assign the SortElements fn. to a table header
                SortElements(a, b, c, d);
            }
        }
        // add sorting to table headers
        for ( i = 0, tblLen = tables.length; i < tblLen; i++ ) { 
            tbl = tables[i];
            if ( tbl.className.indexOf('sortIt') + 1) {
                hdrs = tbl.getElementsByTagName('th');
                if ( hdrs ) {
                    for ( j = 0, hdrsLen = hdrs.length; j < hdrsLen; j++ ) {
                        AddEvent(hdrs[j],'click',PreserveSortScope(tbl,'tr','td',j));
                        if ( !hdrs[j].title ) hdrs[j].setAttribute('title','Click to sort');
                    }
                }
            }
        }
    };
    var AddSortByDate = function (tbl, col, dateMask) {
        // Input: the table name (or object), a column index (or array) 
        // and a date mask ('dd-mmm-yy')
        // Adds a sortBy = 'date' property to the first row
        // will ignore the first row, assuming it is a header row
        var i, rLen, cell;
        while ( col.length ) AddSortByDate(tbl,col.pop(),dateMask);
        if ((col instanceof Array) || isNaN(col)) return;
        tbl = Dlr(tbl);
        tbl.rows[0].cells[col].sortBy = 'date';
        AddSortByDate2(tbl, 'tr', 'td', col, dateMask);
    };
    var AddSortByDate2 = function (parentEl, childTag, colTag, colIndex, dateMask) {
        var parent = Dlr(parentEl), kids, startAt = 0, i, rLen, cell;
        if ( parent.nodeName.toLowerCase() == 'table' ) {
            parent = parent.tBodies[0] || parent;
            startAt = ( parent.rows[0].cells[0].nodeName.toLowerCase() == 'th' ) * 1;
        }
        kids = parent.getElementsByTagName(childTag);
        for ( i = startAt, rLen =  kids.length; i < rLen; i++) {
            cell = kids[i].getElementsByTagName(colTag)[colIndex];
            if (cell) {
                if ( typeof cell.numberValue != 'undefined' ) delete cell.numberValue;
                // the above enables switching from a number to a date sort 
                // (although v. unlikely)
                cell.dateValue = new Date(StringToDate(cell.firstChild.nodeValue, dateMask));
                if (cell.dateValue.toString() == "NaN" || cell.dateValue.toString() == 
                        "Invalid Date") 
                    cell.dateValue = 0;
            }
        }
    };
    var AddSortByNumber = function (tbl, col) {
        // col is a column index or array of indices
        // will ignore the first row, assuming it is a header row
        var i, rLen, cell, tempNum;
        while ( col.length ) AddSortByNumber(tbl,col.pop());
        if ((col instanceof Array) || isNaN(col)) return;
        tbl = Dlr(tbl);
        tbl.rows[0].cells[col].sortBy = 'number';
        AddSortByNumber2(tbl,'tr','td',col);
    };
    var AddSortByNumber2 = function (parentEl, childTag, colTag, colIndex) {
        var parent = Dlr(parentEl), kids, startAt = 0, i,
            rLen, cell, tempNum;
        if ( parent.nodeName.toLowerCase() == 'table' ) {
            parent = parent.tBodies[0] || parent;
            startAt = ( parent.rows[0].cells[0].nodeName.toLowerCase() == 'th' ) * 1;
        }
        kids = parent.getElementsByTagName(childTag);
        for (i = startAt, rLen = kids.length; i < rLen; i++) {
            cell = kids[i].getElementsByTagName(colTag)[colIndex];
            if (cell) {
                if ( typeof cell.dateValue != 'undefined' ) delete cell.dateValue;
                // the above enables switching from a date to a number sort
                // (although v. unlikely)
                tempNum = cell.firstChild.nodeValue;
                tempNum = tempNum.replace(/[^0-9.-]/g, '');
                cell.numberValue = parseFloat(tempNum);
                if (isNaN(cell.numberValue)) 
                    cell.numberValue = 0.0;
            }
        }
    };
    var StringToDate = function (sDate, sFormat, cutOff) {
        // Input: a date value as a string, it's format as a string e.g. 'dd-mmm-yy'
        // Optional: a cutoff (integer) for 2 digit years.
        // If no 'd' appears in the format string then the 1st of the month is assumed.
        // If the year is 20 and the cut-off is 30 then the value will be converted to 2020;
        // if the year is 40 then this will be converted to 1940.
        // If no cut-off is supplied then '20' will be pre-pended to the year (YY).
        // Output: a string in the format 'YYYY/MM/DD' or ''
        // Will not attempt to convert certain combinations e.g. DMM, MDD, DDM, YYYYD
        var sParsed, fndSingle;
        // sParsed will be constructed in the format 'YYYY/MM/DD'
        sDate = sDate.toString().toUpperCase();
        sFormat = sFormat.toUpperCase();
        
        if (sFormat.search(/MMMM|MMM/) + 1) {       // replace Mar/March with 03, etc.
            sDate = sDate.replace(new RegExp('(' + ShortMths.join('|') + ')[A-Z]*', 'gi'),
                function (m) {
                var i = ShortMths.indexOf(m.charAt(0).toUpperCase() + 
                    m.substr(1, 2).toLowerCase()) + 1;
                return ((i < 10) ? "0" + i : "" + i).toString();
            });
            sFormat = sFormat.replace(/MMMM|MMM/g, 'MM');
        }
        if (sFormat.search(/DDDD|DDD/) + 1) {       // replace Tue/Tuesday, etc. with ''
            sDate = sDate.replace(new RegExp('(' + ShortDays.join('|') + ')[A-Z]*', 'gi'), '');
            sFormat = sFormat.replace(/DDDD|DDD/g, '');
        }
        sDate = sDate.replace(/(^|\D)(\d)(?=\D|$)/g, function($0, $1, $2) {
            // single digits 2 with 02
            return $1 + '0' + $2;
        });
        sFormat = sFormat.replace(/(^|[^DMY])(D|M)(?=[^DMY]|$)/g, function($0, $1, $2){
            return $1 + $2 + $2;        // replace D or M with DD and MM
        });
        // are there still single Ds or Ms?
        fndSingle = sFormat.search(/(^|[^D])D([^D]|$)|(^|[^M])M([^M]|$)/)+1;
        if ( fndSingle ) return '';     // do not attempt to parse, for example, 'DMM'
        sFormat = sFormat.replace(/(^|[^Y])(YY)(?=[^Y]|$)/g, function($0, $1, $2, index){
            var tempDate = sDate.substr(0, index + 1);
            tempDate += (cutOff) ? ((parseInt(sDate.substr(index + 1, 2),10) > cutOff) ? 
                '19' : '20') : '20';
            tempDate += sDate.substr(index + 1);
            sDate = tempDate;
            return $1 + $2 + $2;
        });
        sParsed = ('YYYY/MM/DD').replace(/YYYY|MM|DD/g, function(m){
            return (sFormat.indexOf(m) + 1) ? sDate.substr(sFormat.indexOf(m), m.length) : '';
        });
        if (sParsed.charAt(0) == '/') {
            // if no year specified, assume the current year
            sParsed = (new Date().getFullYear()) + sParsed;
        }
        if (sParsed.charAt(sParsed.length - 1) == '/') {
            // if no date, assume the 1st of the month
            sParsed += '01';
        }
        return ( sParsed.length == 10 ) ? sParsed : ''; // should end up with 10 characters
    };
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  • #9
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts

    Sorting elements

    I thought I would pursue the idea I raised in a previous post:
    the following code allows me to sort a gallery according to an amount or date. It should/will work even if the gallery is within a carousel, a table row, or even a sequence of floated elements - see screenshots (the first is sorted by amount, the second by date, ascending or descending).

    Code:
    <!DOCTYPE html>
    <html>
    <head>
    <title>Sort a Gallery</title>
    <style type="text/css">
    body {
        font-size: 0;
    }
    ul {
        list-style-type: none;
        margin: 0; padding: 0;
    }
    li {
        display: inline-block;
        margin: 0; padding: 0;
        font-size: 12px;
    }
    img, span {
        margin: 0; padding: 0;
    }
    </style>
    <script type="text/javascript" src="sorttable.js"></script>
    <script type="text/javascript">
    function init() {
        // AddSortByNumber/Date are for simple tables,
        // 2 is for other element hierarchies.
        AddSortByNumber2('gallery', 'li', 'span', 0);
        AddSortByDate2('gallery', 'li', 'span', 1, 'dxx mmm yy');
        // the xx's are placeholders for "any two characters".
    }
    window.onload = init;
    </script>
    </head>
    
    <body>
        <button onclick="SortElements('gallery','li','span',0);">Sort by cost</button>
        <button onclick="SortElements('gallery','li','span',1);">Sort by date</button>
    <ul id="gallery" class="sortIt">
        <li><img src="http://lorempixel.com/150/150/sports/1" width="150" height="150">
            <br>Cost <span>&pound;70.00</span><br>
            Available: <span>1st Nov 12</span></li>
        <li><img src="http://lorempixel.com/150/150/sports/2" width="150" height="150">
            <br>Cost <span>&pound;69.99</span><br>
            Available: <span>22nd Nov 12</span></li>
        <li><img src="http://lorempixel.com/150/150/sports/3" width="150" height="150">
            <br>Cost <span>&pound;7.00</span><br>
            Available: <span>3rd Mar 13</span></li>
        <li><img src="http://lorempixel.com/150/150/sports/4" width="150" height="150">
            <br>Cost <span>&pound;12.00</span><br>
            Available: <span>1st Jan 13</span></li>
        <li><img src="http://lorempixel.com/150/150/sports/5" width="150" height="150">
            <br>Cost <span>&pound;20</span><br>
            Available: <span>10th Nov 12</span></li>
    </ul>
    
    </body>
    </html>
    It requires the sorttable.js coded (and attached) in the previous posts. Added: The sorting could equally well be attached to the actual amount or date spans (within the gallery).

    PS I suggest renaming the file to something like andysort.js as there are others already named sorttable.js.
    Attached Thumbnails Attached Thumbnails Sorting tables by date or number-sort1.jpg   Sorting tables by date or number-sort2.jpg  
    Last edited by AndrewGSW; 09-21-2012 at 03:11 PM.
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  • #10
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts
    My last post here (I promise ) - I've combined the previous post's example with my Event Delegation method discussed in another thread, so that I can click on the amounts or dates within the gallery to perform the (ascending or descending) sort.

    Code:
    <!DOCTYPE html>
    <html>
    <head>
    <title>Sort a Gallery</title>
    <style type="text/css">
    body {
        font-size: 0;
    }
    ul {
        list-style-type: none;
        margin: 0; padding: 0;
    }
    li {
        display: inline-block;
        margin: 0; padding: 0;
        font-size: 12px;
    }
    #gallery img, #gallery span {
        margin: 0; padding: 0;
    }
    span.amt, span.dte {
        color: blue;
    }
    span.amt:hover, span.dte:hover {
        background-color: lightgray;
        cursor: pointer;
    }
    </style>
    <script type="text/javascript" src="sorttable.js"></script>
    <script type="text/javascript">
    var addEvent = function (elem, eventType, func) {
        if ( elem.addEventListener )
            addEvent = function (elem, eventType, func) {
                elem.addEventListener(eventType, func, false);
            };
        else if ( elem.attachEvent )
            addEvent = function (elem, eventType, func) {
                elem.attachEvent('on' + eventType, func);
            };
        addEvent(elem, eventType, func);
    };
    
    var delegateEvent = function (elem, childElems, eventType, func, args) {
        addEvent(elem, eventType, function (e) {
            var evt = e || window.event;
            var elem = evt.target || evt.srcElement;
            if ( elem.nodeName.toLowerCase() == childElems.toLowerCase() ) {
                func(elem, args);
            }
        });
    };
    function sortGallery(obj, args) {
        if (obj.className.indexOf('amt') + 1) {
            SortElements('gallery', 'li', 'span', 0);
        } else if (obj.className.indexOf('dte') + 1) {
            SortElements('gallery', 'li', 'span', 1);
        }
    }
    
    function init() {
        // AddSortByNumber/Date are for simple tables,
        // 2 is for other element hierarchies.
        AddSortByNumber2('gallery', 'li', 'span', 0);
        AddSortByDate2('gallery', 'li', 'span', 1, 'dxx mmm yy');
        // the xx's are placeholders for "any two characters".
        delegateEvent(document.getElementById('gallery'), 'span', 'click', sortGallery);
    }
    window.onload = init;
    </script>
    </head>
    
    <body>
        <button onclick="SortElements('gallery','li','span',0);">Sort by cost</button>
        <button onclick="SortElements('gallery','li','span',1);">Sort by date</button>
    <ul id="gallery" class="sortIt">
        <li><img src="http://lorempixel.com/150/150/sports/1" width="150" height="150">
            <br>Cost <span class="amt" title="sort">&pound;70.00</span><br>
            Available: <span class="dte" title="sort">1st Nov 12</span></li>
        <li><img src="http://lorempixel.com/150/150/sports/2" width="150" height="150">
            <br>Cost <span class="amt" title="sort">&pound;69.99</span><br>
            Available: <span class="dte" title="sort">22nd Nov 12</span></li>
        <li><img src="http://lorempixel.com/150/150/sports/3" width="150" height="150">
            <br>Cost <span class="amt" title="sort">&pound;7.00</span><br>
            Available: <span class="dte" title="sort">3rd Mar 13</span></li>
        <li><img src="http://lorempixel.com/150/150/sports/4" width="150" height="150">
            <br>Cost <span class="amt" title="sort">&pound;12.00</span><br>
            Available: <span class="dte" title="sort">1st Jan 13</span></li>
        <li><img src="http://lorempixel.com/150/150/sports/5" width="150" height="150">
            <br>Cost <span class="amt" title="sort">&pound;20</span><br>
            Available: <span class="dte" title="sort">10th Nov 12</span></li>
    </ul>
    
    </body>
    </html>
    Regards, Andy. Live demo.
    Attached Thumbnails Attached Thumbnails Sorting tables by date or number-sort3.jpg  
    Last edited by AndrewGSW; 09-20-2012 at 10:40 PM.
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  • #11
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts
    If anyone has experience of benchmarking/profiling I would appreciate some assistance obtaining timings for my table sorting please. I think my console.log for milliseconds is incorrect in the attached file (I grabbed the expressions from the internet).

    I have 171ms to sort 1000 rows by a date column in Google Chrome using:
    console.time("test");

    console.timeEnd("test");


    This is at entry and exit of the function SortElements().
    Attached Files Attached Files
    Last edited by AndrewGSW; 09-24-2012 at 08:36 PM.
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •