HTML5, The Audio Element

Adding audio to HTML documents has always been challenging. HTML requires you to use a plug-in for audio controls. An HTML plug-in could be described as software that runs embedded into, or “on top of”, your web browser. Before Flash dominated the market, the plug-ins you could use for this were Windows Media Player, QuickTime, and Real Audio. The problem with this was that not everybody had these plug-ins installed on their computer, and that goes for Flash as well. You often times had some text explaining which media player works best with the website and required users to download and install it themselves. If you were thorough, you would write some unnecessary JavaScript to try and determine the plug-in that would work best, and since each plug-in has its own way of doing certain things, it only made the procedure that much more of a “task”. Things change with HTML5.

HTML5 comes with its very own <audio> element. To have audio in your HTML5 document, you use the following code:

<audio src="audio_file.mp3"></audio>

If you want to give your users controls, such as play and pause, you need to specify the ‘controls’ boolean attribute. A boolean attribute doesn’t have a value, if it’s there, the value is true, and if it’s not there the value is false. If you’re coding an XHTML document, you could say controls=”controls”.

<audio controls src="audio_file.mp3"></audio>

If you want to auto-play your file, you can use the ‘autoplay’ attribute. If you don’t want to auto-play, but you know the file will be played at some point, you can buffer, or pre-load the file. Buffering will tell the browser to download the file, but not to play it yet. There are two attributes for buffering: ‘autobuffer’ and ‘preload’. ‘autobuffer’ is a boolean attribute, and therefore does not take any values, merely having it in your attribute list will turn on auto-buffering. But beware, Safari auto-buffers by default. The ‘preload’ attribute takes the following values: none, auto and metadata. Using preload=”none”, you can explicitly tell browsers not to buffer the audio, and in turn, not to download the audio file until the user’s ready to listen to it. If you have a site with multiple audio files on one page, allowing them to auto-buffer would consume a lot of unnecessary bandwidth.

<audio controls autobuffer src="audio_file.mp3"></audio>
 
OR
 
<audio controls preload="none" src="audio_file.mp3"></audio>

Easy, right? Almost perfect? Yep, almost. Unfortunately there are these things called patents, and while some audio formats are free to use and develop with, some are patent protected. The MP3 audio format is patent protected, while the M4A or AAC is patent encumbered. What this means to you is that every browser may not support the audio format you have. The audio element has an optional ‘child’ element called ‘source’. You can use it to specify various formats or even different URL locations for your audio track. The browser will use whichever one it finds that it supports or can play. The format of choice in the open-source realm is OGG Vorbis, .ogg files. FireFox and Opera support OGG but Safari does not. This means that you will most likely have to find yourself audio software that will convert between audio formats. Thankfully, many exist. This also means that you may need to upload multiple copies of your audio file to the web server.

The ‘source’ element has two attributes, ‘src’ and ‘type’. The ‘src’ attribute let’s you specify the URL to where the audio-file is located. The ‘type’ attribute is optional, it allows you to specify the audio format type for each file. If the ‘type’ attribute is not provided, the web browser will try to determine the file type on its own – most likely by fetching the header information from the URL. Other content that goes inside the audio element should be ignored by browsers which support it, but rendered by browsers that do not. This way you can provide a failsafe for those not supporting HTML5 or the HTML5 audio element.

<audio controls>
	<!-- specify file types with the source element -->
	<source src="audio_file.mp3" type="audio/mp3">
	<source src="audio_file.ogg" type="audio/ogg">
 
	<!-- display a flash player in unnsuported browsers -->
	<object type="application/x-shockwave-flash" data="media_player.swf?file=audio_file.mp3">
		<param name="movie" value="media_player.swf?file=audio_file.mp3">
 
		<!-- if flash isn't supported, display a link -->
		<a href="audio_file.mp3">Download the file</a>
	</object>
</audio>

Example

Here is an example that should fall back to using a custom Flash player I made, if your browser isn’t equipped with the HTML5 audio element. Enjoy the music!

Making Me Nervous, By: Brad Sucks:

VN:F [1.9.22_1171]
Rating: 8.8/10 (13 votes cast)
VN:F [1.9.22_1171]
Rating: +6 (from 8 votes)
Share/Save

3 Comments

Randomizing Javascript Arrays

An array in JavaScript is like a collection of data. When one variable usually stores one value, an array stores multiple values. Each value is associated with an index position, otherwise known as ‘array key’. If you would like to learn more about arrays and how they work, read this article: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array

If an array were a deck of cards, one might say that we need to “shuffle the deck”. That’s exactly what we need to do in this situation, but it’s better referred to as “sorting the array”. We need to change the order that the array is sorted in. The Array data type is really an object in JavaScript, and like most objects, it comes pre-built with methods (functions) that we can take advantage of. One method of interest is ‘sort’.

The Array’s ‘sort’ method accepts a callback function as an argument and uses it to compare the data inside the array. A callback function is a reference to a function that can be executed at a later time in your code. This can be better referred to as a ‘compare function’, because that’s what it’s there for, to compare the data. When executed, the ‘compare function’ is passed two valus from the array. If the ‘compare function’ is not provided, the array will be sorted in alphabetical order. See this website for detailed information on the Array’s ‘sort’ method: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/sort.

The idea is, you compare the data that gets passed to the ‘compare function’ and return a numerical value. The array gets sorted based on the values you return. The values can be less than 0, greater than 0, or exactly 0. Each value has special importance for how the data gets sorted. So, basically, we need a random number that meets this definition. For this, we use Math.random().

Math.random() returns a random number between 0 and 1. This is almost perfect, but we miss an entire number range, less than 0. Since the value from Math.random() could be 0.12, or 0.5, or 1, or even 0, we can subtract 0.5 from it to include the negative numbers in our range, and we still have the possibility of getting 0 or a value greater than 0. And so we have the following code:

?View Code JAVASCRIPT
var my_array = ['one','two','three'];
 
my_array.sort(function(){
	return Math.round(Math.random()) - 0.5;
});

A Not So Shuffled Array

At a glance, this looks like it should be perfect for what we need. When observed more carefully, though, we find inconsistancies in how the items actually get shuffled. This is due to the way the ‘sort’ method actually works. It’s based off the Bubble Sort algorithm. The bubble sort says, if A < B and B < C then there's no need to compare A and C. Because of this, some items may not actually get shuffled, and we end up with a not so shuffled array.

Fisher-Yates Shuffle

In 1938, two men known as Ronald Fisher and Frank Yates, outlined a way to randomize a list of numbers. We refer to it now as, the Fisher-Yates Shuffle. This method was released in their book, Statistical tables for biological, agricultural and medical research, and was designed to be implemented using pencil and paper. The method worked like this:

  1. Write down the numbers from 1 to N
  2. Pick a random number, k, between one and the number of unstruck numbers remaining (inclusive)
  3. Counting from the low end, strike out the kth number not yet struck out, and write it down elsewhere.
  4. Repeat from step 2 until all the numbers have been struck out.

Knuth Shuffle

If you were going to code the Fisher-Yates Shuffle using JavaScript, you would most likely model it off what we know as the Knuth Shuffle. In 1964, Richard Durstenfeld modernized the Fisher-Yates Shuffle for computer use in his book, Communications of the ACM, volume 7. This modernization was made popular as the Knuth Shuffle, by Donald E. Knuth, in volume 2 of his book, The Art of Computer Programming.

This approach is a little more difficult to implement than using ‘sort’, but the results are worth it. It works by looping the array backwards, and each time through, swapping the current item with a random item. The range that it uses to generate a random number follows the rule, 0 <= random number <= current index. If given an array with 4 items, the 4th item in the array will be swapped with an item at index positions 0, 1, or 2. The 3rd item will be swapped with the item at index positions 0 or 1. The 2nd item won't actually be so random, it will swap with the item at index position 0, the first item. At this point, the first item may or may not have already been swapped. By the time the fourth iteration occurres, all of the items in the array should have been shuffled, so it only loops n - 1 times, where 'n' represents the amount of items in the array. Here's what it looks like in JavaScript. I've attached it to the Array's prototype object so that every array has access to it.

?View Code JAVASCRIPT
Array.prototype.randomize = function()
{
	var i = this.length, j, temp;
	while ( --i )
	{
		j = Math.floor( Math.random() * (i - 1) );
		temp = this[i];
		this[i] = this[j];
		this[j] = temp;
	}
}
 
var my_array = ['one','two','three'];
my_array.randomize();

Contrasted Example

View: Live Example.

VN:F [1.9.22_1171]
Rating: 9.6/10 (16 votes cast)
VN:F [1.9.22_1171]
Rating: +4 (from 4 votes)

1 Comment

CSS Sprites

Simply put, a sprite, when used in your Cascading Style Sheet, is one image containing multiple images. The idea behind using a sprite is to lesson the amount of HTTP Requests your webpage makes to the server, and also try to limit the amount of data being downloaded from the server. If done correctly, this can greatly increase your website’s load times. You see it more often on bigger websites, such as Youtube. Bigger sites that have an intense amount of traffic need to limit the amount of requests made to their web servers. Big site or small, though, you should use sprites in your CSS whenever possible.

If you take a look at Youtube, you will notice that just about the entire site is in one sprite. This works because their site design is minimal enough to support it all on one. It’s likely that you will have more design aspects and will need more images, and so in that case you should use multiple sprites, and whenever possible. They are very common among content-tabs, or with any boxy design where you need rounded corners. They are also utilized very well when you need to provide multiple themes for a given design. One sprite can contain all the icons for a given theme, and so when the site operator wants to switch themes, the code just needs to load a new image. If every themed sprite has the same elements positioned in the same place, all of the CSS stays the same and you have a new look on your site. Their most common usage, though, is probably for rollover images.

When creating a sprite, each image has its own placement, with a small amount of space (if any) between it and the next image. Sprites work with the background-position CSS rule. This rule allows you to move the background so it displays at certain positions in your element. Since each image in your sprite is at a specific location, when you want to display a particular image, you position the background so the top left corner of the image aligns with the top left corner of your HTML element. Then the width and height of your element need to match the width and height of the image you are displaying.

Let’s take the following image for a quick example. It has 5 stars in it, each with a slightly different color. Each star occupies exactly 19 pixels in width by 20 pixels in height. Using CSS classes, we can display a different color star in various places on our site, and we only have to download one image. Let’s take a look.

Stars Sprite Image

With CSS, we create a class labeled ‘star’ and assign the stars image you see above as the background image. We specify the width and height of a single star, and then we make classes for each star color. The different color CSS classes will need to reposition the background image so the appropriate star displays as it should.

.star {
	background-image:url(small_stars.png);
	width:19px;
	height:20px;
}
 
.star.lightblue {
	background-position:0px 0px;
}
 
.star.red {
	background-position:77px 0px;
}
 
.star.darkblue {
	background-position:57px 0px;
}
 
.star.green {
	background-position:38px 0px;
}
 
.star.yellow {
	background-position:19px 0px;
}

Now, we use the classes together in order to style a star with a specific color: <div class=”star green”></div> for instance, will give us a green star. This also demonstrates how CSS rules can be cascaded, or used together.

Light Blue Red Dark Blue Green Yellow

Navigation Tabs With Sprites

Since sprites can be used for various purposes, I’ve also chosen to demonstrate its usage with a more complex example: navigation tabs. Let’s pretend we are making an HTML navigation, and the designs need to have ‘tabs’ for each link, and each tab has rounded left and right corners. The first thing we need to do is create an image with our tab designs on them. We can call this image ‘navtop.png’. Tabs are a little tricky because the content on the tab may be long or short, so we need to account for this. We do this by making the tab image extremely long, so that no matter the text size, we don’t run out of image. Things become clear when you look at the sprite below. We also need to account for rollover and active states. When a user puts their mouse over a tab, we want the colors to change, and if the user clicks on a tab, when the next page loads, it should load the tab in an active-state. The active state should have different colors than the rollover and non-active states. The colors change because the images are being switched. To account for this, we will have all the images in the same sprite.

This technique is otherwise known as ‘sliding windows’, or ‘sprited sliding doors’.

First thing’s first, we need to create the sprite image. I’ve created mine, so hopefully after looking at it, you will understand how you need to create yours. For this exercise, it’s easy, just three really long tab images, one for the non-active state, one for the rollover-state, and one for the active state.

Navigation Tabs

Now we need to put it together. Let’s create our navigation with an unordered list. Make sure to give your UL a unique ID attribute, so we can refer to it when styling. If you want to use the same sprite for tabs in multiple areas on your site, you can use a class name instead of an ID attribute.

<ul id="topnav">
	<li><a href="link_one.html">Link One</a></li>
	<li><a href="link_two.html">Link Two</a></li>
	<li><a href="link_three.html">Link Three Has a Longer Name</a></li>
	<li><a href="link_four.html">Link Four</a></li>
</ul>

Next we need to style our navigation menu so that each LI item is next to the other, with some space in between them. We use a right or left margin to give them space, whichever fits best into your design. In order to get them to display on the same line and next to each other, we need to float each LI element ‘left’. We also need to give each LI a fixed height. This is the height of our tab images, but not the entire sprite, just one image. My tabs are 29 pixels tall. LI elements come pre-styled, each with a bullet point, so we’re going to have to strip those styles as well. Let’s take a look at the CSS code needed to accomplish this.

#topnav li {
	/* get rid of default styles */
	list-style-type:none;
	list-style-position:inside;
 
	/* float left so they line up next to each other */
	float:left;
 
	/* set a fixed height */
	height:29px;
 
	/* give each LI a right margin */
	margin-right:15px;
}

And so what used to look like this:

Ends up looking like this:

It’s always a good rule to start with * { margin:0; padding:0; } at the top of your css layout, that way you don’t have unexpected spacing. The browsers like to put their own margins and spacing on specific elements and it can throw you off when laying out a design. In this rule, * refers to every element, so you’re saying, every element has no margin and no padding. This way, you can assign margins and paddings wherever you need them.

It’s time to style the tabs. Tabs can be tricky to style because both corners need to show a rounded edge, and the content may be long or short, so the tab image that is displayed is not a fixed width. In order to make this work, we have to use the background image on two different tags. One tag will have the background image aligned to the left, so the left corners show, and the other will have its background image aligned to the right so that the right corners show. The tag with the text inside it should have the right positioned background, and it should be nested within the first tag. An example of this nested relationship can be found above, where we have an LI tag, with an anchor tag nested inside of it: <li><a href=”my_link.html”>My Link Text</a></li>. The LI tag will have it’s background positioned left, and the anchor will have its background positioned right. The anchor tags also need to be displayed as block-elements so that they contain the entire ‘body’ of their parents. The background image for both tags should be positioned at its top most position, since that is where our non-active state is positioned in the sprite.

My tabs look better with a black background, so I am going to nest them within a parent container. My parent container is just a DIV with background-color set to black. I also like to start my tabs a little from the left, so I’m going to give my parent container a left padding.

Now, because of our rounded corners, we need to give a little room for the design, so that the content doesn’t flow into the corners. For my corners, I will set aside 9px from the left of the tab, and 9px from the right of the tab. We can accomplish this using padding. Let’s look at the CSS:

/* here are the styles for our new container element */
#topnav_container {
	width:100%;
	height:29px;
	background-color:#000;
	padding-left:50px;
	padding-top:50px;
}
 
#topnav li {
	/* these are old rules explained above */
	list-style-type:none;
	list-style-position:inside;
 
	float:left;
 
	height:29px;
	margin-right:15px;
 
	/* here is our left padding, it goes on the LI */
	padding-left:9px;
 
	/* this is our new background rule */
	background:url(navtop.png) top left;
}
 
/* this is our new rule for anchor tags */
#topnav li a {
	/* disply as a block element */
	display:block;
 
	/* here is our right padding, it goes on the anchor */
	padding-right:9px;
 
	/* anchors need a fixed height, too, which is the height of the LI minus any top or bottom padding */
	height:29px;
 
	/* this is the background style for our anchors */
	background:url(navtop.png) top right;
}

And this is what we end up with:

As I’m sure you noticed, the link colors don’t blend nicely with our tab images, and the placement is way too high. In your document, you will also have to adjust the font-size, because unless previously set, the font size for your links will be the default font size. Mine are pre-styled with my theme, and so they look smaller on this step than they normally would. You will have to adjust the font-size and the top padding of your anchor tags. Just remember that when you adjust the top or bottom padding, you need to subtract those amounts from the height. I’m going to give my links a top padding of, 8px, which means I will make the height 21px instead of 29px. I’m also going to style my links so they are readable, which means I’ll give them a different color and I will strip away the underline.

#topnav li a {
	/* old rules, explained above */
	display:block;
 
	padding-right:9px;
 
	background:url(navtop.png) top right;
 
	/* new rules for positioning, font size and color */
	padding-top:8px;
	font-size:14px;
	color:#cfcfcf;
 
	/* get rid of the underline */
	text-decoration:none;
 
	/* because of our new top padding, the height changes */
	height:21px;
}

And this is the new result:

Now it’s time to incorporate the rollover and active states of our tabs. What we need to do is get the background image to re-position itself whenever the mouse goes over the LI. This is accomplished with the :hover and background-position CSS rules. The background-position rule lets you position your background in different ways. We are going to position our background image with pixels. The rule works like this, background-position:left-pixel-position top-pixel-position; If you specify 0px for both values, it targets the top left corner. If you give a value greater than 0px, it targets the oposite corner. The left pixel position is from right to left, 1px being the right most position in the image. The top pixel position goes from bottom to top, 1px being the bottom most position in the image. Since our tabs are 29px in height, if we say, background-position:0px 29px; we will be styling the last tab in the sprite, which happens to be our active-state. We need to add styles for our active state and our rollover-state. Remember, though, that our anchor tag background images are positioned to the right, and our LI background images to the left. Let’s take a look at the new CSS for these rules:

/* style the active state - the active's rollover state doesn't change, so use the same rule */
#topnav li.active , #topnav li.active:hover {
	background-position:0px 29px;
}
 
/* style for the active state's anchor tag - the rollover state doesn't change, so use the same rule */
#topnav li.active a , #topnav li.active:hover a {
	color:#000;
	background-position:right 29px;
}
 
/* when the mouse is over the LI, change it to the rollover-state */
#topnav li:hover {
	background-position:0px 58px;
}
 
/* when the mouse is over the LI, change the anchor's image to the rollover state and change the font color */
#topnav li:hover a {
	color:#FFF;
	background-position:right 58px;
}

And here is the final result. I’ve made one of my tabs active, so you can see what it looks like. To make it active, give the LI the class=”active” attribute.

View: Live Example

VN:F [1.9.22_1171]
Rating: 7.8/10 (53 votes cast)
VN:F [1.9.22_1171]
Rating: +7 (from 9 votes)

, ,

1 Comment

jQuery Autocomplete With MySQL And PHP

Making an auto-suggestion script, something that reads your input and shows related matches as you type, can be quite a challenge. It’s been made very popular by the big search engines. Yahoo did it first, and now Google has Instant which is killing its competitors. But how do you get one on your site? Luckily, jQuery has given us a very simple solution: http://jqueryui.com/demos/autocomplete/.

Let’s pretend you are making a website for a client who has multiple locations all throughout the United States. They ask you to build a form which takes a zipcode and spits out locations surrounding that zipcode. They also request, that, as the user types their zipcode, a suggestion box appears showing them relevant matches.

jQuery’s autocomplete makes this an easy task. The first thing you need to do, obviously, is create your form. Make sure you give your search box an id attribute, as it’s easier to work with that way.

<form action="search.php" method="post">
	Enter your zipcode:
	<input type="text" id="zipsearch" />
 
	<br />
	<input type="submit" value="Search" />
</form>

The second thing you need to do is tell jQuery to use its auto-complete User Interface (UI) on the search box you just made. When the auto-complete UI searches a database, you need to specify the website address for the PHP script that will be querying the database and returning results. Let’s call our script, ‘suggest_zip.php’ since it will be suggesting zip codes from partial searches. Also, to limit the amount of queries that are made, we can tell the auto-complete UI not to send anything to the server unless the user has typed at least ‘x’ amount of characters, or numbers in our case. Let’s limit ‘x’ to 2 numbers. We can stick this all in the ‘ready’ event, so it doesn’t fire until the document has loaded.

?View Code JAVASCRIPT
jQuery(document).ready(function($){
	$('#zipsearch').autocomplete({source:'suggest_zip.php', minLength:2});
});

And that’s it for the HTML and JavaScript side of things. Just make sure you are loading the required jQuery libraries to make this work. See the link for dependancies: http://jqueryui.com/demos/autocomplete/. You can download jQuery at the following locations: http://docs.jquery.com/Downloading_jQuery and http://jqueryui.com/download. Our script also uses jQuery’s ‘smoothness’ UI styles, which come bundled on their site. The UI styles style the results for us. You can make your own theme or use one of the pre-built themes jQuery has: http://jqueryui.com/themeroller/.

Now, let’s take a look at how we need to build our PHP script to work with the auto-complete UI that we just added to our form. First, we need to make a connection to the database. Since I use MySQL for my database, I’ll use mysql_connect and the mysql_* functions to make this script. After we have a valid connection to the database and the database we are using has been selected, mysql_select_db(), we can write our database query. Now, jQuery’s auto-complete expects two values to be returned along with each result: ‘value’ and ‘label’. Our script will be returning an array of data. Each item in that array needs to have ‘value’ and / or ‘label’. If ‘label’ is provided, jQuery shows your results using this, but when you select a result, it uses ‘value’ to populate your textbox. If ‘label’ is not provided, jQuery will use ‘value’ for both. So, our array in PHP looks like this: $data = array( array(‘label’=>’Item One’, ‘value’=>1) , array(‘label’=>’Item Two’, ‘value’=>2) ); If you need help with arrays in PHP, see the following webpage: http://php.net/array. When we return this data back to jQuery, we have to put it into a format that jQuery understands, which is JSON, aka. Javascript Object Notation. In order to turn an array of data from PHP into JSON, we use PHP’s built-in function json_encode. Use echo or print to transfer the data from PHP to jQuery: echo json_encode( $data ); If we take our array example above, what would be returned actually looks like this: [{“label”:”Item One”,”value”:1},{“label”:”Item Two”,”value”:2}], and that is JSON.

When jQuery sends the HTTP request to our suggest_zip.php script, it will send the text that’s being searched in the variable labeled, ‘term’. We can use $_REQUEST[‘term’] to access it. $_REQUEST allows us to access variables that were sent along with HTTP Requests, so if it was sent by an HTML Form Post, or over the URL: www.website.com?term=text, $_REQUEST will allow us to access it.

Let’s take a look at the PHP code inside of suggest_zip.php:

<?php
 
// if the 'term' variable is not sent with the request, exit
if ( !isset($_REQUEST['term']) )
	exit;
 
// connect to the database server and select the appropriate database for use
$dblink = mysql_connect('server', 'username', 'password') or die( mysql_error() );
mysql_select_db('database_name');
 
// query the database table for zip codes that match 'term'
$rs = mysql_query('select zip, city, state from zipcode where zip like "'. mysql_real_escape_string($_REQUEST['term']) .'%" order by zip asc limit 0,10', $dblink);
 
// loop through each zipcode returned and format the response for jQuery
$data = array();
if ( $rs && mysql_num_rows($rs) )
{
	while( $row = mysql_fetch_array($rs, MYSQL_ASSOC) )
	{
		$data[] = array(
			'label' => $row['zip'] .', '. $row['city'] .' '. $row['state'] ,
			'value' => $row['zip']
		);
	}
}
 
// jQuery wants JSON data
echo json_encode($data);
flush();

Here’s the SQL structure necessary for the zipcode table, written in MySQL:

create table zipcode
(
	id int not null primary key auto_increment ,
	zip varchar(20) not null ,
	city varchar(100) not null ,
	state varchar(5) not null 
);
create index idx_zipcode on zipcode ( zip(5) );

And that’s it. Now you have a form that will auto-suggest zipcodes as you type.

View: Live Example; suggest_zip.php

Download: ZIP Bundle – Grab this for a complete zipcode table and all the code bundled together.

Join us on DALNet for questions and discussion; irc.dal.net #php (requires IRC client)

Live Example

Grouped Results

As requested, here is an example demonstrating how to group the results in the autocomplete UI. Since this blog is rather old, I have chosen to demonstrate this using PDO instead of the deprecated mysql_* functions.

First, we need to create a custom autocomplete widget, so we can overload the method used to render the menu. When the UI renders the menu, it needs to read the current category, and if it’s not the same as the last category, it should print an LI with a special class on it, so the autocomplete knows it’s not a result. This assumes that the results are sorted by category, otherwise you will get the category listed multiple times.

?View Code JAVASCRIPT
$.widget('custom.groupedSearch', $.ui.autocomplete,
{
	_renderMenu: function(ul, items)
	{
		var currentCategory = "";
		$.each( items, $.proxy(function(index, item)
		{
			// evaluate the category and render an LI tag
			if (item.category != currentCategory)
			{
				ul.append("<li class='ui-autocomplete-category'>" + item.category + "</li>");
				currentCategory = item.category;
			}
 
			// render the item (this returns the LI DOMNode instance)
			var li = this._renderItem(ul, item);
		}, this));
	}
});
 
// initialize the custom autocomplete widget
$('.zipcode').groupedSearch({
	source : 'groupedZipcodeSearch.php' ,
	minLength : 2
});

The PHP just needs to order the mysql results by the category in question. In my example, the category consists of two fields, state taking precedence. Given a zipcode that starts with “123”, we could demonstrate this query as follows:

select zip, city, state
from zipcode
where zip like "123%" 
order by state asc, city asc, zip asc
limit 0,10

Next, include ‘category’ in the response array and javascript will be able to group it. This example groups the results by city and state, but the javascript will support any grouping, so long as its provided a ‘category’ key in the array returned from the suggestion script.

$data[] = array(
	'label' => 'Displayed Result' ,
	'value' => 'Chosen Result Value' ,
	'category' => 'Grouped Category'
);

View: Live Example; PHP Source

Live Example

Populating Related Fields

As requested, here is an example demonstrating how we might populate related form fields when an item is selected from the search results. This is actually a simple task. To demonstrate this, I’ll be populating the related City and State for the selected Zipcode.

The first step to this is structuring the query so it can fetch and return the desired fields with each row in the search results. It’s easy for my example because all of the data is stored in the same table.

select zip, city, state 
from zipcode 
where zip like '123%'
order by zip asc 
limit 0,10

The second step is formatting the data array before it gets JSON encoded. The related fields need to be included with each result.

$data[] = array(
	'value' => $row->zip ,
	'city' => $row->city ,
	'state' => $row->state
);

The third and final step is setting up the on-select handler for the jQuery Autocomplete UI. All we need to do is populate the related form fields from the data associated with the selected item.

My example is straight forward, all of the fields are in the same form, and I’m not modifying any HTML. You may have different logic in your on-select handler, but the idea is the same.

Please see http://api.jqueryui.com/autocomplete/#event-select for more information.

?View Code JAVASCRIPT
jQuery(document).ready(function(){
	$('.zipsearch').autocomplete({
		source:'jQueryAutocompleteRelatedFields.php', 
		minLength:2,
		select:function(evt, ui)
		{
			// when a zipcode is selected, populate related fields in this form
			this.form.city.value = ui.item.city;
			this.form.state.value = ui.item.state;
		}
	});
});

View: Live Example; PHP Source

Live Example

VN:F [1.9.22_1171]
Rating: 8.9/10 (325 votes cast)
VN:F [1.9.22_1171]
Rating: +52 (from 94 votes)

, , ,

105 Comments

Guess That Letter

Writing a guess-that-letter is almost exactly like writing Guess That Number, except instead of storing a numerical value, we store a character from A – Z. When the user guesses, we use the ascii value of the character to hint to the user, higher or lower.

?View Code JAVASCRIPT
var guess_ascii, guess_char, guess_tries = 0;
 
function RandomRange(low,high)
{
    return( Math.floor((high-low-1)*Math.random()) + low );
}
 
/* http://sharkysoft.com/tutorials/jsa/content/018.html */
function AsciiValue(c)
{
	// restrict input to a single character
	c = c.charAt (0);
 
	// loop through all possible ASCII values
	var i;
	for (i = 0; i < 256; ++ i)
	{
		// convert i into a 2-digit hex string
		var h = i . toString (16);
		if (h . length == 1)
			h = "0" + h;
 
		// insert a % character into the string
		h = "%" + h;
 
		// determine the character represented by the escape code
		h = unescape (h);
 
		// if the characters match, we've found the ASCII value
		if (h == c)
			break;
	}
	return i;
}
 
/**
* @desc Think of a number from 1 to x
* @param number range to guess within
**/
function GuessChar( num )
{
	guess_tries = 0;
	guess_range = num;
	guess_ascii = RandomRange(97,122);				// a is ascii char 97, z is ascii char 122
	guess_char = String.fromCharCode( guess_ascii );
}
 
function Guess( frm )
{
	var g = frm.guess1.value.toLowerCase();				// we are dealing with a-z not A-Z
	var ascii = AsciiValue(g);
 
	if ( ascii < 97 || ascii > 122 )
	{
		alert("Please insert a letter from A - Z.");
		return;
	}
 
	guess_tries += 1;
	status = "Tries: "+ guess_tries;
 
	if ( g == guess_char )
	{
		if ( guess_tries == 1 )
			alert("Correct!  You guessed it in 1 try!  Wow, good job!!");
		else
			alert("Correct!  You guessed it in "+ guess_tries +" tries!");
 
		GuessOver();
	} else if ( guess_tries >= 10 ) {
 
		alert("Sorry, time's up. The letter was: "+ guess_char);
		GuessOver();
	} else if ( ascii < guess_ascii )
		frm.hint.value = "No, guess higher.";
	else if ( ascii > guess_ascii )
 
		frm.hint.value = "No, guess lower.";
}
 
/**
* @desc Prompt to start the guessing game over
**/
function GuessOver()
{
	if ( !confirm('Would you like to play again?') )
	{
		alert("Thanks for playing!  :)");
		location.reload();
	} else {
		GuessChar();
		document.forms.form1.hint.value = "Enter your Guess.";
	}
}
 
// initialize the guessing game
GuessChar();

View: Open Source Copy


Guess That Letter

I'm thinking of a letter between A and Z. Try to guess it in less than 10 tries.



Guess:


VN:F [1.9.22_1171]
Rating: 6.8/10 (6 votes cast)
VN:F [1.9.22_1171]
Rating: +1 (from 1 vote)

,

2 Comments

Guess That Number

Writing a guess-that-number script in javascript is notorious in low-level javascript classes. I can’t tell you how many times someone has approached me on IRC asking about, “how to make a guess that number script?”. Since I wrote it so many times, I figured I would post it here for the world to access.

Isn’t sharing fun?

?View Code JAVASCRIPT
var guess_num = 0, guess_range, guess_tries = 0;
 
/**
* @desc Think of a number from 1 to x
* @param number range to guess within
**/
function GuessNum( num )
{
	if ( isNaN(num) )
		throw "Invalid Number Provided For GuessNum()";
 
	guess_tries = 0;
	guess_range = num;
	guess_num = Math.floor(Math.random() * num) + 1;
}
 
function Guess( frm )
{
	var g = parseInt(frm.guess1.value);
 
	if ( isNaN(g) )
	{
		alert("Please insert a numerical value.");
		return;
	} else if ( g < 1 || g > guess_range ) {
		alert("You must select a number between 1 and "+ guess_range);
		return;
	}
 
	guess_tries += 1;
	status = "Tries: "+ guess_tries;
 
	if ( g == guess_num )
	{
		if ( guess_tries == 1 )
			alert("Correct!  You guessed it in 1 try!  Wow, good job!!");
		else
			alert("Correct!  You guessed it in "+ guess_tries +" tries!");
 
		GuessOver();
	} else if ( guess_tries >= 10 ) {
 
		alert("Sorry, time's up. The number was: "+ guess_num);
		GuessOver();
	} else if ( g < guess_num )
		frm.hint.value = "No, guess higher.";
	else if ( g > guess_num )
 
		frm.hint.value = "No, guess lower.";
}
 
/**
* @desc Prompt to start the guessing game over
**/
function GuessOver()
{
	if ( !confirm('Would you like to play again?') )
	{
		alert("Thanks for playing!  :)");
		location.reload();
	} else {
		GuessNum( 100 );
		document.forms.form1.hint.value = "Enter your Guess.";
	}
}
 
// initialize the guessing game
GuessNum( 100 );

View: Open Source Copy


Guess That Number

I'm thinking of a number between 1 and 100. Try to guess it in less than 10 tries.



Guess:


VN:F [1.9.22_1171]
Rating: 7.3/10 (3 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

,

No Comments

Welcome To HTML Blog

Hello and welcome to HTML Blog.  This blog is here for others to reference when in need, but its sole purpose drives to encourage me in my constant effort towards growth.  Please drop a comment and let me know if you like my work.

Check back soon for posts…

Check our sister site, http://www.phpprofessional.us for information on PHP.

VN:F [1.9.22_1171]
Rating: 10.0/10 (3 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

No Comments