• Demo and Introduction
  • The HTML and CSS Files
  • The jsLib_event.js and jsLib_dom_ready.js Files
  • The report_library.js File
  • The report_library.js File Continued
  • The Complete report_library.js File and the report.js File
  • The report_library.js File Continued

    This page explains the methods of the TableSort object.

    The imageClickHandler Method

    This is the method that runs every time an image is clicked. A parameter called columnName is passed to it. This starts out as the class name of the column. that.sortColumn is the particular class that the table is being sorted by when the arrow is clicked. If the class of the column is the same class that the application is already sorting by, it simply toggles the value of the sortUp property and changes the sorting direction of the column. If these values dont match, the column that the application was sorting by changes its image to the "off" arrows and the value of the sortColumn property changes to the value of the new sorting class. The value of the sortUp property is then reset to true.

    In the next if statement, the application changes the image of the new sorting column to the "on" arrows and sets all other column images to the "off" arrows. Finally, it runs the sort method to sort the new column.

    //the imageClickHandler metho of the TableSort object is a function with one parameter: columnName
    TableSort.prototype.imageClickHandler = function (columnName) {
        //the value of the variable that is this
    	var that = this;
        
        //return the following function
        return function () {
            //if the sortColumn property of that equals the value of columnName
            if ( that.sortColumn == columnName ) {
                //toggle the sortUp property of the that object
    			that.sortUp = ! that.sortUp;
            // otherwise
            } else {
                //the src property of the that.sortColumn item in the imageNodes array is "arrows_off.png"
                that.imageNodes[that.sortColumn].src = "arrows_off.png";
                
                //the value of the sortColumn property of that is the value of ColumnName
                that.sortColumn = columnName;
                //the value of the sortUp property of the that object is true
    			that.sortUp = true;
            }
            
            //if the sortUp property of that has a value of true
            if ( that.sortUp ) {
                //the src property of the that.sortColumn item in the imageNodes array is "arrows_up.png"
    			that.imageNodes[that.sortColumn].src = "arrows_up.png";
            } else {
                //the src property of the that.sortColumn item in the imageNodes array is "arrows_down.png"
    			that.imageNodes[that.sortColumn].src = "arrows_down.png";
            }
    		//execute the sort method of the that object
            that.sort();
        }
    }
    

    The sort Method

    This is the method that sorts all of the information in a particular column so that it is in ascending or descending order. It begins by checking to see if a sorting column has been declared, if not, it returns to the calling function. It also checks to make sure that there is more than one row so that it has something to sort. Next it creates an array of the table rows and removes the first row from the array(the header row) so that it is not sorted along with the other rows. The if statement starting on line 27 determines whether or not the last row is included in the sorting based off of the value of the lastRow property. If it is not supposed to be included, it is temporarily removed from the document and also removed from the array of table rows.

    	//the sort method of the TableSort object is defined as
    TableSort.prototype.sort = function () {
        //the value of the variable that is this
    	var that = this;
        //if the sortColumn property of the TableSort object is an empty string, return to the calling function
    	if ( this.sortColumn == "" ) return;
    
        //the value of the variable rowNodes is an array of the tr tags in the table
        var rowNodes = this.table.getElementsByTagName("tr");
        //if the length of the rowNodes array is equal to or less than 1, return to the calling function
    	if (rowNodes.length <= 1 ) return;
    
        //the value of the variable rows is an empty array
        var rows = [];
        //create a for loop where i equals zero, the for loop runs as long as the value of i is less than the length of the rowNodes array, and i increments by 1 each time
    	for ( var i = 0; i < rowNodes.length; i++) {
            //add the item in the rowNodes array represented by the number i to the end of the rows array.
    		rows.push( rowNodes[i] );
        }
    
        //the value of the variable tbodyNode is the parentNode of the first item in the rows array
        var tbodyNode = rows[0].parentNode;
        
        //remove the first item from the rows array
    	rows.shift();
    	
        
        //if the value of the lastRow property of the that object is false
    	if ( that.lastRow == false ) {
    		//the value of the variable totalsRow is the last item in the rows array
    		var totalsRow = rows[rows.length - 1];
    		//remove the row represented by totalsRow from the tbodyNode
    		totalsRow.parentNode.removeChild(totalsRow);
    		//remove the last item from the rows array
    		rows.pop();		
    	}
    	
    	

    The sort Method Continued

    The second part of the sort method checks to see if the individual row values that will be passed to it later in the code (the value variable) can be converted to dates or monetary values so that it knows how to sort them. It then determines which direction it is supposed to be sorting based on the value of the sortUp property. The sortRows function compares the values in the column to be sorted two rows at a time. First it gets an array of the individual table data values in the first row and determines whether they have the class name that is supposed to be sorted. If they do, it passes their value on to a variable called valueA. It does the same for the second row in the next for loop and passes the table data values that have the correct class name to a variable named valueB.

    	 //the variable isDate is a function with one parameter: value
        var isDate = function ( value ) {
            //the variable d is a new instance of the Date object with a parameter of value
    		var d = new Date(value);
            //return true if value can be converted to a date
    		return ! isNaN(d);
        }
        //the variable isMoney is a function with one parameter: value
    	var isMoney = function ( value ) {
            //the value of the variable m is the replace method of value with the parameters /[$,]/g and an empty string
    		var m = value.replace( /[$,]/g, "" );
            //return true if value is a text string that can be turned into a number
    		return ! isNaN(m);
        }
    
        //the value of the variable direction is 1 if the value of the sortUp property of that is true or -1 if it is false
        var direction = ( that.sortUp ) ? 1 : -1;
        
        //sortRows is a function with the parameters rowA and rowB
        var sortRows = function (rowA, rowB) {
            //create the new variables i, textA, textB, valueA, and valueB
    		var i, textA, textB, valueA, valueB;
            //create the variable cell
    		var cell;
    
            //the value of the variable cellsA is an array of the td tags from rowA
            var cellsA = rowA.getElementsByTagName("td");
            //create a for loop where i equals 0, the loop runs while i is less than the length of the cellsA array, and i increments by 1 on each loop
    		for ( i = 0; i < cellsA.length; i++ ) {
                //the value of cell is the value of the item represented by i in the cellsA array
    			cell = cellsA[i];
                //if the value of the className property of cell equals the value of the sortColumn property of that
    			if ( cell.className == that.sortColumn ) {
                    //the value of valueA is the firstChild nodeValue of  cell
    				valueA = cell.firstChild.nodeValue;
                    //end the function
    				break;
                }
            }
    		  //the value of the variable cellsB is an array of the td tags from rowB
            var cellsB = rowB.getElementsByTagName("td");
            //create a for loop where i equals 0, the loop runs while i is less than the length of the cellsB array, and i increments by 1 on each loop
    		for ( i = 0; i < cellsB.length; i++ ) {
                //the value of cell is the value of the item represented by i in the cellsB array
    			cell = cellsB[i];
                //if the value of the className property of cell equals the value of the sortColumn property of that
    			if ( cell.className == that.sortColumn ) {
                    //the value of valueB is the firstChild nodeValue of cell
    				valueB = cell.firstChild.nodeValue;
                    //end the function
    				break;
                }
            }
    	

    The Final Portion of the sort Method

    The last section of the sort method compares the values of valueA and valueB so that it can sort the order of the column. First it checks to see if they are numbers, dates, or monetary values using the methods we saw defined earlier in the code such as isDate and isMoney. If they are numbers, the application converts them to numbers with decimal places so that they can be compared. If they are dates, the application creates new date objects using valueA and valueB. If the values are monetary values, it removes extra characters such as dollar signs so that the numbers can be easily compared.

    In line 22, the application compares the values of valueA and valueB and returns a value of one, zero, or negative one one depending on how the values compare and on the value of direction (recall that the value of direction is 1 if it's ascending and -1 if it's descending.). In line 37 the application calls the sortRows function to run and compare the row values in the rows array. At the end of this method, a for loop is run to add the newly sorted rows back into the document. If the final row was removed to prevent it from being sorted, it is also added back to the document after all of the sorted rows.

    
    
            //if valueA and valueB are numbers 
            if ( ! isNaN(valueA) && ! isNaN(valueB) ) {
                //the value of valueA is valueA converted to a number with decimal places
    			valueA = parseFloat(valueA);
                //the value of valueB is valueB converted to a number with decimal places
    			valueB = parseFloat(valueB);
            //otherwise, if valueA and valueB can be converted to dates
    		} else if ( isDate(valueA) && isDate(valueB) ) {
                //the value of valueA is a new date object with the parameter of valueA
    			valueA = new Date(valueA);
                //the value of valueB is a new date object with the parameter of valueB
    			valueB = new Date(valueB);
            //otherwise, if valueA and valueB are money values
    		} else if ( isMoney(valueA) && isMoney(valueB) ) {
                //the value of valueA is valueA converted to a number with decimal places that has the dollar signs and commas replaced with empty strings
    			valueA = parseFloat(valueA.replace( /[$,]/g, "" ));
                //the value of valueB is valueB converted to a number with decimal places that has the dollar signs and commas replaced with empty strings
    			valueB = parseFloat(valueB.replace( /[$,]/g, "" ));
            }
    
            //if the value of valueA is less than the value of valueB
            if ( valueA < valueB ) {
                //return -1 multiplied by the value of direction
    			return -1 * direction;
            //otherwise if the value of valueB is less than the value of valueA
    		} else if ( valueB < valueA ) {
                //return 1 multiplied by the value of direction
    			return 1 * direction;
            //otherwise
    		} else {
                //return the number 0
    			return 0;
            }
        }
        
        //execute the sort method of the rows array with the parameter of the function sortRows
        rows.sort( sortRows );
    
        //create a for loop where i equals 0, the loop continues as long as the value of i is less than the length of the rows array, and the value of i is incremented each time through the loop
        for ( i = 0; i < rows.length; i++) {
            //execute the appendChild method of tbodyNode with the parameter of the item in the rows array represented by i
    		tbodyNode.appendChild( rows[i] );
        }
    	
    	//if totalsRow exists in this object
    	if (totalsRow) {
    		//execute the appendChild method of tbodyNode with the parameter of totalsRow
    		tbodyNode.appendChild( totalsRow );
    	}
    }
    	

    Previous Next