Posts Tagged ‘HTML’

A sliding drawer type thing feat. jquery

A while ago a friend of mine realized he had so many employees that listing them all on a single page would make for one of great length. A strange problem to have.
Using some simple CSS and Javascript we can hide the bulk of the information and show only what is necessary. You know, for increased usability and all that:

A definitions list provides the perfect data structure for our purposes:

A bird
This is a picture of a bird sitting an a tree, and looking quite proud of that.
A cave
This is the description of the cave.. Tor lives here, and is a Zombie.
A zombie
Poker was pretty popular for a while, even the zombies got into it.
Bobby
This is a picture of bobby. I actually have a giant version of this framed on a wall over to the right.

For each entry, we have a title (dt) and the data itself (dd). After the definition list, we have an empty div identified as info_container. This is where we’ll display the appropriate data.

The HTML itself is pretty minimal and hopefully clear, which is just the way we like it.

The javascript is a bit more complicated:

google.load("jquery", "1");	// We want jquery... let's say version 1?
google.setOnLoadCallback( // Once google tells us JQuery has finished loading, we can do some stuff
	function() { // This is the annonymous function google will call-back
		$('dl.drawerify dt').click( //Every time we click a dt in the drawerified definitions list
			function() {
				var new_one = $('dl.drawerify dt').index(this);
				if (selected == new_one) return;  // Don't do anything if we've clicked on the one that's already open
				$('dl.drawerify dt:nth('+selected+')').removeClass('current');
				selected = new_one;
				$(this).addClass('current');
				show_info($(this).next('dd').html() ); // Fill the info_container
			}
		);
		$('dl.drawerify dt:first').click(); // Initially, we want the first one shown (so we just fake-click on it)
	}
);

var selected = -1; // The index of the currently displayed entry in the definitions list

// Fill the info_container with the appropriate data
function show_info( desc ) {
	var container = $('#info_container');
	if (container.html().length > 0) {

	// Animate the drawer retracting
	  container.animate({
		width: "0px"
	  }, 300, "swing", function() { container.html(''); show_info( desc ); } );

	} else {
		container.html("
" + desc + "
"); // Fill the container // Animate the drawer extending container.animate({ width: "250px" }, 300, "swing" ); } }

The first line is us telling Google that we want to use JQuery. We could just include JQuery ourselves, but man we are way too lazy for that.

We want only one dt tag to have the current class applied to it at a given time. Lines 8 removes the class from the previously selected dt and line 10 adds it to the new one, using various jquery selector strings.
In line 11, we pass the contents of the dd immediately following the current dt to the show_info function.

Now comes the animation part. Jquery provides a function called animate. We can use it to animate things!
Starting at line 23, the logic goes a little something like this:
If there there is already information in the info_container, we want to retract the drawer. If not, we’re good to extend it once we’ve filled it with the new content.

A lot of jquery functions take callbacks as optional parameters, which is useful for us because once a drawer has closed we’d like to clear it of content and then fill it with new content and open it. That last part sounds an awful lot like what we’d do anyway if the drawer were empty. So maybe all we really have to do is clear it of content, and then have the show_info function call itself with its original parameters? Sounds good to me, and we can totally do it with another anonymous function. That’s what line 28 is about.

And now the Javascript is done! That wasn’t so complicated? I am a big fan of anonymous functions.

Next comes the CSS. This is where we’ll define what the drawer-thing looks like:

dl.drawerify, #info_container {
	height: 108px;
	background-color: #fff;
	padding: 10px;
}
dl.drawerify {
	width: 140px;
	float: left;
	margin: 0px;
}
dl.drawerify dt.current {
	color: #ffffff;
}

dl.drawerify dd {
	display: none;
}
dl.drawerify dt {
	cursor: pointer;
	font-weight: bold;
	background: #324e63;
	color: #b3c4d2;
	font-family: arial, verdana;
	padding: 3px;
	padding-left: 10px;
	margin-bottom: 1px;
	font-size: 16px;
}
dl.drawerify dt:hover {
	background-color: #233544;
}
#info_container {
	width: 0px;
	float: left;
	overflow: hidden;
	font-family: verdana;
	font-size: 8pt;
	padding-left: 0px;
	color: #324e63;
}
#info_container .inner {
	width: 220px;
}
#info_container img {
	margin-right: 10px;
	float: left;
}
body {
	background-color: #EDEFF0;
}

The most important parts of the css are:
Line 7 and 8 let us display info_container to the left of the definitions list, rather than below it.
Line 19 tells the browser to display the little hand icon when you mouse-over the definition titles instead of an arrow (like when you mouse-over a link).
Line 35 and 42 allow the animation to work nicely. 35 tells the browser to clip anything that exceeds the dimensions of the info_container, and 42 sets the width of the inner div. By setting it, we prevent its width from automatically changing to fit within info_container. That way its content doesn’t get re-arranged during the animation.

The complete code is available, though everything important can be found above.

PHPing a very simple form

We’re going to create the same form as last time, but enhance it a bit using PHP and MySQL. Where applicable, I’ve linked parts of the code to the appropriate documentation where you can find more information and possibly cake.

We’ll be using more than one PHP file, just to show off require_once.

The first step is to connect to the database. I’ll include a couple of simple functions for dealing with the resources returned.

This file is called mysql.inc.php:


<?php

This is the magical start tags that ends with ?>. Between these two guys is where we place our PHP code. You can have more than one PHP block per file, as you'll see below, and the "php" succeeding the ? character isn't actually necessary.

//configuration information

These two slashes start a single-lined comment. Anything following those two characters, until the line ends is ignored by PHP - you know, for documentation? :p

$server = 'localhost';
$username = '';
$password = '';
$database = 'quizes';

Variables begin with the $ character, and all statements are terminated using the ; character.

//connect to the database
mysql_connect($server, $username, $password);
mysql_select_db($database);

//retrieve rows from a table as an array of associative arrays
function sql_getRows($query) { //$query is a line of SQL we will pass to the function
   $rows = mysql_query($query);
   return sql_assoc($rows); //this function is defined 3 lines from now
}

//turn a mysql resource into an array of associated arrays
function sql_assoc($resource) {
   $i = 0;
   $values = array();
   while ($row = mysql_fetch_assoc($resource)) {
     foreach($row as $k => $v) $values[$i][$k] = $v;
     $i++;
   }
   return $values;
}
?>


 

Okay, and now for the form! We’ll call this file index.php:


<?php

require_once
('mysql.inc.php');

We're telling php to require the inclusion of the file we just made (above). We could have used include_once, but it won't work without that file anyway.

//create the html for a select box populated with clients from a database
//we want all of the clients

$clients = sql_getrows('SELECT client_id, client_name FROM clients');

This is the SQL select query we're sending to the database through our sql_getrows function. Since we want all the clients, we left off the WHERE clause. We are also explicitly specifying fields by name - the * character can be used if you'd like to grab all the fields.

The format of the data we get back will be an array of associative arrays - so what we are getting is a nested array. The first level is indexed numerically; the second by they database table field name. To access the client_id of the first record returned, you would use the syntax $clients[0]['client_id']. Or, you can use a loop to run through the data:

$select_html = "<select name=\"clientId\">\n";

Right now we're creating a string (stored as the variable $select_html) which consists of the HTML necessary for a select box.

\ is an escape character. One set of quotes tells PHP where our string starts and where it ends, another is part of the HTML we'll be outputting. If we have quotes within quotes, we have to escape them using the \ character. Similarly, it is used for special characters like \n - which is the new line character. The new lines won't change how your form is displayed within the web browser, but they can be important if you're going to be viewing the source created. The same goes for \t, except that it is the tab character. Outputting well-formatted code can help with debugging.

foreach($clients as $c) {
$select_html .= "\t<option value=\"". $c['client_id'] ."\">". $c['client_name'] ."</option>\n";

Foreach loops can take the form ($array as $key=>$value), or just ($array as $value) - this is the latter. Each time it loops through the clients list, we use the variable $c to reference that client's information. $c is itself an associative array keyed by the client table's field names (that we requested via SQL).

}
$select_html .= "</select>\n";

the . character is for string concatenation. Placing it before the = symbol is the same as writing $select_html = $select_html . "</select>\n";. So we're just appending to the string already held in the variable.

?>

Here ends our first php block for the file

<h1>Quiz maker</h1>

<form method="post" value="form-handler.php" >

<p>Client: <? echo $select_html; ?></p>

This is a single statement within a php block. Echo just tells php to output the value of $select_html variable here.

<p>Name: <input type="text" name="QuizName" value="MyFirstQuiz" /></p>
<p>Date: <input type="text" name="QuizDate" value="<? echo date("Y-m-d"); ?>" /> <small>YYYY-MM-DD</small></p>

<table>
<tr>
<th>Question</th><th>Answer</th>
</tr>
<tr>
<td><input type="text" name="questions[]" /></td>
<td><input type="text" name="answers[]" /></td>
</tr>
<tr>
<td><input type="text" name="questions[]" /></td>
<td><input type="text" name="answers[]" /></td>
</tr>
</table>

<input type="submit" value="Create »" />
</form>


Now we have a form!
Next time, maybe the form submission handler? Or maybe a blog about perfume? Or maybe installing Magento on Dreamhost? I don’t even know!

Also, it’s neumann‘s birthday.

A very simple form

I’m going to explain a very simple HTML form, that is prepared for processing by PHP. Then later I’ll describe a similar PHP file that retrieves a client list from a database.

Here’s the form we’ll be looking at:


Quiz maker

Client:

Name:

Question Answer

Ignore the styling if you can, it’s getting that from the GC’s CSS. Here’s the HTML for that form:



<h1>Quiz maker</h1>

Heading one, the first level of headings. Similar to h2, and h3.

<form method="post" value="form-handler.php" >

This is where we specify the file that will process the form, once it's been submitted. We haven't written this guy yet.

<p>Client: <select name="ClientId">
<option value="0">Select a client</option>
<option value="3">The International Test Company</option>
<option value="4">agency&bull;nu</option>
<option value="14">J# Industries</option>
</select></p>

Select tags make those select boxes. Each option of a select box is defined by one of those nested option tags.

The value attribute of the selected option is what will be sent when the form is submitted. In this situation, we want to send the ClientID.

<p>Name: <input type="text" name="QuizName" value="MyFirstQuiz" /></p>

An input of type text gives you a single-line box that you can type into.

<table>
<tr>

This guy specifies a table row, which ends at the next </tr> tag.

<th>Question</th><th>Answer</th>

A table heading field.

</tr>
<tr>
<td><input type="text" name="questions[]" /></td>

The name field of a form element is how we will access the submitted data during the processing phase. The [] at the end of the name means php will read this data as new element in a questions array. This way, we can loop through the two arrays (questions, and answers) and they will match up.

<td><input type="text" name="answers[]" /></td>
</tr>
<tr>
<td><input type="text" name="questions[]" /></td>
<td><input type="text" name="answers[]" /></td>
</tr>
<tr>
<td><input type="text" name="questions[]" /></td>
<td><input type="text" name="answers[]" /></td>
</tr>
</table>

<input type="submit" value="Create &raquo;" />

This guy makes the button we'll have to press to submit the form.

</form>


That’s basically it. Next time: The same thing but with more PHP :P

returning false; this is a weird post at sheldon’s insistence

Days ago, I shared a conversation with a man named Jeff. We met in an alley off the a lesser-known junction of the Canadian arterial internet pipe. I was afraid, at first, as he is tall and wildly bearded. But he was not an electronic mugger, and wished instead to discuss an issue encountered while using XHTML Strict.
This was convenient for me, for I had no wish to be mugged, and he said: When clicking on links to #, you are jumped to the top of the page.

<a href=”#” onclick=”do_some_js_stuff();”>JS Interface link</a>

I agreed with him, not yet convinced his intentions completely mug-free, and suggested returning false.

<a href=”#” onclick=”do_some_js_stuff(); return false;“>JS Interface link</a>

Dawn found my words effective, as I left that alley with both wallet and dignity.

But the experience got me thinking. I would prefer an internet better lit, and I might approach it like this:

<a href=”#” class=”jsui” onclick=”do_some_js_stuff();”>JS Interface link</a>

And with jquery, use the jsui class to automatically return false on clicks:

$('.jsui').click( function() { return false;});

An other option would be to return the return value of the event handler you’re already using:

<a href=”#” onclick=”return do_some_js_stuff();”>JS Interface link</a>

And just be sure to return false from applicable handlers.

In summary, when clicking on a link to # while using XHTML Strict, you will be jumped to the beginning of the page. We can combat this by returning false. There are many ways you can do that, but which you use probably only matters if you are a snob.

.