views:

341

answers:

3

Hello

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"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;

<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>
+1  A: 

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.

matpol
Are you suggesting to replace td with divs?
MelmanRo
You could place a div inside each cell and show/hide that when you do the zoom thing.
Olly Hodgson
+1  A: 

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.

Olly Hodgson
Can you tell me what would be the changes on the css as well?
MelmanRo
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
+1  A: 

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.

Niels Bom