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 4 of 4
  1. #1
    New to the CF scene
    Join Date
    Jun 2011
    Posts
    2
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Sorting an array by Date Desc

    Hi All.

    I have a dynamic Coldfusion form which adds multiple addresses which holds fields like Town, Postcode, ResidentFromDate, ResidentToDate... and on click of the save button I have a script function that runs which I am trying add all the elements of this form into an array and then sort by ResidentFromDate and output the results...

    Here is what I have at the minute but my sort does not seem to be working and is throwing out results in the following order (10/2006, 01/2005, 08/2006, 01/2007) and that is clearing not in descending order...

    If someone could take a look at my script and tell me what is wrong I would be much appreciated (see below)

    * I seem to be getting results and it is just not sorting correctly, so my theory is something is up with the part where I am calling addresses.sort.

    Code:
    var dates = {
        convert:function(d) {
            // Converts the date in d to a date-object. The input can be:
            //   a date object: returned without modification
            //  an array      : Interpreted as [year,month,day]. NOTE: month is 0-11.
            //   a number     : Interpreted as number of milliseconds
            //                  since 1 Jan 1970 (a timestamp) 
            //   a string     : Any format supported by the javascript engine, like
            //                  "YYYY/MM/DD", "MM/DD/YYYY", "Jan 31 2009" etc.
            //  an object     : Interpreted as an object with year, month and date
            //                  attributes.  **NOTE** month is 0-11.
            return (
                d.constructor === Date ? d :
                d.constructor === Array ? new Date(d[0],d[1],d[2]) :
                d.constructor === Number ? new Date(d) :
                d.constructor === String ? new Date(d) :
                typeof d === "object" ? new Date(d.year,d.month,d.date) :
                NaN
            );
        },
        compare:function(a,b) {
            // Compare two dates (could be of any type supported by the convert
            // function above) and returns:
            //  -1 : if a < b
            //   0 : if a = b
            //   1 : if a > b
            // NaN : if a or b is an illegal date
            // NOTE: The code inside isFinite does an assignment (=).
            return (
                isFinite(a=this.convert(a).valueOf()) &&
                isFinite(b=this.convert(b).valueOf()) ?
                (a>b)-(a<b) :
                NaN
            );
        },
    	inRange:function(d,start,end) {
            // Checks if date in d is between dates in start and end.
            // Returns a boolean or NaN:
            //    true  : if d is between start and end (inclusive)
            //    false : if d is before start or after end
            //    NaN   : if one or more of the dates is illegal.
            // NOTE: The code inside isFinite does an assignment (=).
           return (
                isFinite(d=this.convert(d).valueOf()) &&
                isFinite(start=this.convert(start).valueOf()) &&
                isFinite(end=this.convert(end).valueOf()) ?
                start <= d && d <= end :
                NaN
            );
        }
    }
    
    // define array
    var addresses = [];
    	
    	// if atAddrSince is greater than 5 years from today
    	if (atAddrSince > addrFromValidate)
    	{
    		// loop round each previous address
    		for (i=1;i<=maxID;i++)
    		{
    			var addrPart = [];
    			
    			if (eval('document.fmAddPrevAddr.address1'+i))  
    			{
    				var address1 = eval('document.fmAddPrevAddr.address1'+i+'.value');
    				var town = eval('document.fmAddPrevAddr.town'+i+'.value');
    				var country = eval('document.fmAddPrevAddr.country'+i+'.value');
    				var postcode = eval('document.fmAddPrevAddr.postcode'+i+'.value');				
    				var residentfrom = eval('document.fmAddPrevAddr.ataddrsince'+i+'.value');
    				var residentto = eval('document.fmAddPrevAddr.ataddrto'+i+'.value');
    
    				// insert into array	
    				addrPart[0]=address1;
    				addrPart[1]=town;
    				addrPart[2]=country;
    				addrPart[3]=postcode;
    				addrPart[4]=residentfromdate;
    				addrPart[5]=residenttodate;
    					
    				addresses.push(addrPart);
    			}
    		}
    		
    		addresses.sort(sortfunction)
    			
    		function sortfunction(a, b)
    		{
    			if(dates.compare(a[4],b[4]) == -1) 
    			{
    				return true; 
    			}
    			else
    			{
    				return false; 
    			}
    		}
    		
    		for (var v=0;v<addresses.length;v++) 
    		{
    			var addresses1 = addresses[v];
    		
    			alert(addresses1[4]);
    		}
    	}
    Many Thanks,
    George

  • #2
    New to the CF scene
    Join Date
    Jun 2011
    Posts
    2
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Resolved this now with the following code...

    Code:
    		// sort address by resident from DESC
    		addresses.sort(sortfunction)
    			
    		function sortfunction(a, b)
    		{
    		    if (a[4] > b[4])
    		        return -1;
    		    else if (a[4] < b[4])
    		        return 1;
    		    else
    		        return 0;
    		}

  • #3
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,901
    Thanks
    79
    Thanked 4,421 Times in 4,386 Posts
    As a minor point...

    Using eval( ) is generally considered to be evil.

    Instead of doing
    Code:
    			if (eval('document.fmAddPrevAddr.address1'+i))  
    			{
    				var address1 = eval('document.fmAddPrevAddr.address1'+i+'.value');
    				var town = eval('document.fmAddPrevAddr.town'+i+'.value');
    				var country = eval('document.fmAddPrevAddr.country'+i+'.value');
    				var postcode = eval('document.fmAddPrevAddr.postcode'+i+'.value');				
    				var residentfrom = eval('document.fmAddPrevAddr.ataddrsince'+i+'.value');
    				var residentto = eval('document.fmAddPrevAddr.ataddrto'+i+'.value');
    (and so on), you could do
    Code:
        var form = document.fmAddPrevAddr;
        if ( form["address1"+i] != null )
        {
            var address1 = form["address1"+i].value;
            var town = form["town"+i].value;
            var country = form["country"+i].value;
            ... etc. ...

  • #4
    Regular Coder
    Join Date
    Sep 2010
    Location
    Far far away
    Posts
    122
    Thanks
    0
    Thanked 16 Times in 16 Posts
    The next hint -- convert inputs to Date format when create an object:
    Code:
    function convertToDate(d)
    {
    // implement the dates.convert function here
    };
    
    for (var i = 1; i <= maxID; i++) {
        var form = document.fmAddPrevAddr;
        var address = {
            address1: form['address1' + i].value, 
            town: form['town' + i].value, 
            country: form['country' + i].value, 
            postcode: form['postcode' + i].value, 
            residentfrom: convertToDate(form['ataddrsince' + i].value), 
            residentto: convertToDate(form['ataddrto' + i].value) 
        };
        addresses.push(address);
    }
    
    // a.residentfrom and b.residentfrom are Date type fields
    // comparison of Date type values is performed as Number values
    // so the callback function returns 
    // < 0 - a > b
    // = 0 - a == b
    // > 0 - a < b
    addresses.sort(function(a, b)
    {
        return b.residentfrom - a.residentfrom;
    });


  •  

    Posting Permissions

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