Category Archives: HTML

Multiple JPlayers on the same page

JPlayer is a very nice Javascript library that allows you to create HTML5 media players in your HTML pages.

http://www.jplayer.org/

The site creates pretty decent documentation and examples, but I recently came to a dead halt when I had to create multiple audio players on the same page.

The JPlayer site provides an example of this, but it isn’t exactly clear how it works. This post explains exactly what you have to do.

First thing to understand:

In HTML5, when you want to create a media player, you either use the default interface or create a custom interface. If you want to create a custom interface, you have to create separate HTML for the interface. The default JPlayer installation includes a custom interface, so if you want to create multiple players, you have to create multiple interfaces, each of which must be carefully constructed from the point of view of the DOM and CSS.

Each of your interfaces will have a DOM Element ID, which of course must be unique. That ID determines which players activates when a control in that interface is clicked (play, stop, pause etc). If you don’t have this correctly set up, either multiple players will start at once, or nothing will happen at all.

If you only create one player on a page, the default Interface Element ID that JPlayer looks for is “#jp_interface_1″.

If you want to create multiple players, you need to tell each JPlayer instance which interface it is associated with.

To do this, you specify the cssSelectorAncestor property for each player instance you create:

eg

function js_audioPlayer(file,location) {
	jQuery("#jquery_jplayer_" + location).jPlayer( {
	    ready: function () {
	      jQuery(this).jPlayer("setMedia", {
		mp3: file
	      });
	    },
	    cssSelectorAncestor: "#jp_interface_" + location,
	    swfPath: "/swf"
	  });
return;
}

In this example, I’m passing a file and location variable into a wrapper function, which then constructs the player.

In my script, I dynamically create Player DIVs with IDs:

jquery_jplayer_1
jquery_jplayer_2
jquery_jplayer_3
etc

and Interface DIVs with IDs:

jp_interface_1
jp_interface_2
jp_interface_3
etc

and then run the js_audioPlayer() javascript function as many times as I want players:

js_audioPlayer(‘file1.mp3′,1);
js_audioPlayer(‘file2.mp3′,2);
js_audioPlayer(‘file3.mp3′,3);
etc

More: http://www.jplayer.org/latest/developer-guide/#jPlayer-predefined-css-selectors

Copying an entire website with Httrack

As a web developer, you often get asked to update and upgrade existing websites, and to fix issue with existing websites.

More often than not, its easier to do this on a local copy of the website than on a live remote server.

There are various ways to copy an entire website, but sometimes when a site isn’t very well designed (eg with absolute rather than relative links) this can take quite a bit of sorting out.

This is where a tool called Httrack comes in every handy. It’ll download the website for you over http (so you don’t even need ftp login details) and convert all links to relative links.

Its available for both Windows and Linux, and is in the repositories for Ubuntu.

Google Maps and Dynamic IFRAMEs

I recently created an application that displayed a Google Map in an IFRAME in the main page.

The IFRAME itself was created by running a small piece of javascript to populate innerHTML in a specific DIV container.

For some reason, several of the tiles were missing from the page when it first rendered.

After tricking around with this for ages, I eventually came up a solution.

When you insert a Google Map in a page, either in a standard page or in an IFRAME, the map will display according to the geometry of the page. For standard page, the geometry is straightforward, and you generally won’t encounter any problems.

In a page containing an IFRAME things are a little different, particularly when you create the IFRAME on the fly.

Consider this:

A page starts to render. Its a long page, and half way down, some javascript runs to create an IFRAME. This IFRAME then goes off and pulls down a Google Map, but this process starts before the parent page is fully rendered.

Result: Google Map is wonky.

So what’s the solution?

Basically, you just need to insert a little delay into your Javascript to allow the parent page fully render before the Google Map create begins:

eg

setTimeout(js_viewGoogleMap,1000);

If you need to pass co-ords to your map rendering function, just
create an inner function in your primary function:

eg

function js_viewGoogleMap(x,y) {

function loadMap() {

load(x,y);

}

setTimeout(loadMap,1000);

}

Hope this helps.

Multidimensional arrays in form data

Readers are probably aware that you can pass an array to a script from a HTML form.

For instance, if you want to pass multiple checkbox items, or data from a SELECT where the user can select more than one option:

<INPUT TYPE=checkbox VALUE=1 NAME=myData[]>
<INPUT TYPE=checkbox VALUE=2 NAME=myData[]>
<INPUT TYPE=checkbox VALUE=3 NAME=myData[]>

or

<SELECT NAME=myData[] MULTIPLE>

will appear in the PHP Superglobal $_GET/$_POST arrays as an array:

$_GET['myData'] or $_POST['myData']

What users may not know is that you can also pass a multi-dimensional array from a form. This is particularly handy if your form is dynamically created with a variable input names.

For instance, if you want to create a checkbox that a user can tick and then add data that is associated with that checkbox.

Say you have a property website, and you allow a seller to specify that a property is close to the airport (checkbox) and then allow the seller to specify the distance in km and miles from the airport using 2 SELECTs.

Your checkbox would form the first layer of the array:

<INPUT TYPE=checkbox VALUE=1 NAME=myData[x]>

Where x = discreet data that refers to a property being ‘close to an airport’.

Your 2 SELECTS would then be:

<SELECT NAME=myData[x][0]>
<SELECT NAME=myData[x][1]>

This will place the multi-dimensional array $myData in either $_GET or $_POST, which you can use like any other multi-dimensional array.

IE 6 and 7 Imagemap crash issue

Imagemaps are a bit old hat these days, but they still have their uses and this IE bug can be a real killer.

If you dynamically create an Imagemap using Javascript, IE has a problem with polygon areas that have different number of co-ordinates. Basically, IE will crash if you click on an area that has fewer co-ordinates than a previous area.

To get around this, don’t use DOM element properties to create your Imagemap:

Don’t use:

map_image.isMap = ‘ismap’;
map_image.useMap = ‘#layer0′;

etc

Put your IMG tag inside a SPAN instead, and update it using the innerHTML property.

Firefox, Imagemaps and Float DIVs

Here is some curious Firefox behaviour I’ve recently discovered. It took me several hours to figure out what was happening.

If you place an imagemap inside a DIV in Firefox, it works fine.

However, if you then float that DIV, Firefox moves the image with the DIV, but leaves behind the imagemap where the DIV would have been had it not been floated.

IE doesn’t repeat this behaviour. It moves the imagemap with the image. I’m not sure which is the standardised behaviour, but if you want to place imagemaps in columns on a page, and you want this to work in Firefox, you have to use tables. DIVs won’t cut it.

What form am I?

Its nice to have a single piece of Javascript that you can use on all the forms you have in an application, but it can be difficult between browsers to get your Javascript to recognise what form it has been called from.

Here’s a simple solution.

Give your form a numeric ID. That way, you can pass the ID to a function that can then do whatever it is you need to do with the form.

For example:

<FORM ID=100 NAME=registration_form ACTION=index.php METHOD=get>

<INPUT TYPE=text NAME=user_name>

<INPUT TYPE=button VALUE=submit_button onClick=’submitMe(100);’>

</FORM>

Your submitMe() function then looks like this:

function submitMe(formID) {

document.getElementById(formID).submit;

}

And if you have more than 1 form in a page, you can use different numeric IDs for each form: 100,101,102 etc

Finally, you can of course give your form a contextual name as well as an numeric ID (eg. “registration_form”) so that you can also access the form components and values through the DOM, ie:

var userName = document.registration_form.user_name.value;

Sweet.