Juan Almonte Juan Almonte - 1 month ago 9
Javascript Question

Javascript to change title when another column is clicked

I have a table and after a heading in another column is clicked I would like to reset any other columns to say sort by. Currently I have:

<html>
<head>
<script>
function changeSort(obj)
{

var firstName = document.getElementById('fName');
var lastName = document.getElementById('lName');
var phoneNumber = document.getElementById('phone');
var birthDate = document.getElementById('birth');


if(obj.id == 'fName')
{
//alert("fName");
obj.title = (obj.title== 'sort ascending first name') ? 'sort descending first
name' : 'sort ascending first name';
}

if(obj.id == 'lName')
{
//alert("lName");
obj.title = (obj.title== 'sort ascending last name') ? 'sort descending first name' : 'sort
ascending last name';
}

if(obj.id == 'phone')
{
//alert("phone");
obj.title = (obj.title== 'sort ascending phone number') ? 'sort descending phone
number' : 'sort ascending phone number';
}

if(obj.id == 'birth')
{
//alert("birth");
obj.title = (obj.title== 'sort ascending birth date') ? 'sort descending birth
date' : 'sort
ascending birth date';
}

}

</script>
</head>
<body

<table>

<tr>
<th id="fName" onclick='changeSort(this)' title="sort by First Name" >First Name</th>
<th id="lName" onclick='changeSort(this)' title="sort by Last Name" >Last
Name</th>
<th id="phone" onclick='changeSort(this)' title="sort by Phone Number" >Phone
Number</th>
<th id="birth" onclick='changeSort(this)'title="sort by Birth Date" >Birth
Date</th>
</tr>

</table>

</body>
</html>


When I perform a sort on the first column i would like it to change the title to ascending or descending which it currently does but if I decide I would like to sort by last name I want the first name columns title to change back to sort by first name and to not be ascending or descending. How can I get the title of a changed table head to go back to the default when another table head is clciked?

Answer

Picking up on André's point that there are cleaner ways, here's the code refactored to make it independent of the number of columns, and otherwise more general.

function changeSort(th){
    var titleTemplates = {
        asc:  'sort ascending %s',
        desc: 'sort decending %s',
        dflt: 'sort by %s'
    };
    titleTemplates.get = function(key, txt){
        var t = this[key] || this.dflt;
        return t.replace('%s', txt);
    };
    var headerRow = th.parentNode;
    var cells = headerRow.getElementsByTagName('th');
    for(var i=0; i<cells.length; i++){
        var c = cells[i];
        var s = c.getAttribute('sortCode');
        var s_ = (c !== th) ? '' : (!s || s == 'desc') ? 'asc' : 'desc';
        c.setAttribute('sortCode', s_);
        c.title = titleTemplates.get(s_, c.innerHTML);
    }
}

tested in Opera 11.61

You could (and really should) go further by attaching the click handler to the TH elements in javascript rather than in the HTML.

Comments