SitePoint Sponsor

User Tag List

Results 1 to 5 of 5
  1. #1
    SitePoint Zealot
    Join Date
    Jul 2008
    Posts
    154
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Clickable table text?

    Hi! I am trying to have the individual text in the cells of a table clickable so that when I click on it, it will call a function which will receive which X column and Y row cell it was clicked.

    Any ideas?

    Thanks!

  2. #2
    SitePoint Member
    Join Date
    Dec 2008
    Posts
    8
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    So let me get this straight... you want the table to maybe look like
    a1|a2|a3
    b1|b2|b3
    c1|c2|c3

    and have the browser inform which cell was clicked?

  3. #3
    Non-Member DelvarWorld's Avatar
    Join Date
    Jul 2004
    Location
    Baloney
    Posts
    341
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You can add an onclick to any element. Loop through each row and column of the table and assign an onclick to each one. The onclick should point to a function, called cellClick() or something like that. In cellClick the keyword this should point to the table cell you clicked on. Now to find out what row and column that cell is in you need to loop through the table in cellClick, and keep track of what row and column you are on with variables, like var row=0, column=0. When you find the matching cell equal to this in the loop you return that. if(element1 == element2) works in JavaScript.

    This is very psuedo-codey and it's a kind of complex problem. If this doesn't make sense to you I can try to clarify, but the logic should work.

  4. #4
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2008
    Posts
    5,757
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think this should work. I haven't bothered to test how thead/tfoot might come into play here, and whether or not some browsers play differently.
    Code:
    var tds = document.getElementById('myTable').getElementsByTagName('td');
    for (var i in tds) {
        tds[i].onclick = function() {
            var tr = this.parentNode;
            var cells = tr.cells;
            for (var cellIndex in cells) {
                if (this === cells[cellIndex]) {
                    break;
                }
            }
            var rows = tr.parentNode.rows;
            for (var rowIndex in rows) {
                if (tr === rows[rowIndex]) {
                    break;
                }
            }
            alert('row ' + rowIndex + ', cell ' + cellIndex);
        }
    }

  5. #5
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Instead of placing multiple event listeners, one for each cell, you can place just the one event listener on the table and process things from there.

    For the sake of this example, I'll be working with this sample table.

    Code html4strict:
    <table id="myTable">
    	<tr><td>Cell 1, 1</td><td>Cell 2, 1</td><td>Cell 3, 1</td></tr>
    	<tr><td>Cell 1, 2</td><td>Cell 2, 2</td><td>Cell 3, 2</td></tr>
    	<tr><td>Cell 1, 3</td><td>Cell 2, 3</td><td>Cell 3, 3</td></tr>
    </table>

    The contents of the cells are not important. I just used coordinate values so that I could easily check that the x and y being reported by the script were correct. There can be anything you like in the table cells.

    The makeClickableTable function sets things up so that we can then process the results. This script need to be run from the end of the body, just before the </body> tag.

    Code javascript:
    function makeClickableTable(id) {
        var table = document.getElementById(id);
    	table.onclick = processTableClick;
    }
    makeClickableTable('myTable');

    The processTableClick function gets the cell that was clicked, makes sure that we do have a TD element, gets the x and y coordinates of that cell and then calls the doSomethingWithCellAt function with those coordinates

    Code javascript:
    function processTableClick(evt) {
    	evt = evt || window.event;
    	var cell = evt.target || evt.srcElement;
    	var x, y;
    	// Allow for browsers that let you target text nodes
    	if (cell.nodeType !== 1) {
    		cell = cell.parentNode;
    	}
    	while (cell.nodeName !== 'BODY' && cell.nodeName !== 'TD') {
    	    cell = cell.parentNode;
    	}
    	if (cell.nodeName === 'BODY') {
    		return;
    	}
    	x = getCol(cell);
    	y = getRow(cell);
    	doSomethingWithCellAt(x, y);
    }

    The getCol function is nice and simple. It just goes through all of the TD elements near the one we clicked on, and looks for one that matches.

    Code javascript:
    function getCol(cell) {
        var parent = cell.parentNode;
    	var els = parent.getElementsByTagName('td');
    	var i;
    	for (i = 0; i < els.length; i += 1) {
    		if (els[i] === cell) {
    			return i + 1;
    		}
    	}
    }

    This getRow function is nearly identical, except that it's working at a level higher than the getCol function.

    Code javascript:
    function getRow(cell) {
        var parent = cell.parentNode.parentNode;
    	var target = cell.parentNode;
    	var els = parent.getElementsByTagName('tr');
    	var i;
    	for (i = 0; i < els.length; i += 1) {
    		if (els[i] === target) {
    			return i + 1;
    		}
    	}
    }

    And finally, we do something with the x and y values

    Code javascript:
    function doSomethingWithCellAt(x, y) {
    	alert('The clicked cell was at ' + x + ', ' + y + '.');
    }

    Here's the full code that can be use for testing purposes

    Code html4strict:
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
    <title>Test</title>
    <style type="text/css">
    </style>
    </head>
    <body>
    <table id="myTable">
    	<tr>
    		<td>Cell 1, 1</td>
    		<td>Cell 1, 2</td>
    		<td>Cell 1, 3</td>
    	</tr>
    	<tr>
    		<td>Cell 2, 1</td>
    		<td>Cell 2, 2</td>
    		<td>Cell 2, 3</td>
    	</tr>
    	<tr>
    		<td>Cell 3, 1</td>
    		<td>Cell 3, 2</td>
    		<td>Cell 3, 3</td>
    	</tr>
    </table>
    <script>
    makeClickableTable('myTable');
    function makeClickableTable(id) {
        var table = document.getElementById(id);
    	table.onclick = processTableClick;
    }
    function processTableClick(evt) {
    	evt = evt || window.event;
    	var cell = evt.target || evt.srcElement;
    	var x, y;
    	// Allow for browsers that let you target text nodes
    	if (cell.nodeType !== 1) {
    		cell = cell.parentNode;
    	}
    	while (cell.nodeName !== 'BODY' && cell.nodeName !== 'TD') {
    	    cell = cell.parentNode;
    	}
    	if (cell.nodeName === 'BODY') {
    		return;
    	}
    	x = getCol(cell);
    	y = getRow(cell);
    	doSomethingWithCellAt(x, y);
    }
    function getCol(cell) {
        var parent = cell.parentNode;
    	var els = parent.getElementsByTagName('td');
    	var i;
    	for (i = 0; i < els.length; i += 1) {
    		if (els[i] === cell) {
    			return i + 1;
    		}
    	}
    }
    function getRow(cell) {
        var parent = cell.parentNode.parentNode;
    	var target = cell.parentNode;
    	var els = parent.getElementsByTagName('tr');
    	var i;
    	for (i = 0; i < els.length; i += 1) {
    		if (els[i] === target) {
    			return i + 1;
    		}
    	}
    }
    function doSomethingWithCellAt(x, y) {
    	alert('The clicked cell was at ' + x + ', ' + y + '.');
    }
    </script>
    </body>
    </html>
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript


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
  •