20seven

Devigner blog about development and design

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:

<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.