Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Problem with Sort Table JavaScript? 1

Status
Not open for further replies.

Happy100

Technical User
Jun 25, 2004
102
GB
Hi

I have kindly been given an example of a JavaScript to sort tables. -

I have added the script to my page above. I've got it to work,
all except the Weekly Rates column and I think that because
I have numeric and text on the same column.

Can anyone advise what JavaScript code change is needed for this?

Many thanks

Happy
 
It's funny - when you look at code that you wrote a long time ago you say "I can do better" and I'm sure I can, but here's the quick and dirty fix - I will see what I can do about cross-browser compatability.

BTW - I only looked at whole numbers so if you have data where you need to compare 5.75 to 5.5, I would need to rework it a bit...

Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Test JavaScript Sort Table</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<SCRIPT>
var allNums = false;        // boolean variable to see if whole column is numeric
var allDates = false;        // boolean variable to see if column vals are all dates
var lastSort = -1;                // variable to hold last column number sorted
var absOrder = true;        // boolean to sort in reverse if on same column
//-----------------------------------------------------------------------
function setDataType(inValue) {
    // This function checks data type of a value
    //         - sets allNums to false if a non-number is found
    //        - sets allDates to false if a non-date is found
    var isDate = new Date(inValue);
    if (isDate == "NaN") {
        if (isNaN(inValue)){
            // The value is a string, make all characters in
            // String upper case to assure proper a-z sort
            inValue =  inValue.toUpperCase();
            allNums = false
            allDates = false
            return inValue;
          }
        else {
            // Value is a number, make sure it is not treated as a string
            allDates = false
            return parseFloat(1*inValue);
          }
        }
  else {
        // Value to sort is a date
        allNums = false
        return inValue ;
      }
  }
//-----------------------------------------------------------------------
function sortTable(col, inTable){
    if (lastSort == col){
        // sorting on same column twice = reverse sort order
        absOrder ? absOrder = false : absOrder = true
    }
    else{
        absOrder = true
    }
    lastSort = col
    allTR = document.getElementById(inTable).childNodes[0].childNodes
    // allTR now holds all the rows in the dataTable
    totalRows = allTR.length
    colToSort = new Array()        //holds all the cells in the column to sort
    colArr = new Array()                //holds all the rows that correspond to the sort cell
    copyArr = new Array()            //holds an original copy of the sort data  to match to colArr
    resultArr = new Array()            //holds the output 

    allNums = true
    allDates = true
    
    //store the original data
    //remember that the first row - [0] -  has column headings
    //so start with the second row - [1]
    //and load the contents of the cell into the array that will be sorted
    for (x=1; x < totalRows; x++){
        colToSort[x-1] = setDataType(allTR[x].childNodes[col].innerText)
        colArr[x-1] = allTR[x]
    }
    //make a copy of the original
    for (x=0; x<colToSort.length; x++){
        copyArr[x] = colToSort[x]
    }

    //sort the original data based on data type
    if (allNums){
        colToSort.sort(numberOrder)
    }
    else if (allDates){
        colToSort.sort(dateOrder)
    }
    else{
        colToSort.sort(textOrder)
    }

    //match copy to sorted
    for(x=0; x<colToSort.length; x++){
        for(y=0; y<copyArr.length; y++){
            if (colToSort[x] == copyArr[y]){
                boolListed = false
                //searcg the ouput array to make sure not to use duplicate rows
                for(z=0; z<resultArr.length; z++){
                    if (resultArr[z]==y){
                        boolListed = true
                        break;
                    }
                }
                if (!boolListed){
                    resultArr[x] = y
                    break;
                }
            }
        }
    }
    //now display the results - it is as simple as swapping rows
    for (x=0; x<resultArr.length; x++){
        allTR[x+1].swapNode(colArr[resultArr[x]])
    }
}
//-----------------------------------------------------------------------
function numberOrder(a,b){ 
    absOrder ? rVal = b - a : rVal = a - b
    return rVal
}
//-----------------------------------------------------------------------
function dateOrder(a,b){
    absOrder ? rVal = Date.parse(a) - Date.parse(b) : rVal = Date.parse(b) - Date.parse(a)
    return rVal
}
//-----------------------------------------------------------------------
function textOrder(a,b){
    if (a.toString() < b.toString()){
        absOrder ? rVal = -1 : rVal = 1
    }
    else{
        absOrder ? rVal = 1 : rVal = -1
    }
    return rVal
}

[blue]function numberSort(col, inTable){
    if (lastSort == col){
        // sorting on same column twice = reverse sort order
        absOrder ? absOrder = false : absOrder = true
    }
    else{
        absOrder = true
    }
    lastSort = col
    allTR = document.getElementById(inTable).childNodes[0].childNodes
    // allTR now holds all the rows in the dataTable
    totalRows = allTR.length
    colToSort = new Array()        //holds all the cells in the column to sort
    colArr = new Array()                //holds all the rows that correspond to the sort cell
    copyArr = new Array()            //holds an original copy of the sort data  to match to colArr
    resultArr = new Array()            //holds the output 
    //store the original data
    //remember that the first row - [0] -  has column headings
    //so start with the second row - [1]
    //and load the contents of the cell into the array that will be sorted
    for (x=1; x < totalRows; x++){
        colToSort[x-1] = findFirstNumber(allTR[x].childNodes[col].innerText)
        colArr[x-1] = allTR[x]
    }
    //make a copy of the original
    for (x=0; x<colToSort.length; x++){
        copyArr[x] = colToSort[x]
    }

   colToSort.sort(numberOrder)

    //match copy to sorted
    for(x=0; x<colToSort.length; x++){
        for(y=0; y<copyArr.length; y++){
            if (colToSort[x] == findFirstNumber(copyArr[y])){
                boolListed = false
                //search the ouput array to make sure not to use duplicate rows
                for(z=0; z<resultArr.length; z++){
                    if (resultArr[z]==y){
                        boolListed = true
                        break;
                    }
                }
                if (!boolListed){
                    resultArr[x] = y
                    break;
                }
            }
        }
    }

    //now display the results - it is as simple as swapping rows
    for (x=0; x<resultArr.length; x++){
        allTR[x+1].swapNode(colArr[resultArr[x]])
    }   

}

function findFirstNumber(inVal){
	numFound = ""
	for (n=0; n<inVal.length; n++){
		thisChar = parseInt(inVal.substr(n,1))
		if (!isNaN(thisChar)){
			numFound = numFound + thisChar
		}
		else{
			if (numFound != "") n = inVal.length
		}
	}
	if (numFound == "") numFound = 0
	return numFound
}[/blue]



</SCRIPT>
<style> 
table {
  border: none; 
  margin: 0 auto; 
  background-color: #990000;
  text-align: center;
} 
tr { 
  background-color: #FFFF66;
  font-family: "Times New Roman", Times, serif; font-size: 18px;
} 
th,td { 
  margin: 4px; 
  padding: 4px; 
} 
th,td { 
  white-space: nowrap;
} 
</style>
</head>
<body bgcolor="#990000">
<div align="center"><font size="5" color="#FFFFFF">Selft Catering Accommodation 
  </font></div>
<table id="dataTable1" align="center">
  <tr> 
	<th><a href="javascript: sortTable(0, 'dataTable1')">Town/City</a></th>
	<th><a href="javascript: sortTable(1, 'dataTable1')">Name</a></th>
	<th><a href="javascript: sortTable(2, 'dataTable1')">Property Type</a></th>
	<th><a href="javascript: [blue]numberSort[/blue](3, 'dataTable1')">Weekly Rates From (&pound;)</a></th>
	<th><a href="javascript: sortTable(4, 'dataTable1')">Rooms</a></th>
  </tr>
  <tr> 
	<td>AAA</td>
	<td>A Property</td>
	<td>Cottage</td>
	<td>195.00</td>
	<td>1</td>
  </tr>
  <tr> 
	<td>GGG</td>
	<td>B Property</td>
	<td>Apartment</td>
	<td>150.00</td>
	<td>2</td>
  </tr>
  <tr> 
	<td>BBB</td>
	<td>C Property</td>
	<td>Campsite</td>
	<td>95.00</td>
	<td>3</td>
  </tr>
  <tr> 
	<td>CCC</td>
	<td>D Property</td>
	<td>Caravan Site</td>
	<td>-</td>
	<td>4</td>
  </tr>
  <tr> 
	<td>DDD</td>
	<td>E Property</td>
	<td>Cottages</td>
	<td>100.00</td>
	<td>5</td>
  </tr>
</table>
<p align="center">&nbsp;</p>
<p align="center"><font size="5" color="#FFFFFF">Serviced Accommodation</font>
<table id="dataTable2" align="center">
  <tr> 
	<th><a href="javascript: sortTable(0, 'dataTable2')">Town/City</a></th>
	<th><a href="javascript: sortTable(1, 'dataTable2')">Name</a></th>
	<th><a href="javascript: sortTable(2, 'dataTable2')">Property Type</a></th>
	<th><a href="javascript: [blue]numberSort[/blue](3, 'dataTable2')">Room Rates(&pound;)</a></th>
	<th><a href="javascript: sortTable(4, 'dataTable2')">Rooms</a></th>
  </tr>
  <tr> 
	<td>AAA</td>
	<td>A Property</td>
	<td>B&amp;B</td>
	<td>195.00+</td>
	<td>1</td>
  </tr>
  <tr> 
	<td>GGG</td>
	<td>B Property</td>
	<td>Guest House</td>
	<td>From 80.00</td>
	<td>2</td>
  </tr>
  <tr> 
	<td>BBB</td>
	<td>C Property</td>
	<td>Hotel</td>
	<td>95.00</td>
	<td>3</td>
  </tr>
  <tr> 
	<td>CCC</td>
	<td>D Property</td>
	<td>Hotel</td>
	<td>-</td>
	<td>4</td>
  </tr>
  <tr> 
	<td>DDD</td>
	<td>E Property</td>
	<td>B&amp;B</td>
	<td>25.00+ PPPN</td>
	<td>5</td>
  </tr>
</table>
<p>&nbsp;</p>
</body>
</html>

Programming today is a race between software engineers striving to build better and bigger idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning. - Rick Cook

 
FANTASTIC! :)
Looking really good! I'm well impressed!
Hopefully you will also be able to get it to work for other browsers?
Also we do have quite a number of accommodations that have a .50 or .95 listing price, eg. 49.95 or 25.50, so if you could look at that as well, that would be great, but if need be, I could go through them all and find the ones that have this pricing and round the values up.

Many thanks once again.

Happy. (very) :)

 
Code:
function findFirstNumber(inVal){
	numFound = ""
	inVal = inVal.toString()
	for (n=0; n<inVal.length; n++){
		thisChar = parseInt(inVal.substr(n,1))
		if (!isNaN(thisChar)){
			numFound = numFound + thisChar
		}
		else{
			thisChar = inVal.substr(n,1)
			if (thisChar == ".") {
				numFound = numFound + thisChar
			}
			else{
				if (numFound != "") n = inVal.length
			}
		}
	}
	if (numFound == "") numFound = 0
	return parseFloat(numFound)
}

Programming today is a race between software engineers striving to build better and bigger idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning. - Rick Cook

 
The new bit of code works a treat for the decimal values! Thank you :)

I have now tested it on Netscape 4.08, Netscape 7, Mozilla, Firefox and Opera. And none of them seem to want to play ball for some reason, only works in IE for some reason?

I've had a search on the web to see if I could find a Javascript Browsers debugger and found quite a few, but not knowing much about Javascript code, it all became very confussing when trying to use them?

Many thanks

Happy.



 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top