jQuery: Hide table columns with a single value

I’m currently working on a piece of software where one view on the data is a list view, basically an HTML table. I’m displaying one row per item and one attribute of this item per column. Additionally, the header had two lines: the actual column header and a filter field (where you can type in a string which will filter the rows displayed). So it looks like this (with of course more rows):

<table id="list-view-table">
    <thead>
        <tr>
            <th>Actions</th>
            <th>Type</th>
            <th>Number</th>
            <th>Task</th>
            <th>Owner</th>
            <th>Due Date</th>
            <th>Creation Date</th>
            <th>Priority</th>
        </tr>
        <tr>
            <td>...</td>
            <td>...</td>
            <td>...</td>
            <td>...</td>
            <td>...</td>
            <td>...</td>
            <td>...</td>
            <td>...</td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <a onclick="deleteItem(113528234059682)" href="#" title="Delete"><img src="delete.png"></a>
                <a onclick="cloneItem(113528234059682)" href="#" title="Clone"><img src="clone.png"></a>
            </td>
            <td>
                <select>
                    <option value="type1" selected="selected">Type 1</option>
                    <option value="type2">Type 2</option>
                </select>
            </td>
            <td>3</td>
            <td></td>
            <td>Henri</td>
            <td></td>
            <td>2013-06-28</td>
            <td>1</td>
        </tr>
    </tbody>
</table>

Of course I’m kind of oversimplifying. The rows and cells would have different classes and IDs, but those are not relevant here.

Now what happens is that multiple columns are either empty because the attribute is not set for any item or all contain the same value. In the example above I only have 8 columns and you could end up having 20 columns. Many of them containing the same value in all cells. It makes things not very readable and these columns actually do not really help much, since the user actually knows that all items have the same value for an attribute.

So I started implemented a piece of PHP code to only add columns to the table which do not have the same value. Sounded like a great idea. The problem is that on the page, you can also edit an item and thus change the values. So a column might need to be added because after the update of an item, not all cells in the column have the same value. So I built in a reload of the page whenever an item was updated. But it caused the filtering and sorting to be lost. So I needed a JavaScript solution for this.

First we need a function which can be called once the page is loaded and every time an item is updated:

function hideOneValueColumns(table_id) {
}

I provide the ID of the table as parameter. There are a few different things I additional need:

  1. First I do not want to consider the rows with headers or filters when evaluating whether all cells in the column have the same value. For the column header, it’s easy because it’s a different element type (<th/> instead of </td>). For the filters, I’ll just assign the row a specific class and add a parameter to the function to ignore this row.
  2. Second I have columns with actions which should always be displayed and a some columns I want to always be displayed (like the type which is a select box and needs to be there for the user to be able to change it). The solution is the same: Just add a new parameter with a class to ignore.

Here’s the current signature of the function:

function hideOneValueColumns(table_id, ignore_row_class, ignore_column_class) {
}

Almost done, only need some logic in the function ! 😉

First we’ll go through the column. One of the issues we have here is that columns are not directly modeled in the table. Instead a table contains multiple rows which contain cells. These cells are vertically align. So they display as columns but you cannot just select a given column directly. Moreover cells can span multiple columns and/or rows.

Disclaimer 1: I assume the table does not contain any cell spanning multiple rows or columns. It is the case in my example and it makes everything easier.

So to go through the columns means going through the cells of a given row and then considering the cells below them in the other rows. So let’s first start with the column header as it is anyway using a different HTML element:

$('#'+table_id+' th').each(function(i) {
}

In this function, we get a column index (or rather a cell index in this row). We can then use it to find the cells of the same columns in the rows of the table.

But first we need to check whether this column is one of the columns we wanted to ignore. One way to do it would be to extend the selector to not select these columns e.g.:

$('#'+table_id+' th:not(.'+ignore_column_class+')')

The problem is that the index you then get is relative to the selector you use. If you exclude cells in the header using a selector, you’ll need to fo the same afterwards for the other rows. So the cells in the other rows need to have the same class. I didn’t want that. So I implemented it this way:

 function hideOneValueColumns(table_id, ignore_row_class, ignore_column_class) {
    //first go through the column headers
    $('#'+table_id+' th').each(function(i) {
        //only process the column if it isn't one of the column we should ignore
        if (!$(this).hasClass(ignore_column_class)) {
        }
    });
}

Now we need to go through the cells of the columns and hide them or show them depending on the values of all cells in the column. But we need to consider the rows we are to ignore. On the other hand, we need to hide and show all cells in the columns no matter whether they are to be evaluated or not. So I’m just getting them with two similar selectors (you could of course get the first one and create the second list by filtering it but I do not think it’d be much faster or less resource intensive):

             //get all cells of the columns (in order to show or hide them)
            var all_cells = $(this).parents('table').find('tr td:nth-child(' + (i + 1) + ')');
            //get the cells we'll use to decide whether we want to filter the column or not
            var filtered_cells = $(this).parents('table').find('tr:not(.'+ignore_row_class+') td:nth-child(' + (i + 1) + ')');

In order to find out whether all cells have the same value, we’ll just go through the cells (ignoring the rows as specified) and gather the different cell values:

             //array containing the list of different values in a column
            var values = new Array();
            filtered_cells.each(function() {
                var value = this.innerHTML;
                if (values.indexOf(value) == -1) {
                    values.push(value);
                }
            });

If the value is not already in the array, just add it. Then we only have to show all cells in the column (including column headers) if there are at least 2 different values:

             if (values.length < 2) {
                $(this).hide();
                all_cells.hide();                    
            }
            else {
                $(this).show();
                all_cells.show();                    
            }

So we basically hide or show the column header (the <th> tag selected above) and all cells of the column.

That’s it. The complete code looks like this:

 function hideOneValueColumns(table_id, ignore_row_class, ignore_column_class) {
    //first go through the column headers
    $('#'+table_id+' th').each(function(i) {
        //only process the column if it isn't one of the column we should ignore
        if (!$(this).hasClass(ignore_column_class)) {
            //get all cells of the columns (in order to show or hide them)
            var all_cells = $(this).parents('table').find('tr td:nth-child(' + (i + 1) + ')');
            //get the cells we'll use to decide whether we want to filter the column or not
            var filtered_cells = $(this).parents('table').find('tr:not(.'+ignore_row_class+') td:nth-child(' + (i + 1) + ')');
            //array containing the list of different values in a column
            var values = new Array();
            //gather the different cell values
            filtered_cells.each(function() {
                var value = this.innerHTML;
                if (values.indexOf(value) == -1) {
                    values.push(value);
                }
            });
            //hide if less than 2 different values and show if at least 2 different values
            if (values.length < 2) {
                $(this).hide();
                all_cells.hide();                    
            }
            else {
                $(this).show();
                all_cells.show();                    
            }
        }
    });
}

You can call this function like this:

hideOneValueColumns('list-view-table', 'filters', 'no-hide');

Where “filters” is the class of the rows you want to ignore and “no-hide” the class applied to all columns which should not be affected by this function.

Another thing you could had: check whether the number of rows is more than 1 (in this case this whole thing makes no sense). In order to do it, you need to first find the number of rows (other than the one which should be ignored). Since we assume there is a column header row, we want to check whether we have more than 2 rows. Here’s how to compute the number of rows:

var row_count =  $('#'+table_id+' tr:not(.'+ignore_row_class+')').length;

If it is greater than 2, we do the same as above. Otherwise, we will just show all cells (since they might have been hidden previously):

$('#'+table_id+' th').show();
$('#'+table_id+' tr td').show();

Now the whole code:

 function hideOneValueColumns(table_id, ignore_row_class, ignore_column_class) {
    var row_count =  $('#'+table_id+' tr:not(.'+ignore_row_class+')').length;
    if (row_count > 2) { 
        //first go through the column headers
        $('#'+table_id+' th').each(function(i) {
            //only process the column if it isn't one of the column we should ignore
            if (!$(this).hasClass(ignore_column_class)) {
                //get all cells of the columns (in order to show or hide them)
                var all_cells = $(this).parents('table').find('tr td:nth-child(' + (i + 1) + ')');
                //get the cells we'll use to decide whether we want to filter the column or not
                var filtered_cells = $(this).parents('table').find('tr:not(.'+ignore_row_class+') td:nth-child(' + (i + 1) + ')');
                //array containing the list of different values in a column
                var values = new Array();
                //gather the different cell values
                filtered_cells.each(function() {
                    var value = this.innerHTML;
                    if (values.indexOf(value) == -1) {
                        values.push(value);
                    }
                });
                //hide if less than 2 different values and show if at least 2 different values
                if (values.length < 2) {
                    $(this).hide();
                    all_cells.hide();                    
                }
                else {
                    $(this).show();
                    all_cells.show();                    
                }
            }
        });
    }
    else {
        $('#'+table_id+' th').show();
        $('#'+table_id+' tr td').show();
    }
}

Post-it cards and 3D shadow effect with CSS3

After having a plain 2D post-it and a 3D rotated post-it, let’s now move to 3D shadow effects.

First we’ll start with a pretty simple post-it card:

<html>
	<body>
		<style>
			.card {
				width: 250px;
				height: 100px;
				padding: 10px;
				background: #FFFFA5;
				font-family: "Lucida Handwriting",cursive;
				font-size: 15px;
			}
		</style>
		<div class="card">
			<p>Buy some milk</p>
		</div>
	</body>
</html>

It looks like this:

simple post-it card

Then we’ll add some shadow so that it looks like the card is not stuck to the background:

.card {
	-webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1);
	box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1);
}

It now looks like this:

simple post-it card with shadow

Note that the shadow is not the same all over the card. It makes it more like a real card with real light and shadow.

Now we want to have a effect so that it looks like the card is not completely rigid but the corners are slightly curved i.e. they look further away from the background. Since we cannot just rotate the card and say that the rotation is non-linear (at least I don’t know a way to do it), we’ll have to use some kind of optical illusion using shadows.

Since our card already has a shadow, we’ll use two additional elements which will throw an additional shadow. Later on, we’ll use pseudo-elements to display them but right now, we’ll just use some normal divs for the sake of explaining how it works:

<style>
.shadow-element-before,
.shadow-element-after {
	width: 125px;
	height: 20px;
}
</style>
<div class="shadow-element-before"></div>
<div class="shadow-element-after"></div>

Note that these elements need to have half the width of the card (here it’s a fixed width but when building it in with pseudo-element you can use width: 50%). The height depends on how you like it, you should just experiment a little bit. I find 20% of the height of the card to be a good height for the effect.

We’ll also add the shadow we need for the effect:

.shadow-element-before,
.shadow-element-after {
	-webkit-box-shadow: 0 15px 10px rgba(0, 0, 0, 0.7);
	box-shadow: 0 15px 10px rgba(0, 0, 0, 0.7);
}

These elements will look like this:

shadow elements without rotation

Now we’ll want to rotate them slightly to create the illusion that the corner of the cards which are going up (even though actually it’s the shadow of these elements which is rotated):

.shadow-element-before {
	-webkit-transform: rotate(-2deg);
	transform: rotate(-2deg);
}

.shadow-element-after {
	-webkit-transform: rotate(2deg);
	transform: rotate(2deg);
}

The left one is rotated counter-clockwise and the right one clockwise. Here I only use the CSS3 property and the WebKit specific property as newer versions of FireFox do not need a browser specific prefix and I’m not much into Opera or IE. But if required, you could define copies of the box-shadow property with the following additional prefixes: -moz-, -o- and -ms-.

Here’s how the shadow elements look like with the rotation:

shadow elements with rotation

Now we can have them displayed as hidden pseudo-element. Hidden meaning they are displayed below the opaque card. So we have to do the following:

  1. Define the pseudo elements with :before and :after.
  2. Set an empty content for the pseudo element.
  3. Change the z-index of the pseudo-elements to have them displayed below the card.
  4. In order to be able to properly position the shadow elements, they have to have the position property set to absolute and the card should be set to relative.
  5. Since we’ve defined a bottom shadow for the pseudo element of 15 pixels, we’ll place them 15 pixel from the bottom so that you only see the blur of the shadow. If you want, you can reduce it to see a little more of the shadow.
  6. Position the shadow elements 10px from the left resp. from the right hand side so that the shadow below the card is not visible in the corners. This then looks like the corners are slightly lifted.

The code then looks like this:

<style>
	.card, .simple-card {
		width: 250px;
		height: 100px;
		padding: 10px;
		background: #FFFFA5;
		font-family: "Lucida Handwriting",cursive;
		font-size: 15px;
	}

	.card-shadow {
		-webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1);
		box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1);
	}

	.card {
		position: relative;
	}
	
	.card:before,
	.card:after {
		content: "";
		position: absolute;
		z-index: -5;
		bottom: 15px;
		width: 50%;
		height: 20%;
		-webkit-box-shadow: 0 15px 10px rgba(0, 0, 0, 0.7);
		box-shadow: 0 15px 10px rgba(0, 0, 0, 0.7);
	}

	.card:before {
		left: 10px;
		-webkit-transform: rotate(-2deg);
		transform: rotate(-2deg);
	}

	.card:after {
		right: 10px;
		-webkit-transform: rotate(2deg);
		transform: rotate(2deg);
	}

	.simple-card, .card-before, .card-after {
		margin-bottom: 40px;
	}
	
	.card-before,
	.card-after {
		content: "";
		width: 125px;
		height: 20px;
		-webkit-box-shadow: 0 15px 10px rgba(0, 0, 0, 0.7);
		box-shadow: 0 15px 10px rgba(0, 0, 0, 0.7);
	}

	.card-before {
		left: 10px;
		-webkit-transform: rotate(-2deg);
		transform: rotate(-2deg);
	}

	.card-after {
		right: 10px;
		left: auto;
		-webkit-transform: rotate(2deg);
		transform: rotate(2deg);
	}
</style>
<div class="card card-shadow">
	<p>Buy some milk</p>
</div>

And the card like this:

post-it card with 3D shadow effect

Just play around with the different properties and change their values to have the card look as you like.

3D effect on post-it cards with CSS

Some time ago, I’ve written a post about creating Post-it cards with CSS.

Now, instead of rotating the card, I wanted to have a 3D effect showing the card stuck on the board at the top and loose at the bottom. This can also be achieved with CSS3 transforms.

What you need for this is to define a container which will basically host the 3D effect and the card in it:

<html>
	<body>
		<div class='container'>
			<div class='card'>Buy some milk</div>
		</div>
	</body>
</html>

Now you need to define the size of the card on the container and have the card fully occupy it:

.container {
	width:250px; 
	height:150px;
	position: relative;
	margin: 10px;
}

.card {
	width: 100%;
	height: 100%;
	padding: 15px;
	position: absolute;
}

The paddings and margins are just there that it looks nicer. The container is set to relative positioning and the card to absolute positioning.

So that it looks like a post-it card, you’ll need to style it a little bit:

.card {
	width: 100%;
	height: 100%;
	padding: 15px;
	position: absolute;
	background: none repeat scroll 0 0 #FFFFA5;
	border: 1px solid black;
	box-shadow: 2px 4px 6px #444444;
	-moz-box-shadow: 2px 4px 6px #444444;
	-webkit-box-shadow: 2px 4px 6px #444444;
	font-family: "Lucida Handwriting",cursive;
	font-size: 15px;
}

It will look like this:

Post-it without 3D effect

Now to get the 3d effect, you need to:

  1. Define a perspective on the container. It basically defines how many pixels a 3D element is placed from the view.
  2. Define a transformation on the card slightly rotating in the middle on the horizontal axis.

The following should be added to the style of the container:

perspective: 100px;
-webkit-perspective: 100px;

Note that unlike what you will find googling for it, Firefox does seem to support the CSS perspective property without -moz- prefix (but you might need it for older versions of the browser). Also note that Chrome (and I guess Safari too) does require a browser specific prefix.

And the following should be added to the style of the card:

transform: rotateX(4deg);
-webkit-transform: rotateX(4deg);

Here again note that you require a -webkit- property for Chrome but can use the one without browser prefix for the newer versions of Firefox.

And you’re done. The card then looks like this:

Post-it with 3D effect

Here the complete sample code in case you just want to quickly copy and paste it:

<html>
	<head>
		<style>
.container {
	width:250px; 
	height:150px;
	position: relative;
	margin: 10px;
	perspective: 100px;
	-webkit-perspective: 100px;
}

.card {
	width: 100%;
	height: 100%;
	padding: 15px;
	position: absolute;
	background: none repeat scroll 0 0 #FFFFA5;
	border: 1px solid black;
	box-shadow: 2px 4px 6px #444444;
	-moz-box-shadow: 2px 4px 6px #444444;
	-webkit-box-shadow: 2px 4px 6px #444444;
	font-family: "Lucida Handwriting",cursive;
	font-size: 15px;
	transform: rotateX(4deg);
	-webkit-transform: rotateX(4deg);
}
		</style>
	</head>
	<body>
		<div class='container'>
			<div class='card'>Buy some milk</div>
		</div>
	</body>
</html>

HTML5: New HTML5 semantic tags

Note: Eine deutsche Version des Artikels findet ihr bei amazingweb

In the early days of web development, HTML was used to define the content, structure and  appearance of a website.
With the introduction of CSS, there was a migration to a kind of Model-View pattern where CSS was responsible for the view i.e. the appearance and HTML only for the content and structure i.e. the model.
Using JavaScript (and especially with the many JavaScript libraries currently available), it has gradually evolved a Model-View-Controller pattern, where JavaScript has assumed the Controller role.
But the blending of content and structure was still there. The problem is not only that both content and structure are defined in HTML, but that there was no real way to separate or distinguish them.

The structural aspect of HTML, before HTML5, was usually reduced to a tree of div and span tags. This is nothing more than a grouping of parts of the site, which mostly results from the need to address these parts separately in CSS or JavaScript. So it was more a presentation or controller-driven organization of content, but in no case a semantically-related structuring.>

HTML5 now addresses this very issue. HTML becomes semantic. Specifically, it means that in HTML5 the different logical parts of a web page can now also be defined with dedicated HTML tags. Most websites have such a structure (or a relatively similar structure):

web site structure

Such a structure is typically encoded as:

<body>
    <div id="header">
        <h1>Titel</h1>
        <h2>Untertitel</h2>
    </div>
    <div id="navigation">
        <div id="menu_item1" class="menu_item">...</div>
        <div id="menu_item1" class="menu_item">...</div>
    </div>
    <div id="content">
        <div id="post1" class="post">...</div>
        <div id="post2" class="post">...</div>
        <div id="post3" class="post">...</div>
        <div id="post4" class="post">...</div>
    </div>
    <div id="sidebar">
        <div id="widget1" class="widget">...</div>
        <div id="widget2" class="widget">...</div>
        <div id="widget3" class="widget">...</div>
        <div id="widget4" class="widget">...</div>
    </div>
    <div id="footer">
    </div>
</body>

So there was already a semantic structuring of the web pages before HTML5. But there was no standardized structure, so everyone could do it in a different way and it was not possible to parse it universally.
The only truly semantic tags that were in HTML4 were the header tags (h1 to h6). They were unfortunately often understood as formatting tags, even if slowly their interpretation by search engines made them more semantical again.

New tags were defined in HTML5 to allow replacing most of the div container structure and encode web pages using a standardized page structure. In HTML5, the same page would look like this:

<body>
    <header>
        <hgroup>
            <h1>Titel </h1>
            <h2>Untertitel</h2>
        </hgroup>
    </header>
    <nav>
        <div id="menu_item1">...</div>
        <div id="menu_item1">...</div>
    </nav >
    <section>
        <article>...</article>
        <article>...</article>
        <article>...</article>
        <article>...</article>
    </section>
    <aside>
        <section>...</section>
        <section>...</section>
        <section>...</section>
        <section>...</section>
    </aside>
    <footer>
    </footer>
</body>

The nav tag can either be positioned within the header tag or outside. It depends on how exactly one understands the header tag.

The section tag is relatively similar to the div tag. The difference is that the section tag also means that the contents being combined are also linked thematically which was not always the case with the div tag.

The header tag can of course also be used in an article or section tag to define the title of an article or the widget name. It is also interesting to see that in modern browsers the appearance of h1 to h6 tags is different depending on what level they are defined in. The following:

<body>
    <section>
        <header>
            <h1>Articles</h1>
        </header>
        <article>
            <header>
                <h1>Article</h1>
            </header>
            <section>
                <h1>Section</h1>        
             </section>
         </article>
     </section>
</body>

Looks like this:

Different H1 sizes

These header tags have again a semantic meaning and are no longer pure formatting elements.

This new HTML5 structure is nice and semantically meaningful. But it has one drawback: Older browsers do not understand it. So often the two structures are combined. The older browsers simply ignore the new tags, they do not know and will only see the old structure. But newer browsers see both structures, which is ugly (but if you must support older browsers, you’re used to compromises anyway). Such a combined structure would look like this:

<body>
    <header>
        <hgroup>
            <div id="header">
                <h1>Titel</h1>
                <h2>Untertitel</h2>
            </div>
        </ hgroup>
    </header>
    <nav>
        <div id="navigation">
            <div id="menu_item1">...</div>
            <div id="menu_item1">...</div>
        </div>
    </ nav>
    <section>
        <div id="content">
            <article>
                <div id="post1">...</div>
            </article>
            <article>
                <div id="post2">...</div>
            </article>
            <article>
                <div id="post3">...</div>
            </article>
            <article>
                <div id="post4">...</div>
            </article>
        </div>
    </section>
    <aside>
        <div id="sidebar">
            <section>
                <div id="widget1">...</div>
            </section>
            <section>
                <div id="widget2">...</div>
            </section>
            <section>
                <div id="widget3">...</div>
            </section>
            <section>
                <div id="widget4">...</div>
            </section>
        </div>
    </aside>
    <footer>
        <div id="footer">
        </div>
    </footer>
</body>

Of course, with such a structure, the question is justified, whether it even makes sense to use the HTML5 semantic tags. There are basically 2 cases:

  • If you do not have to support older browsers (lucky you !), you can simply replace the old div tags with the new semantic tags.
  • If it is not the case, even though it is more work and the legibility suffers however from a functional perspective, you lose nothing compared to the old structure and the new HTML5 tags will slowly play an ever increasing role for search engines. With them it could be ensured that visitors arrive mostly because of the content on the page and not because there is something in the sidebar. The bounce rate would thus decrease.

Moving to the new HTML5 tags is recommended in the long term in any case, and is not a huge effort on a more technical side.

HTML5: time, datetime and pubdate

The HTML5 tag <time> addresses the need for semantically tagging a date or time. It allows defining both a machine readable and human readable version of a date or time. This way you can just have Yesterday displayed and let a machine parsing your page that it’s actually December, 7th 2012.

This is also of course useful for working with timezones. Let’s say you’re living in Germany but are on a business trip to India and write about doing something at 2pm. For the reader, it’s obvious that it’s 2pm Indian Standard Time but a machine will not understand that when you write 2pm, it usually means 2pm Central European Time but in this particular page/post it’s not the case. On the other hand, I don’t think that any human being likes reading date/times with time zone info (especially when it’s clear from the context which time zone is meant).

Using a <time> tag is as easy has writing <time>2011-12-25</time>. Of course, here you just tag “2011-12-25” as a date/time info but other than that it doesn’t really carry more info. If you do not use the datetime attribute, the content of the time tag must be a valid date/time i.e. contain a machine readable date/time.

Now, it really get’s interesting when I can write “last Christmas” and a machine parsing this understand I mean December, 25th 2011. That’s also really simple, just write <time datetime="2011-12-25">last Christmas</time>. This will be displayed as but will be interpreted by a machine as 2011-12-25.

Instead of a date, you could also have a time e.g. <time datetime="14:00">at 2pm</time> or a date and time e.g. <time datetime="2012-12-08T12:07+01:00">Now</time>.

If you specify a date and a time, you have to specify a UTC time offset or use “Z” for UTC time e.g. 2012-12-08T12:07+00:00 is the same as 2012-12-08T12:07Z.

You can also write a date omitting the year e.g. 12-08 for December 8th or a duration. Durations are defined by a P (for period of time) followed by the duration definition:

  • PnYnMnDTnHnMnS e.g. P3Y for three years or PT2H25M for 2 hours and 25 minutes
  • PnW e.g. P2W for 2 weeks

Note that P1M is a one month duration and PT1M is a one minute duration.

One restriction with <time> is that it can only represent in the Christian Era. Older date cannot be encoded. So if you’re writing an online biography of Julius Caesar, you can forget the <time> tag (except when referencing other books written about him later on).

Note that the <time> tag was removed from the HTML5 specification last year (to be replaced by the <data> tag) but made it again in HTML5 shortly afterwards. So it’s future is not 100% clear but at least it made it in WordPress and Drupal so it’s quite widely used.

The pubdate attribute is used to tell whoever is parsing the time tag that the time value is related to the time when article/document was published. To be exact, it indicates the date of publication of its nearest <article> ancestor if present or the entire document. There are good chances that pubdate will be removed from the HTML5 specification. That’s why HTML5 validators report its presence (and why I’ve removed it from my theme).

Check username availability using jQuery and PHP

I’m working on a new website. I currently only have a screen where the new users can register. Since I want to make it as easy as possible for a new user to register (partly to avoid having them give up in the first few minutes), I need to take care of the username issue:
When you register somewhere, you have to enter a few things about yourself and though I’m sticking to only username, email address and password it’s still a pain to fill it all in, click submit and get the message that the username is not free.
It’s much easier on the new user, if you immediately give him feedback whether the username he has chosen is still free. And it’s much better, if he doesn’t have to click X times on the “check availability” button.

So basically what I need is a form with a username text field. And whenever the user types in something, I want to give some visual feedback (like changing the color of the text field border) whether this username is available or not.

First I need a form element (in the body):

<form method="post" action="register.php">
	<label for="username">Username</label>
	<input type="text" maxlength="30" name="username" id="username">
	<input type="submit" value="submit">
</form>

Of course such a form with only a username makes no sense, but it’s good enough to explain what I’m doing…

Next, we need to do some jQuery magic (in the head section):

<script src="jquery-1.8.0.min.js"></script>
<script>
$(document).ready(function(){
	$('#username').keyup(check_username);
});

function check_username(){
	var username = $('#username').val();
	if(username == '' || username.length < 6){
		$('#username').removeClass("available").removeClass("notavailable");
	}
	else {
		jQuery.ajax({
			type: 'POST',
			url: 'check_username.php',
			data: 'username='+ username,
			cache: false,
			success: function(response){
				if(response == 1){
					$('#username').removeClass("available").addClass("notavailable");
				}
				else {
					$('#username').removeClass("notavailable").addClass("available");
				}
			}
		});
	}
}
</script>

A few comments on this part:

  • I use keyup to install my function because I want the check to happen as the user types. If it creates too much network traffic for your taste or it’s good enough for you to only check the availability when the user leaves this text field, you could use change() or blur().
  • Since in my case the username needs to have at least 6 characters I do not check usernames with less than 6 characters.

As you see I use some CSS classes to change the appearance of the text field based on the availability of the username, here the CSS part:

.notavailable {
    border: 3px #C33 solid !important;
}
.available {
    border: 3px #090 solid !important;
}

Instead of changing the border color, you could also change the background color or show a tick or cross sign…

Now let’s have a look at the last piece: the PHP part on the server, check_username.php (which is called using Ajax):

<?php
$username= mysql_real_escape_string($_REQUEST["username"]);
$con = mysql_connect("xxxxxx","xxxxxx","xxxxxx");
if (!$con)
{
	echo 0;
}
else {
	mysql_select_db("xxxxxx", $con);
	$result = mysql_query("SELECT * FROM users WHERE username='" . $username . "'");
	$num = mysql_num_rows($result);
echo $num; //it will always return 1 or 0 since we do not allow multiple users with the same user name.
}
mysql_close();

That’s it ! And this is how it looks like:
Green border when the user name is available
Red border when the user name is not available

Three column layout

The first possibility (and oldest one) is to simply use HTML tables to create the three columns. Basically, you create a table which only has one row and 3 columns.


<table width=”100%”>
    <tr>
        <td width=”20%” style=”vertical-align: top;”>  
        …
        </td>
        <td width=”50%” style=”vertical-align: top;”>
        …
        </td>
        <td width=”30%” style=”vertical-align: top;”>
        …
        </td>
    </tr>
</table>

Pros: 

  • wide browser support

Cons: 

  • polluting the HTML with non-semantic tags
  • the content is not displayed the same when in a div tag or in a table cell

In order not to pollute our content with non-semantic tags (<table>,<tr> and <td>), the obvious solution is to switch to CSS tables. This allows to use semantically meaningful div tags by only having the formatting tables in CSS.


Here the HTML code:
<div id=”leftcol”>


</div>
<div id=”middlecol”>

</div>
<div id=”rightcol”>

</div>

And the CSS:

body {

    display: table; width: 100%
}
 
#leftcol, #middlecol, #rightcol {
    display: table-cell;
}
 
#leftcol {
    width: 20%;
}
 
#middlecol {
    width: 50%;
}
 
#rightcol {
    width: 30%;
}

Pros:

  • not polluting the HTML with non-semantic tags



Cons:

  • doesn’t work in IE7 and earlier
  • using CSS tables does affect the rendering of the contents
The third possibility is to use CSS floats. Here we basically define a central column with a margin as wide as the left column and then have the left and right columns respectively float on the left and right side of the central column.

Here’s the HTML:
<div id=”middlecol”>

</div>
<div id=”leftcol”>

</div>
<div id=”rightcol”>

</div>

It’s important to first define the div for the middle column. From a semantic point of view, we could consider it being actually better since it’s usually the main content column and the other 2 usually contain the navigation and sidebar.

Here’s the CSS:

#middlecol
{
    float: left;
    width: 50%;
    margin-left: 20%;
}
#leftcol
{
    float: left;
    width: 20%;
    margin-left: -70%;
}
#rightcol
{
    float: left;
    width: 30%;
}

Pros:

  • not polluting the HTML with non-semantic tags
  • doesn’t impact the rendering of the columns (except their positions)

Cons:
  • doesn’t work in older browser