Variables in Javascript Nested Functions

March 19th, 2009

Like many programming/scripting languages, Javscript provides the ability to nest one function inside another function, a bit like this:

function outside () {

function inside() {

window.alert(’Hello World’);

}

}

This behaviour is most commonly seen when a developer needs to assign a function to an event that is created inside another function, for instance:

function outside () {

var menu =document.createElement(’SELECT’);

menu.onchange = function () {

window.alert(’Hello World’);

}

}

One of the difficulties that can arise here is that quite often it is necessary to pass a variable to the inner function. Say for instance, you want to create a 3 SELECTs, each having an onChange event which displays an alert unique to that SELECT. Would this work?

function outside () {

for (i=1;i<4;i++) {

var menu =document.createElement(’SELECT’);

menu.id = i;

menu.onchange = function (i) {

window.alert(’Menu’ + document.getElementById(i).id);

}

}

}

The simple answer is that no, it won’t.

What this execution will do is run the inner function at the same time as the outer function and assign the return value of the inner function to the ‘onchange’ property of the SELECT object, even if nothing is returned.

This isn’t what we want. What we want is for the inner function to be assigned to the onChange event of the SELECT.

There are couple of ways to do this, 3 of which are very well explained in this article.

Here’s one of them. What we do in this case is create a new property for the SELECT object, to which we assign the necessary variables, which we can then reference with the this object reference.

function outside () {

for (i=1;i<4;i++) {

var menu =document.createElement(’SELECT’);

menu.menuid = i;

menu.onchange = function () {

window.alert(’Menu’ + this.menuid);

}

}

}

This method isn’t without its problems either, but it will work in the majority of cases. If you want the Gold Standard solution, check out the referenced article above, preferably from a quiet, well-aired room with a nice view of distant snow-capped mountains (ie its a little complicated…)

Thoughts on Wordpress

March 12th, 2009

Let’s be clear, Wordpress is great software. Its easy to install, its easy to use and it serves its purpose, blogging, very well.

However, the extent to which Wordpress is now being used to replace actual web development is getting ridiculous.

This really struck home to me recently when I saw an online shop based on Wordpress. It had a cart, a search function, a user database, the whole nine yards. I mean, come on, if you’re serious about selling stuff on the Internet, why on earth would you use blogging software as your shopping engine!!

A whole cottage industry also appears to have sprung up whereby so called Web Design companies and hacking free Wordpress templates and selling them on as bespoke brochure websites to unsuspecting customers.

This is pretty sharp practice. Wordpress templates are made available free by their designers to facilitate non-commercial use. Its never going to be possible to restrict their usage, but netiquette should dictate that these templates aren’t resold as bespoke designs.

Ultimately, growing user awareness will sort this out, which is always the Great Leveller on the Internet. At some stage, people are going to stop handing over good money to pay for something they can get for free on any number of community blogging sites.

And in the final analysis, bepsoke web development has never actually been easier. The availability of wonderful Javascript tools like the TinyMCE has brought CMS development well within the reach of even novice developers, so there should be no need to clutter up the web space with obsolete blogging functionality.

There it is then.

Wordpress for blogging, and that’s it.

Ubuntu 8 rocks!

February 12th, 2009

I recently (and belatedly) upgraded my laptop from Ubuntu 6 to Ubuntu 8.

I hadn’t really been very diligent in taking the OS updates as they became available, so I decided the safest way to go about it was to backup all my data and re-format my partitions with a fresh installation.

This all went really smoothly, and I was off and running with Ubuntu 8 within an hour or so.

It really is a great Operating System, and at this stage, can easily rival Windows XP or Vista in terms of ease of use.

I am particularly impressed with the improvements that have been made re. Wireless Networking. With Ubuntu 6, hooking up to the Wireless Network took a little bit more mouse work than I was comfortably with, whereas now the whole thing happens in the background.

My new OS also detected the 3G modem in my mobile phone, and established a working connection for me within 30 seconds. It even knew what Irish mobile network I was connected to.

A big issue with my old OS was that it wasn’t able to detect my battery status other than at boot time. I know know exactly how much power my battery has, and I have other readily accessible tools that allow me to easily reduce battery usage on the fly.

Added to this I have all the latest versions of my favourite apps like OpenOffice, GIMP, Firefox, Thunderbird, Gedit etc and I really am pleased I eventually got around to this.

Ubuntu will be getting a hefty donation from NBF this year.

The Scriptalizer

November 6th, 2008

Given the extended use of Javascript in today’s web applications, one of the best ways to improve site performance is to obfuscate your javascript before it is loaded into the browser.

Trimming white space and new lines can shave as much as 50% from your script file sizes, which can make as significant difference to the initial load delay of your site.

http://www.scriptalizer.com is as good a solution as I have found for this.

You upload your files, hit the button, and wham, all your beautifully formed javascript is compressed into a congealed, but wonderfully efficient, blob in a single file.

Only thing is that you have to insert a bit of logic into your code to load your human readable files in development and the single obfuscated file in Production, because you don’t wanted to have to repeat the obfuscation process every time you want to test a new piece of code, and you certainly don’t want to try and edit the obfuscated file by hand.

PLESK, vhost.conf and vhost_ssl.conf

September 25th, 2008

I recently had cause to run 2 websites under different domains from the same code base. I wanted to do this using my PLESK server, and provide for SSL connectivity to both domains.

I set up the 2 domains under PLESK as normal. To get the 2nd domain to run from the codebase for the first domain, I created a vhost.conf in the conf dir for the 2nd domain. This sets the DocumentRoot of the 2nd domain to the DocumentRoot of the 1st domain, and adds the home directory of the 1st domain to the open_basedir directive for the 2nd domain.

ie

the 2nd domain nows picks up its code from the home directory of the 1st domain, and the 2nd domain is now allowed refer to and write to the home directory of the 1st domain.

Next bit was the Digital Certs.

I installed these as normal under PLESK, then set up SSL support for both domains, and specified that both domains should use single directory for both SSL and non-SSL content.

This adds 2 Virtualhost directives to the http.include file (the one you should never edit) for both domains.

Now, to get the 2nd domain to refer to the code base of the 1st domain for SSL content, I copy my vhost.conf file to vhost_ssl.conf, and run

/usr/local/psa/admin/bin/websrvmng -a

This causes an Include statement to be written in both Virtualhost directives in the relevant the http.include file for the 2nd domain, allowing the vhost.conf and vhost_ssl.conf files to be read so that the 2nd domain uses the code base from the first domain for both SSL and non-SSL content.

The result?

https://www.textatrack.co.uk/

and

https://www.downloadmusic.ie

Same code base, but different domains and certs. Neat.

AJAX Character Encoding in Internet Explorer

July 16th, 2008

Is there no end to the woes of IE?

I’ve just spent 3 hours trying to find out why IE 7 won’t encode my form inputs in UTF-8 before sending them off in an XMLHttpRequest package to my server.

Here’s what is supposed to happen:

I send the page to the browser with UTF-8 character encoding, so the browser is supposed to use this encoding in whatever it does.

This is fine when sending form inputs back to the server with a straight-forward FORM Action routine, but when you use XMLHttpRequest in IE7, IE7 insists on sending the form input in ISO-8859-1.

So if someone enters Ø in one of my form inputs, IE7 sends this off to the server as ‘\xd8′ rather than as ‘%C3%98′ as it should.

The result is that garbage goes into my DB which then invalidates any XML that uses that garbage.

Thankfully, I found a solution.

When I take the form input value from my DOM, I pass it through the Javascript encodeURIComponent function before passing it to the XMLHttpRequest object.

var new_value = document.getElementById(”text_input”).value;
//CONVERT FORM INPUT TO UTF-8 FOR IE 7
new_value = encodeURIComponent(new_value);

XMLHttpRequest is supposed to use UTF-8 by default. There may be something wrong with my set up, but for the life of me I couldn’t get it to use UTF-8 (I’ve checked all my HTTP headers and everything is UTF-8; my server also uses UTF-8 by default, and everything works fine in FF) so this was the only solution that worked.

Another day lost to IE7.

Grrrrr.

Dynamic creation of Flash content

March 13th, 2008

Here’s a subject that gets a lot of press in the web development world.

Given the popularity of music and movies on the web, developers need to be able to deliver dynamically created and configured players as a matter of course.

There are a couple of challenges in this. For instance, creating DOM Objects with Javascript isn’t too hard, but creating DOM Embeds is a real nightmare, not least because IE won’t let you append an Embed to any other element, and because IE likes you to re-initialise these objects when you update their parameters.

Then you have the Eolas v. Microsoft issue, which is why you have to click twice on Flash objects in IE before they work.

Finally, you have to deal with all the various browser plugins that attempt to act on media content before any of their competitors, which makes them get up to all sorts of crazy behaviour.

From what I’ve seen, developers approach the dynamic Flash conundrum in one of two ways: they either try and accomplish everything with very long, hopelessly complex innerHTML strings, or they use the SWFObject Javascript library kindly provided by Geoff Stearns who is a Flash engineer with Youtube.

http://blog.deconcept.com/swfobject/

Having tried both myself, I would have to say that SWFObject is the only way to fly.

Its simple to use, its free, its stable in pretty much every browser and it starts Flash objects with a single click in IE, which is really sweet.

You can see it in action on the homepage of www.downloadmusic.ie.

All of the music buttons in the chart are created with SWFObject, but better still, the music buttons in the BATTLE BOX are dynamically created with AJAX and SWFObject. Creating Flash objects with AJAX is all but impossible without SWFObject.

Use it and spend more time with your kids (and thanks to Geoff).

Multidimensional arrays in form data

February 19th, 2008

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

December 21st, 2007

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

December 9th, 2007

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.