SitePoint Sponsor

User Tag List

Results 1 to 10 of 10
  1. #1
    SitePoint Evangelist anjanesh's Avatar
    Join Date
    Jun 2004
    Location
    Mumbai
    Posts
    447
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Adding same event handler function to all cells in a table

    Instead of giving as <td onclick="foo()">, I wanted to use the Traditional Event Registration Model, but how do I specify the same function for all <td>s in the table ?

    Code:
    <table border="1" id="tbl">
    <tr><td>cell 1</td></tr>
    <tr><td>cell b</td></tr>
    <tr><td>cell *</td></tr>
    </table>
    
    <script type="text/javascript">
    var tbl = document.getElementById("tbl");
    tbl.td.onclick = foo;
    
    function foo()
     {
            alert(this.innerHTML);
     }
    
    </script>
    Thanks
    Anjanesh

  2. #2
    SitePoint Wizard Pepejeria's Avatar
    Join Date
    Jan 2005
    Location
    Too far up north
    Posts
    1,566
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code:
    <table border="1" id="tbl">
    <tr><td>cell 1</td></tr>
    <tr><td>cell b</td></tr>
    <tr><td>cell *</td></tr>
    </table>
    
    <script>
    var tbl = document.getElementById("tbl");
    tbl.onclick = foo;
    
    function foo(oEvent) {
        if(!oEvent) var oEvent = window.event;
        var oTarget = oEvent.target || oEvent.srcElement;
    
    
        if(oTarget.nodeName == "TD") {
            alert("cell clicked");
        }
    }
    </script>

  3. #3
    SitePoint Zealot
    Join Date
    Jul 2006
    Posts
    151
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Trying to do this myself

    Hey there,

    I'm currently working on a spreadsheet in Javascript (which you can check out
    here) which does the same thing on page load.

    The problem is, it doesn't seem to work properly in all browsers and in Firefox 2.0 on Windows 98, I can't get any events to fire the way I want them to. It's a big problem that I'm not sure how to solve.

    Anyway, the function I am using to handle adding the event handlers is this:

    Code:
    function addHandler() {
    	var td = document.getElementsByTagName("td");
    	for (var i = 0; i < td.length; i++) {
    		td[i].id = "td" + i;
    		td[i].onclick = function () { this.onclick = ""; curId = this.id; var curText = this.innerHTML; this.innerHTML = '<input id="cell" type="text" size="12" onblur="save(curId);" value="' + curText + '"/>'; var cell = $e('cell'); cell.focus();}
    	}
    	return;
    }
    I'm trying to set up a function so that when a user clicks on a certain cell in the table, the contents of the cell are replaced with an input box of a similar size to the cell. When the user presses the left or right arrow, the current cell changes to the one left or right of the previous cell.

    Anyway, my solution is incomplete, but I hope it gives you some ideas.

    Dave

  4. #4
    I'll take mine raw silver trophy MikeFoster's Avatar
    Join Date
    Dec 2002
    Location
    Alabama, USA
    Posts
    2,560
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Good replies by Pepe and Dave!

    I'll make a general comment about this. IMO, when there are going to be very many event listeners and they are all contained by the same parent - then it is better to put the listener on the parent and let the events bubble up to it - instead of putting a listener on every TD. We saw a similar situation in the thread regarding the mythbusters page.

    Pepe's code illustrates what I'm talking about. He put the listener on the table and let the TD click events bubble up to it - and use "target" to get a reference to the TD that was actually clicked. You'll need to iterate up the parentNode chain to find the TD, in case it was a #text node that was actually clicked on.

    Dave's code answers anjanesh's question - but I suggest not creating a new function for every TD. For example:
    Code:
    function addHandler()
    {
      var tbl = document.getElementById("tbl");
      var td = tbl.getElementsByTagName("td");
      for (var i = 0; i < td.length; i++) {
        td[i].id = "td" + i;
        td[i].onclick = tdOnClick; 
      }
      return;
    }
    
    function tdOnClick()
    {
      this.onclick = ""; // I'm curious about this. Why do this?
      ...
    }

  5. #5
    SitePoint Wizard Pepejeria's Avatar
    Join Date
    Jan 2005
    Location
    Too far up north
    Posts
    1,566
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by MikeFoster View Post
    You'll need to iterate up the parentNode chain to find the TD, in case it was a #text node that was actually clicked on.
    I actually thought about text nodes in my first attempt, but noticed that the target element never was a text node. Just a td or the actual table when you clicked between tds. Alert oTarget.nodeName to test this.

    But yes, still, its a good approach to iterate up the parentNode chain, since the td might contain other html elements

    Updated code:
    Code:
    <table border="1" id="tbl">
    <tr><td>cell 1</td></tr>
    <tr><td>cell b</td></tr>
    <tr><td><span>cell *</span></td></tr>
    </table>
    
    <script>
    var tbl = document.getElementById("tbl");
    tbl.onclick = foo;
    
    function foo(oEvent) {
        if(!oEvent) var oEvent = window.event;
        var oTarget = oEvent.target || oEvent.srcElement;
    	
        while(oTarget.nodeName != "TD") {
    	if(oTarget.nodeName == "TABLE") return;
    	oTarget = oTarget.parentNode;
        }
    
        // oTarget is now a TD, do magic	
        alert("cell clicked");
    }
    </script>

  6. #6
    SitePoint Evangelist anjanesh's Avatar
    Join Date
    Jun 2004
    Location
    Mumbai
    Posts
    447
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks Pepejeria for your code.
    Is it possible to get the oTarget's src id ?

    Code:
    alert(oTarget.style.color);
    Obviously oTarget.style.color doesnt work since oTarget not the TD's id.
    Anjanesh

  7. #7
    SitePoint Wizard Pepejeria's Avatar
    Join Date
    Jan 2005
    Location
    Too far up north
    Posts
    1,566
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Did you try that? oTarget is a cell, so you can gets its property the usual way. For example
    Code:
    alert(oTarget.nodeName);  // TD
    alert(oTarget.id); // Alerts the id, if it has any, if not you will get an empty alert
    
    // etc

  8. #8
    SitePoint Evangelist anjanesh's Avatar
    Join Date
    Jun 2004
    Location
    Mumbai
    Posts
    447
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ah...yes...thanx..it did. I had tried to use this before.
    The page works fine now.

    But this page is actually meant to be called from an XMLHttpRequest object.
    When onclick and onmouseover was added directly (<td onmouseover="" onclick="">) it works but with <script type="text/javascript"> right after the </table>, FF's JS Error Consolse keeps giving
    Code:
    Error: junk after document element
    Source File: http://localhost/test.php?a=b
    Line: 2, Column: 1
    Source Code:
    <script type="text/javascript">^
    Anjanesh

  9. #9
    SitePoint Wizard Pepejeria's Avatar
    Join Date
    Jan 2005
    Location
    Too far up north
    Posts
    1,566
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Funny, I never seen this JS error before. I guess you have some... junk after the document element.

  10. #10
    SitePoint Evangelist anjanesh's Avatar
    Join Date
    Jun 2004
    Location
    Mumbai
    Posts
    447
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I finally found out what the problem was (or atleast I think so).
    This html page that I was loading was through an XMLHttpRequest variable and I had the returned content placed into a DIV. The returned content had HTML (the <table>...</table>) + Javascript.

    The Javascript obviously didn't get parsed but FF definitely tried doing something with it.

    Guess I've to stick to the inline model for this case. The event-handler functions are in a separate JS file, but tbl.onclick = foo; or td[i].onclick = foo can't seem be done.
    Anjanesh


Bookmarks

Posting Permissions

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