-1

I need your help,

Given the html table below, how can I create a javascript function that will, at the click of a mouse, alert me the name of the column header?

Ie. if I click on the COLORS header, a javascript box will popup and alert("COLORS")?

<html>

<head>

</head>

<body>

<table border="1" cellspacing="1" width="500">
    <tr>
        <td>FRUITS</td>
        <td>COLORS</td>
        <td>VEGGIES</td>
        <td>NUMBERS</td>
    </tr>
    <tr>
        <td>apples</td>
        <td>red</td>
        <td>carrots</td>
        <td>123</td>
    </tr>
    <tr>
        <td>oranges</td>
        <td>blue</td>
        <td>celery</td>
        <td>456</td>
    </tr>
    <tr>
        <td>pears</td>
        <td>green</td>
        <td>brocoli</td>
        <td>789</td>
    </tr>
    <tr>
        <td>mangos</td>
        <td>yellow</td>
        <td>lettuce</td>
        <td>098</td>
    </tr>
</table>

</body>

</html>
Jason Kelly
  • 2,539
  • 10
  • 43
  • 80

4 Answers4

3

Try this

var td     = document.getElementsByTagName("td"),
    titles = document.getElementsByTagName("th");

for ( var i = 0; i < td.length; i++ ) {   
    td[i].addEventListener("click", function() {
        alert( titles[this.cellIndex].innerHTML );
    }, false);
}

DEMO


UPDATE

If the click should happen on the table head only

var titles = document.getElementsByTagName("th");

for ( var i = 0, len = titles.length; i < len; i++ ) {   
    titles[i].addEventListener("click", function() {
        alert( this.innerHTML );
    }, false);
}

DEMO

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
Zoltan Toth
  • 46,981
  • 12
  • 120
  • 134
  • Damn, worked on exactly [the same](http://jsfiddle.net/jwyQ9/), should've been faster. ) – raina77ow Oct 22 '12 at 17:12
  • @PeeHaa You might be right.. I've updated the example. Just in case :) – Zoltan Toth Oct 22 '12 at 17:27
  • Why are you recalculating the length of DOM element collection for each iteration? The `.length` in DOM/JS is **NOT** a variable. – tereško Oct 22 '12 at 17:55
  • @tereško The only reason to assign that value to a separate variable in this particular case is enforcing good practices. However it won't make a difference because of the quantity of selected elements. Anyways updated the 2nd part, so the OP will be aware and can decide what he wants to use. – Zoltan Toth Oct 22 '12 at 18:10
  • @ZoltanToth: Just a thought... Since you're using `addEventListener`, you could use `document.querySelectorAll()` to get rid of the live list length recalculation. You could also use `.textContent` to be a little more pure. Any browser that supports `aEL` will support those properties as well. – I Hate Lazy Oct 22 '12 at 18:15
  • @ZoltanToth , thing is that you are NOT dealing with an array there. Instead it is a collection of DOM elements. Each time you call `.length` if re-acquired the list by tag name and re-counts them. It is an expensive operation. One (on IE even two) orders of magnitude more expensive then just recalculating the length of a simple array. You can test it by creating such a for loop where in each iteration you add another tag with same name to the document. You will gain an endless loop. – tereško Oct 22 '12 at 18:18
  • ok this code works: function init() { var titles = document.getElementsByTagName("th"); for ( var i = 0, len = titles.length; i < len; i++ ) { titles[i].attachEvent("onclick", function() { alert( this.innerHTML ); }, false); } }//end of function but why does it tell me "undefined" when the column is clicked? – Jason Kelly Oct 22 '12 at 18:36
2
​(function() {
    var headings = document.getElementsByTagName('th');
    for (var i = 0, amount = headings.length; i < amount; i++) {
        headings[i].addEventListener("click", function() {
            alert(this.innerText);
        });
    }
})();​

Note I have changed the td tags to th tags because that is what it is. :-) Also note that I have used a generic getElementsByTagName('th') call which should work for the HTML provided, but you may want to be more specific in a real HTML document.

Demo: http://jsfiddle.net/3G9Tx/

You may also want to look into console.log() instead of using an alert(), which is in most case easier / prefered.

UPDATE

An improved version:

function getTextFromHeading(e) {
    var e = e || window.event,
        target = e.target || e.srcElement,
        text = target.textContent || target.innerText;  

    if (target.tagName.toLowerCase() === 'th') {
        alert(text);
    }
}

(function() {
    var table = document.getElementsByTagName('table');
    if (table[0].addEventListener) {
        table[0].addEventListener('click', getTextFromHeading);
    } else if (table[0].attachEvent) {
        table[0].attachEvent('onclick', getTextFromHeading);
    }
}());

This has some extra assignments to make sure it is cross browser compatible. It also only uses a single event handler.

Demo: http://jsfiddle.net/yRfem/

PeeHaa
  • 71,436
  • 58
  • 190
  • 262
  • 2
    Is something wrong with my answer? – PeeHaa Oct 22 '12 at 17:21
  • 1
    Perhaps the browser compatibility issues of `addEventListener` and `.innerText`? By using those two together, you've excluded IE8 and lower, and all of Firefox. – I Hate Lazy Oct 22 '12 at 18:05
  • I can't get this code to work. Its failing at: titles[i].addEventListener("click", function() { alert( this.innerHTML ); }, false); – Jason Kelly Oct 22 '12 at 18:14
  • @JasonKelly: Well sure, PeeHaa doesn't have a `titles` variable. Details are important. – I Hate Lazy Oct 22 '12 at 18:16
  • If you're using `addEventListener`, then the `e` parameter, `.target` and `.textContent` will be supported. No need for the fixes. They'll never be utilized. – I Hate Lazy Oct 22 '12 at 18:21
  • @user1689607 tnx. and btw I like your persistence of your `user[\d]+` name :) – PeeHaa Oct 22 '12 at 18:45
1

Since jQuery was not specified, I'll give a non-jQuery solution. Give an onclick event to your cells like this:

<td onclick="alert(this.innerHTML);">FRUITS</td>

jQuery can greatly simplify this task. You can set the event handler for all cells and set the event method in one call.

<tr id="headerRow">
    <td>FRUITS</td>
    <td>COLORS</td>
    <td>VEGGIES</td>
    <td>NUMBERS</td>
</tr>

js:

$(function() {  //on DOM loaded method
  $('#headerRow td').click(function() {
      alert(this.innerHTML);
  });
});

http://jsfiddle.net/xzmMj/

(similar non-jquery concept):

//execute at end of document or in a DOM ready/loaded handler
var arr = document.getElementById('headerRow')
    .getElementsByTagName("td");


for(var i = 0; i < arr.length; i++) {
    (function(_i){
        arr[_i].onclick = function() { alert(this.innerHTML); };
    })(i);
}
Nick Rolando
  • 25,879
  • 13
  • 79
  • 119
0

assuming your using jquery

$('table tr').each(function(index){
  $(this+" td").each(function(index2){
      $(this).click(function(){
         alert($('table td:eq('+index2+')').text());
      });
  });
});

Should get you somewhere( not tested)

DickieBoy
  • 4,886
  • 1
  • 28
  • 47