jQuery Select - call function on add/remove option

Thursday, 16 April 2009

View Comments

This post is in response to a request by Dave in the comments section of my jQuery select cheat sheet post

Dave asked:
How do you bind an event that calls a function whenever a new 'option' tag is added to the 'select' tag?

The answer is kind of long so I thought it would be best to put it in a post so that everyone can read it.

In the 1.3 release of jQuery they have released a new function live. Unfortunately unlike the plug-in it is based on liveQuery it does not support the no-event style callback that liveQuery provides, which means we will need to use the plug-in. Hopefully this will become available in the future (although full credit should be given to Brandon Aaron for his awesome plug-in). Be sure to check out the documentation for more about the no-event callbacks.

Here is a link to the demo that shows how we can achieve a function call on both adding and removing an option to a select element.

You can view source on the HTML, but I'll show you the javascript as that's where the magic is.

It's a very simple demo, but it achieves it's purpose. You should be able to customize this and get it do to whatever you need.

$(document).ready(function(event) {
$("#myselect").data("size", $("#myselect option").size());

$("#myselect option").livequery(function() {
if ($("#myselect option").size() > $("#myselect").data("size")) {
alert('option added');
$("#myselect").data("size", $("#myselect option").size());
}, function() {
if ($("#myselect option").size() < $("#myselect").data("size")) {
alert('option removed');
$("#myselect").data("size", $("#myselect option").size());

$("#addoption").click(function() {

$("#removeoption").click(function() {


function addanoption() {
$("#myselect").append("<option value='1'>Apples</option>");

function removeanoption() {
$("#myselect option:last").remove();

We start of with a call to the jQuery data function which saves the current size of our select element for later reference.

We then use the liveQuery function to match any option that is added to our select element and the extra function call is used whenever the same option is unloaded from the select element. So the first half checks if the current size is greater than the original size (this is needed otherwise the function would be called at document.ready when it matches any initial elements), this is so we know that an addition has been made and then we call whatever function we would like. Similarly when an option is removed we confirm that the size of the select has been reduced (maybe this step is unnecessary, I'll leave to you to decide) and then it calls whatever function you would like for the remove.


7 days of php add-ons - Day 6: PHPMailer

Welcome to day six of 7 days of php add-ons.

Today we'll be looking at PHPMailer

After you have been coding for a while it is a good idea to pick up on the things that you do over and over again in your work. With these tasks it is a good idea to find a good implementation of the same task and keep it handy. This will save you from reinventing the wheel and if you know something works and can be reused it will also save you time with testing. One of these tasks that you will do over and over again is sending mail. It is a good idea to have a mailer class that will take the hassle out of sending emails and can be used in different situations e.g. sending attachments etc.

PHPMailer is still in active development and is a clean robust implementation. It is easy to use and does everything it claims to do.

A new version was just released a couple of weeks ago and includes a whole new collection of easy to follow examples that can be seen here. Including an example of how to send SMTP via a MySQL database and sending mail through Gmail.

Here is a simple example:


$mail = new PHPMailer(); // defaults to using php "mail()"

$body = file_get_contents('contents.html');
$body = eregi_replace("[]",'',$body);

$mail->AddReplyTo("name@yourdomain.com","First Last");

$mail->SetFrom('name@yourdomain.com', 'First Last');

$mail->AddReplyTo("name@yourdomain.com","First Last");

$address = "whoto@otherdomain.com";
$mail->AddAddress($address, "John Doe");

$mail->Subject = "PHPMailer Test Subject via mail(), basic";

$mail->AltBody = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test


$mail->AddAttachment("images/phpmailer.gif"); // attachment
$mail->AddAttachment("images/phpmailer_mini.gif"); // attachment

if(!$mail->Send()) {
echo "Mailer Error: " . $mail->ErrorInfo;
} else {
echo "Message sent!";

Once you get it up and running you can stick it inside a function that can handle multiple recipients or attachments, for example:

function sendemail($body, $subject, $recipients = '', $altbody = '', $attachments = '') {

$mail = new PHPMailer();

$body = eregi_replace("[]",'',$body);

$mail->IsSMTP(); // telling the class to use SMTP
$mail->Host = "TESTSRV01"; // SMTP server

$mail->From = "info@yourdomain.com";
$mail->FromName = "My system";

$mail->Subject = $subject;

$mail->AltBody = $altbody;


$mail->AddAddress("admin@yourdomain.com", "Tim Radnidge");

if ($recipients) {
foreach ($recipients as $recipient) {
$mail->AddAddress($recipient['address'], $recipient['name']);

if ($attachments) {
foreach ($attachments as $attachment) {

if(!$mail->Send()) {
echo "Mailer Error: " . $mail->ErrorInfo;
} else {
return true;

7 days of php add-ons - Day 5: Flowplayer

Sunday, 12 April 2009

View Comments

Hi, for day 5 in our series I want to show you Flowplayer, an open source flash based video player that is available under the GPL license and can also be used in commercial projects.

To get yourself a copy of Flowplayer head to their site here.

I also wanted to point out that I am not receiving any benefit for the add-ons I am mentioning in 7 days of php. I have chosen these based upon my own personal use and the quality and benefit these add-ons have provided me in my own work.

The great thing about Flowplayer is that for the free version it is almost identical to the commercial version. The main difference is the branding, but this is not very prominent and if you wanted to remove it the commercial license is very reasonably priced and you can have your own logo display in the player.

The main reason I chose to discuss Flowplayer is because the free version is a superior quality product and is so simple to install and use.

For a variety of demos you can head to their demo page here. This page includes many different tutorials on getting Flowplayer to run in different contexts commercial, scripting, skinning etc.

To checkout a basic demo head to here

Screen shot of Flowplayer showing branding before video starts.

To get Flowplayer working in the simple possible configuration there are three easy steps.

Include the Flowplayer javascript in your page:

<script src="path/to/flowplayer-3.0.6.min.js"></script>

Set up the place holder for where your video will be played:


Then a call to the flowplayer function to get your player up and running:

<script language="JavaScript">
flowplayer("player", "path/to/flowplayer-3.0.7.swf");

It's as easy as that. Flashplayer plays videos in many different formats and can also handle streaming. Check out their site for more details.

7 days of php add-ons - Day 4: image resizer

Saturday, 11 April 2009

View Comments

Hi, for day four of 7 days of php add-ons I will be loooking at an excellent image resizing script.

Having an easy to use image resizing script is a fantastic tool to have especially when you have a site that uses a CMS, if you have a catalogue of items or if you have an inventory system.

The idea is that you allow your users or administrators to upload an image of any dimension or size (although you would want to put restrictions on the file size) and the you can pass the location of the file through this script and it will allow you to resize the image to a certain size and maintain the aspect ratio of the image.

This script also allows you to crop your image to a certain size square while maintaing the aspect ratio.

In basic terms maintaing the aspect ratio means resizing your image but not having it strecth or blur because of the new dimension. So if it needs to be shrunk or made larger it will still maintain the width to height ratio of the original image.

The image resizing script I've chosen is from Joe Lencioni over at Shifting Pixel. You can download the script and read his post about it here.

After downloading it's easy as pie to set up. All you need to do is create an imagecache folder in the same directory as the resizer script and give it the correct permissions.

Then to resize an image it's as easy as calling the script in the img src. Like this:

<img src="/image.php/coffee-bean.jpg?width=200&amp;height=200&amp;image=/wp-content/uploads/2008/03/coffee-bean.jpg" alt="Coffee Bean" />

And to resize and crop, you pass in the cropratio variable:

<img src="/image.php/coffee-bean.jpg?width=150&amp;height=150&amp;cropratio=1:1&amp;image=/wp-content/uploads/2008/03/coffee-bean.jpg" alt="Coffee Bean" />

The first part of the src attribute is the location of the php script followed by the name. The part image= is the absolute path to the image.

Here are the other paramters that can be passed in:

// Parameters need to be passed in through the URL's query string:
// image absolute path of local image starting with "/" (e.g. /images/toast.jpg)
// width maximum width of final image in pixels (e.g. 700)
// height maximum height of final image in pixels (e.g. 700)
// color (optional) background hex color for filling transparent PNGs (e.g. 900 or 16a942)
// cropratio (optional) ratio of width to height to crop final image (e.g. 1:1 or 3:2)
// nocache (optional) does not read image from the cache
// quality (optional, 0-100, default: 90) quality of output image

This script is released under the Creative Commons Attribution-Share Alike 3.0 United States license. Please refer to the license section of the blog entry for further details about giving credit to the author.

7 days of php add-ons - Day 3: flot

Friday, 10 April 2009

View Comments

I've got a great looking library to show you today as part three of our 7 days of php add-ons.

Today we are going to look at flot. Flot is a pure Javascript plotting library for jQuery.

This is a very nice looking piece of work. It is light and looks just as good as any other flash implementation you can find out there. Some of our apps have dashboards and these load up several small swf files. The problem is that when you start loading more than a couple of flash files on the one page this can become cumbersome and can slow a system down. Because it is using a very lightweight library flot is a great alternative and can reduce the sluggishness that is sometimes associated with loading a large number of swf files. Flot even icludes interactive options such as zooming and mouse tracking and even works with IE 6/7/8, WOW!

Have a look here at some examples. You can see the attention that has been put into producing a good looking quality product. The examples also include tooltips and zooming.

As with yesterday, I'm not going to go into too much detail with examples as the API and examples are downloadable as part of the package. Also to note, although the last release was in September last year, the author still actively replies to questions in the flot Google group.

Enjoy flot!

Thursday, 9 April 2009

View Comments


7 days of php add-ons - Day 2: TCPDF

Welcome to day two of my 7 days of php add-ons, a collection of applications and classes that I hope will broaden your skill set and provide you with some useful tools for tackling some common issues with building web apps using php.
Today I'm going to go over generating pdf documents on the fly using php. The class I've chosen is TCPDF . There are many classes out there that can assist with generating pdf documents including Zend Pdf as part of the Zend framework. The reason I chose TCPDF is because it is still currently being developed, it is well documented, easy to implement and it has many examples provided with the class that you can use as a point of reference.

With the number of different browsers on the market we have a problem when we want to create something that will be rendered exactly the same when viewed and printed. According to Adobe: "The goal of these products is to enable users to exchange and view electronic documents easily and reliably, independently of the environment in which they were created. PDF relies on the same imaging model as the PostScript® page description language to describe text and graphics in a device-independent and resolution-independent manner". What this means for us is we can generate a document that should come out the same regardless of what we use to view and print the document.

On top of this, having our document generated in pdf format means we don't have the hassle of trying to disable or hide the header and footer that every browser sticks on a page when it is printed. If you've ever tried to remove this only for a particular page you will understand how much of a nightmare this can be. If you remove it manually for a particular page it has to be placed back in once it is printed. There are solutions to this out there, but none of them seem to work accross all browsers.

TCPDF currently has a writeHTML function that allows you to use HTML code to specify the layout of your page. Although you need to be careful how you use <p> and <br /> tags for spacing as there is no support for line-height. Besides a limited support for css it's still possible to achieve almost any layout. TCPDF also requires no external libraries and comes with a bunch of free fonts.

I don't want to go into too much detail here with examples as the download provides almost 50 useful examples and it is very easy to use. Here is a basic hello world example using the writeHTML function to give you an idea:





$pdf->SetFont('helvetica', '', 10);


$htmlcontent = "<p>Hello world</p>";

$pdf->writeHTML($htmlcontent, true, 0, true, 0);


It's as easy as that. Check out their home page for all of the main features and access to the docs.

7 days of php add-ons - Day 1: minify

Wednesday, 8 April 2009

View Comments

Welcome to the first of my 7 days of php add-ons.

I've chosen to start things off with minify.

From their own site:

Minify is a PHP5 app that can combine multiple CSS or Javascript files, compress their contents (i.e. removal of unnecessary whitespace/comments), and serve the results with HTTP encoding (gzip/deflate) and headers that allow optimal client-side caching. This helps you follow several of Yahoo!'s Rules for High Performance Web Sites.

The main aim with minifying your css and javascript files is to increase the speed of your site; something that you may not be considering when you are writing your first php scripts. But one of the reasons that I chose this app to demonstrate is that is a very useful tool to have available and something that you will need to use once you start working on larger volume sites.

One of the advantages of using the minify script is having the minified files cached server side. In some browsers this can cause problems when you have web applications that have a high number of regular users; the problem occurs when you update one of your javascript files it may not automatically refresh. The solution in this case is to do a Ctrl-F5 hard refresh, but you can't expect all of your users to do this each time you do a release. I'll show you how you can set up versioning with your minified files so that your server knows there is a new version of your minified file available, problem solved!

Note: On certain high volume sites minify can be slower that serving flat files, so please make sure before deploying this to a live environment you do your own benchmarking tests.

Minify can be downloaded from here. I recommend having a good read through the Wiki before implementing on your site, it has a good FAQ section and a list of common problems others have had while implementing.

Minify has changed slightly with recent releases and they have a walkthrough, if you are happy to place the minfy folder at root level. This will allow you to add each of the files one by one and will then provide you with the necessary URLs to use. I had troubles getting this to work if I placed the minify folder elsewhere other than at the root level. I also prefer setting up the groups manually and being able to use my own URLs, in this way we are able to have versioning.

The main idea to get versioning running is to have the current version number of your app stored in a variable or constant. In this way you only need to specify your app version once. I have stored this in a file called global.php. Anywhere that I want to include my minified css or js files I just call the URL of my minified script and pass in the group name followed by the version.

Here's how it works:

Minify script file name: test-min.php
Version: 5.4b
Group: js

So to include the minified version of my js groups I just called http://www.mysite.com/min-test.php/js5.4b

e.g. <script language="JavaScript" type="text/javascript" src="min-test.php/js5.4b"></script>

Any time you update a file in your groups and you want to be sure that your clients aren't using the cached version all you need to do is change your version number in your config file. If your scripts are written in a way that they read the version from the config file and don't use a hardcoded reference to the version everything should update automatically.

Now let's have a look at the code

require_once 'global.php'; // global file where my ApplicationSettings static class exists

$version = ApplicationSettings::version; // Retrieve the version from my global file
$basepath = "timemp/min-test.php/"; // This needs to be prepended as part of the group name (required since version 2 of minify)

$groups = array(
$basepath . 'js' . $version => array('js/jquery-1.2.6.pack.js' // My js group with the version automatically appended
$basepath . 'css' . $version => array('css/styles.css', // My css group, note you can call your groups whatever you like

set_include_path(getcwd() . '/includes/min/lib' . PATH_SEPARATOR . get_include_path()); // This is the location of your minify library, this is needed for minify to find it's own files
include_once 'Minify.php'; // Include the minify class

$serveOptions = array(
'groups' => $groups, // As part of the serving options add in your groups and a far future expiry date
'maxAge' => 31536000 //maxAge = 1 year

$serveOptions['minifierOptions'][Minify::TYPE_CSS]['prependRelativePath'] = ApplicationSettings::HomeURL; // Read Fixing URIs in CSS files from the user guide (see link below)

Minify::serve('Groups', $serveOptions);


If you want more background on the background of things such as the serve options etc have a look at the User Guide

If you have any issues check out the minify site, many of the common issues are addressed there in detail.

Apart from getting the paths sorted out and reading variables in from your config this app should be very easy to set up. Being able to minify your js and css files is a useful thing to know and a handy tool to have.

A big thanks to Steve and Ryan for their great app. Be sure to check out their blogs: wonko.com and mrclay.org.

7 days of php add-ons

Hi and welcome to 7 days of php add-ons. This includes apps and classes that will help you with common tasks you will come across when developing web applications.

I have chosen seven of my favourite php apps and extensions and I will go through one each day; enhancing your skill set and giving you some useful tools that you can use.

I have hand picked each of these according to ease of use, design and how well they are maintained.

I provide implementation examples and links to download each add-on.

Developing web applications is not just about being able to deliver something that is visually apealing, but also the added functionality and benefit a site can bring. By improving your skill set and having useful tools handy you can easily provide this extra benefit to any of your sites.

Please remember to leave me feedback and ideas.