Amazon.com Widgets
...not so private reflections of greg.newman
RSS feed - Categories & Search

Div On The Table

A recent project required me to develop a reservation data table that needed to be flexible enough across installs that we could quickly change the look and behavior of the table without touching any of the core code. Varying widths, colors, status background images, cell heights were just some of our requirements. All data is retrieved from a MySQL database via PHP. Varying cell widths based on the data made this even more of a challenge as well as each "available" time slot had to include a radio button for new reservations.

reservation table

Sure, this can be done with CSS and HTML tables, but that's not as fun now; is it? Here's a mockup of the divs used in the project.

reservation table

I start with a div container for the css table called "teetable". For each row, I wrap the CSS cells in another container called "teerow". From there I assign widths to the contained divs with a numerator at the end of the id. A cell that spans two slots has an id ending in -2 (teecell-2), one that spans three ends in -3 and so forth. I repeat this logic throughout the CSS table to get the desired results.

Example html:

&lt;div id="teetable"&gt;<br /> &#xA0;&#xA0;&lt;div id="teerow"&gt;<br /> &#xA0;&#xA0;&#xA0;&#xA0;&lt;div id="teedate">&lt;/div&gt;<br /> &#xA0;&#xA0;&#xA0;&#xA0;&lt;div id="teehead">One&lt;/div&gt;<br /> &#xA0;&#xA0;&#xA0;&#xA0;&lt;div id="teehead">Two&lt;/div&gt;<br /> &#xA0;&#xA0;&#xA0;&#xA0;&lt;div id="teehead">Three&lt;/div&gt;<br /> &#xA0;&#xA0;&#xA0;&#xA0;&lt;div id="teehead">Four&lt;/div&gt;<br /> &#xA0;&#xA0;&lt;/div&gt;<br /> <br /> &#xA0;&#xA0;&lt;div id="teerow"&gt;<br /> &#xA0;&#xA0;&#xA0;&#xA0;&lt;div id="teedate">7:08am&lt;/div&gt;<br /> &#xA0;&#xA0;&#xA0;&#xA0;&lt;div id="teecell-2" class="reserved"&gt;Some Data Goes Here&lt;/div&gt;<br /> &#xA0;&#xA0;&#xA0;&#xA0;&lt;div id="teecell-2" class="reserved"&gt;Some Data Goes Here&lt;/div&gt;<br /> &#xA0;&#xA0;&lt;/div&gt;<br /> <br /> &#xA0;&#xA0;&lt;div id="teerow"&gt;<br /> &#xA0;&#xA0;&#xA0;&#xA0;&lt;div id="teedate">7:20am&lt;/div&gt;<br /> &#xA0;&#xA0;&#xA0;&#xA0;&lt;div id="teecell-1" class="available"&gt;Some Data Goes Here&lt;/div&gt;<br /> &#xA0;&#xA0;&#xA0;&#xA0;&lt;div id="teecell-1" class="reserved"&gt;Some Data Goes Here&lt;/div&gt;<br /> &#xA0;&#xA0;&#xA0;&#xA0;&lt;div id="teecell-1" class="checked-in"&gt;Some Data Goes Here&lt;/div&gt;<br /> &#xA0;&#xA0;&#xA0;&#xA0;&lt;div id="teecell-1" class="reserved"&gt;Some Data Goes Here&lt;/div&gt;<br /> &#xA0;&#xA0;&lt;/div&gt;<br /> <br /> &#xA0;&#xA0;&lt;div id="teerow"&gt;<br /> &#xA0;&#xA0;&#xA0;&#xA0;&lt;div id="teedate"&gt;7:30am&lt;/div&gt;<br /> &#xA0;&#xA0;&#xA0;&#xA0;&lt;div id="teecell-4" class="reserved"&gt;Some Data GoesHere&lt;/div&gt;<br /> &#xA0;&#xA0;&#xA0;&#xA0;&lt;/div&gt;<br /> &#xA0;&#xA0;&lt;/div&gt;<br />

The underlying CSS looks something like this:

#teetable { width: 625px; margin: 20px 0 20px 20px; display: block; }<br /> #teehead { width: 125px; height: 20px; float: left; text-align: center; vertical-align: middle; background: #ccc; font-weight: bold; }<br /> #teerow { width: 625px; display: block; }<br /> #teedate { width: 125px; height: 20px; vertical-align: middle; float: left; background: #ccc; text-align: center; }<br /> #teecell-1, #teecell-2, #teecell-3, #teecell-4 { height: 20px; overflow: hidden; vertical-align: middle; float: left; text-align: center; border-bottom: 1px solid #666; }<br /> #teecell-1 {width: 125px;}<br /> #teecell-2 {width: 250px;}<br /> #teecell-3 {width: 375px;}<br /> #teecell-4 {width: 500px;}<br /> .available { background: #fff; }<br /> .reserved { background: #009966 url(images/reserved.gif); }<br /> .checked-in { background: #33CCFF url(images/checkedin.gif); }<br /> .available { background: #fff url(images/available.gif); }<br />

The beauty of this really lies in the PHP that grabs the rows from the database and loops through building the div id's. I have a database table that holds the number of people for each time slot. There is no maximum number of people, but the grid will only show four slots. With a little switch/case, we're off and running with a dynamic CSS data table. All teecells are suffixed with -1, -2, -3, -4 based on the number of people. Remember, our -4 means the cell spans across our four columns.

Based on if the time slot has checked in, is available, or is reserved, a simple if statement throws the table it's style for the background.

if ($res->checkin == "") { <br /> &#xA0;&#xA0;&#xA0;&#xA0;$class = " class=\"reserved\""; <br /> } else { <br /> &#xA0;&#xA0;&#xA0;&#xA0;$class = " class=\"checked-in\""; <br /> } <br />

I cannot provide the full working code, but there is a zip file containing the html and css for this narrative. If you find it useful, drop me a line and let me know what you're using it for.

0 TrackBacks

Listed below are links to blogs that reference this entry: Div On The Table.

TrackBack URL for this entry: http://www.20seven.org/cgi-bin/mt/mt-tb.cgi/42

6 Comments

A recent project required me to develop a reservation data table that needed to be flexible enough across installs that we could quickly change the look and behavior of the table without touching any of the core code. Varying widths, colors, status background images, cell heights were just some of our requirements. All data is retrieved from a MySQL database via PHP. Varying cell widths based on the data made this even more of a challenge as well as each "available" time slot had to include a radio button for new reservations.

Sure, this can be done with CSS and HTML tables, but that's not as fun now; is it? Here's a mockup of the divs used in the project.

I start with a div container for the css table called "teetable". For each row, I wrap the CSS cells in another container called "teerow". From there I assign widths to the contained divs with a numerator at the end of the id. A cell that spans two slots has an id ending in -2 (teecell-2), one that spans three ends in -3 and so forth. I repeat this logic throughout the CSS table to get the desired results.

Example html:

<div id="teetable">
  <div id="teerow">
    <div id="teedate"></div>
    <div id="teehead">One</div>
    <div id="teehead">Two</div>
    <div id="teehead">Three</div>
    <div id="teehead">Four</div>
  </div>

  <div id="teerow">
    <div id="teedate">7:08am</div>
    <div id="teecell-2" class="reserved">Some Data Goes Here</div>
    <div id="teecell-2" class="reserved">Some Data Goes Here</div>
  </div>

  <div id="teerow">
    <div id="teedate">7:20am</div>
    <div id="teecell-1" class="available">Some Data Goes Here</div>
    <div id="teecell-1" class="reserved">Some Data Goes Here</div>
    <div id="teecell-1" class="checked-in">Some Data Goes Here</div>
    <div id="teecell-1" class="reserved">Some Data Goes Here</div>
  </div>

  <div id="teerow">
    <div id="teedate">7:30am</div>
    <div id="teecell-4" class="reserved">Some Data GoesHere</div>
    </div>
  </div>

The underlying CSS looks something like this:

#teetable { width: 625px; margin: 20px 0 20px 20px; display: block; }

#teehead {
width: 125px;
height: 20px;
float: left;
text-align: center;
vertical-align: middle;
background: #ccc;
font-weight: bold;
}


#teerow {
width: 625px;
display: block;
}


#teedate {
width: 125px;
height: 20px;
vertical-align: middle;
float: left;
background: #ccc;
text-align: center;
}


#teecell-1,
#teecell-2,
#teecell-3,
#teecell-4 {
height: 20px;
overflow: hidden;
vertical-align: middle;
float: left;
text-align: center;
border-bottom: 1px solid #666;
}


#teecell-1 {width: 125px;}

#teecell-2 {width: 250px;}

#teecell-3 {width: 375px;}

#teecell-4 {width: 500px;}


.available {
background: #fff;
}


.reserved {
background: #009966 url(images/reserved.gif);
}


.checked-in {
background: #33CCFF url(images/checkedin.gif);
}

.available {
background: #fff url(images/available.gif);
}



The beauty of this really lies in the PHP that grabs the rows from the database and loops through building the div id's. I have a database table that holds the number of people for each time slot. There is no maximum number of people, but the grid will only show four slots. With a little switch/case, we're off and running with a dynamic CSS data table. All teecells are suffixed with -1, -2, -3, -4 based on the number of people. Remember, our -4 means the cell spans across our four columns.

Based on if the time slot has checked in, is available, or is reserved, a simple if statement throws the table it's style for the background.

if ($res->checkin == "") {
    $class = " class=\"reserved\"";
} else {
    $class = " class=\"checked-in\"";
}

I cannot provide the full working code, but there is a zip file containing the html and css for this narrative. If you find it useful, drop me a line and let me know what you're using it for.

Considering this is tabular data, shouldn't you actually be using tables anyway? Doing this is no better than using tables for layout.

Actually, I started it with tables and it wasn't flexible enough. I needed to dynamically expand the cell widths based on how many reservations were set, and if there are openings they have to float to the left of the booked reservations. It was much easier to achieve with divs than table cells by simply setting the div to float: left and assigning a suffix to the div id, which in turn, is a hell of alot less code than tables.

In the end, it can be done both ways.

That last code block could be written a bit easier in the form of this one-liner:

$class = $res->checkin ? ' class="checked-in"' : ' class="reserved"';

Nitpicker, not everything line of code written is a final optimized version. He is obviously just giving an example. I'm sure before he is done he will optimize his code. I could have pointed out at least 30 different ways to better write it, but that's niether here nor there.

I think it's a great tutorial, keep up the good work Greg.

CoderX is correct. What i've posted is only a prototype. The final code is not complete yet, nor is it optimized. There's alot of work in addition to this that I cannot post, but wanted to post the "quick" prototype of the html file for others to take a peek at.

Thanks CoderX, glad you found it useful.

Leave a comment