I'm having a problem while trying to dynamically change a table cell's styling class using JavaScript.

The following issue happens on FF, I opened the page on other browsers too and it worked fine.

I have a html page that contains a 4x4 table. I would like when I click on a cell, to zoom it in and when I click on it again to zoom it out. I defined 2 CSS classes, one for the normal size cell and one for the zoomed cell. I am using JS to change the CSS class when a cell is clicked.

The issue on FF is that when changing from zoomClass to normalClass all the cells to the right of the clicked cell are shifted to the right...

I can't find a solution or a workaround for this problem, if somebody has any ideas please post them here.

Next, I will attach the html, css and js files.

Thanks :)

util.js


function zoom(id) {

    if (document.getElementById(id).className == "zoomClass") {

        document.getElementById(id).className = "normalClass";

    } else {

        document.getElementById(id).className="zoomClass";

    }

}

calendar.css


table, td, th, tr {
    border-color:#D2D3D4;
    border-style:solid;
    border-width:2px;
}

#main_table {
    border-spacing:1px;
    height:450px;
    margin-left:auto;
    margin-right:auto;
    position:relative;
    top:30px;
    width:850px;
}

td.normalClass {
    padding:0;
    font-size:4px;
    color:#3333FF;
}

td.zoomClass {
    display:inline;
    position:absolute;
    width:320px;
    height:240px;
    z-index:100;
    font-size:18px;
}

test.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

    <link rel="stylesheet" type="text/css" href="css/calendar.css" media="screen" />
    <script type="text/javascript" src="js/util.js"></script>
</head>

<body>
<div>
    <div>
        <table id="main_table">
            <tr>
                <td id="1" onclick="zoom(1)" align="right" valign="top" class="normalClass"></td>
                <td id="2" onclick="zoom(2)" align="right" valign="top" class="normalClass"></td>
                <td id="3" onclick="zoom(3)" align="right" valign="top" class="normalClass"></td>
                <td id="4" onclick="zoom(4)" align="right" valign="top" class="normalClass"></td>
            </tr>
            <tr>
                <td id="6" onclick="zoom(6)" align="right" valign="top" class="normalClass"></td>
                <td id="7" onclick="zoom(7)" align="right" valign="top" class="normalClass"></td>
                <td id="8" onclick="zoom(8)" align="right" valign="top" class="normalClass"></td>
                <td id="9" onclick="zoom(9)" align="right" valign="top" class="normalClass"></td>
            </tr>
            <tr>
                <td id="10" onclick="zoom(10)" align="right" valign="top" class="normalClass"></td>
                <td id="11" onclick="zoom(11)" align="right" valign="top" class="normalClass"></td>
                <td id="12" onclick="zoom(12)" align="right" valign="top" class="normalClass"></td>
                <td id="13" onclick="zoom(13)" align="right" valign="top" class="normalClass"></td>
            </tr>
            <tr>
                <td id="14" onclick="zoom(14)" align="right" valign="top" class="normalClass"></td>
                <td id="15" onclick="zoom(15)" align="right" valign="top" class="normalClass"></td>
                <td id="16" onclick="zoom(16)" align="right" valign="top" class="normalClass"></td>
                <td id="17" onclick="zoom(17)" align="right" valign="top"     class="normalClass"></td>
            </tr>
        </table>
    </div>
</body>

</html>
share|improve this question
do you have a live example? – sico87 Dec 10 '09 at 10:16

3 Answers

up vote 1 down vote accepted

Unfortunately "position" doesn't work on table cells. You could try putting a div inside the table cell and positioning that.

Edit: Something like this should do the trick:

td.normalClass div { 
    display: none; 
} 
td.zoomClass div { 
    display: block; 
    position: absolute; 
    width: 320px; 
    height: 240px; 
}

Make sure the div is the first thing in the td and it'll be positioned at the td's top left corner. You might need to play with relative positioning on the td if you need to change the top and left values further.

share|improve this answer
Can you tell me what would be the changes on the css as well? – fmoga Dec 10 '09 at 10:50
Something like this should do the trick: td.normalClass div { display: none; } td.zoomClass div { display: block; position: absolute; width: 320px; height: 240px; }. You might need to play with relative positioning on the td if you need to change the top and left values of the div. – Olly Hodgson Dec 10 '09 at 11:32

A few comments on your code, if I may. I would keep the layout in the CSS file and not in the HTML, so I'd remove all of those align="right" and valign="top". Also, you can reference the cells in your table much more efficiently. Then you won't have to set the class for each cell.

#main_table td{
    padding:0;
    font-size:4px;
    color:#3333FF;
}

I would also keep all of the behaviour of the page in a separate script file (Javascript). So no more onclick="zoom(x)" at every cell. You can use event binding to do that.

Also, if you use event binding, you can just "read" the id of the clicked cell, so you don't have to pass that value in statically in the call of the zoom function.

Lastly: I can highly recommend using jQuery to do this kind of DOM manipulation as it's a lot easier, the code is shorter and more readable and your scripts work across browsers pretty much out of the box.

I don't have a solution for this specific problem but using jQuery it's quite easy to insert a new DOM element, a div for instance, with the content of the clicked cell, float over the table and simulate the zoom effect. That div would be be absolutely positionable and can be styled a lot better than the cell the user clicked on.

share|improve this answer

This is how tables work. I possible I would try and do the same thing using divs and then you should be able to deal with the problem using position:absolute so the expanded div will overlay the others. This could work the same for a table cell.

share|improve this answer
Are you suggesting to replace td with divs? – fmoga Dec 10 '09 at 10:31
2  
You could place a div inside each cell and show/hide that when you do the zoom thing. – Olly Hodgson Dec 10 '09 at 10:35

Your Answer

 
or
required, but never shown
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.