<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Damian Gostomski &#124; Freelance Web DevelopmentjQuery &#187; Damian Gostomski | Freelance Web Development</title>
	<atom:link href="http://www.gostomski.co.uk/category/jquery/feed" rel="self" type="application/rss+xml" />
	<link>http://www.gostomski.co.uk</link>
	<description></description>
	<lastBuildDate>Tue, 31 Jan 2012 21:24:25 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.3</generator>
		<item>
		<title>Easy chained select using jQuery</title>
		<link>http://www.gostomski.co.uk/jquery/easy-chained-select-using-jquery</link>
		<comments>http://www.gostomski.co.uk/jquery/easy-chained-select-using-jquery#comments</comments>
		<pubDate>Tue, 16 Feb 2010 20:29:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.gostomski.co.uk/?p=8</guid>
		<description><![CDATA[Whilst working on Project Trackr, I had the need to be able to easily add chained selects within a form, more specifically, I wanted selecting an account or a client from a drop down list to load another drop down list beneath it with users in that account. An easy way to do this would<a href="http://www.gostomski.co.uk/jquery/easy-chained-select-using-jquery" class="more-info">Read more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>Whilst working on <a title="Project Trackr - Web based project management" href="http://www.projecttrackr.com">Project Trackr</a>, I had the need to be able to easily add chained selects within a form, more specifically, I wanted selecting an account or a client from a drop down list to load another drop down list beneath it with users in that account. An easy way to do this would be to register a listener on a given ID, when something in that dropdown is selected, fire an AJAX event and then load the response contents into a pre specified div. Easy enough and it works, but I wasn&#8217;t satisfied.</p>
<p>I wanted a solution which was a simple as adding a class to the first drop down, that’s it. A couple of minutes later, I had a working solution, and I find it to be very useful, so thought I would share it with you.</p>
<p><span id="more-8"></span></p>
<p><strong>This was a quick and dirty solution to my specific problem. In my case, I don&#8217;t need to worry about this not working when JavaScript is disabled. If you need to worry about such things, Paul Norman suggested how this might work in <a href="http://www.gostomski.co.uk/jquery/easy-chained-select-using-jquery/comment-page-1#comment-20">the comments</a></strong></p>
<p>The solution is made up of 3 parts, the HTML, JavaScript and the PHP, which I will now go through one at a time.</p>
<h3>The HTML</h3>
<p>There is absolutely nothing fancy here, at all, so much so, that I’ve decided to not bother with the rest of the form/HTML page and just show the relevant field.</p>
<pre class="brush: xml; title: ;">
&lt;p&gt;
	&lt;label for=&quot;form_client&quot;&gt;Client&lt;/label&gt;
	&lt;?php echo form_error('client_id')?&gt;
	&lt;?php echo HTML::client_dropdown($clients, false, array('class'=&gt;'chain_user'))?&gt;
&lt;/p&gt;
</pre>
<p>A couple of quick points here, I wrap each form field, label and error (not shown here) in a set of paragraph tags, which allows me to style them using CSS. The client_dropdown function returns a select element containing the clients passed in. This results in something like</p>
<pre class="brush: xml; title: ;">
&lt;select class=&quot;chain_user&quot; id=&quot;form_client&quot;&gt;
	&lt;option&gt;&lt;/option&gt;
	&lt;option value=&quot;1&quot;&gt;Account 1&lt;/option&gt;
	&lt;option value=&quot;2&quot;&gt;Account 2&lt;/option&gt;
	&lt;option value=&quot;3&quot;&gt;Account 3&lt;/option&gt;
	&lt;option value=&quot;4&quot;&gt;Account 4&lt;/option&gt;
	&lt;option value=&quot;5&quot;&gt;Account 5&lt;/option&gt;
	&lt;option value=&quot;6&quot;&gt;Account 6&lt;/option&gt;
&lt;/select&gt;
</pre>
<h3>The Javascript</h3>
<p>I’m a huge fan of jQuery, so obviously that’s what I’m using here. The code itself is well commented, so it should be pretty self explanatory</p>
<pre class="brush: jscript; title: ;">
var SITE_URL	= 'http://localhost/project/';
var LOADING		= '&lt;img src=&quot;'+SITE_URL+'images/loading.gif&quot; class=&quot;loading&quot; /&gt;';

$(document).ready(function() {
	/**
	 * Listen out for chain events
	 * In this case, any select which has a class &quot;chain_user&quot;
	 * It will load a dropdown with all the users in that account beneath it
	 */
	$('select.chain_user').change(function() {
		// First, we need the account ID
		// Leave now if this is not set (They selected the empty item at the top)
		var account_id = $(this).val();
		if(account_id == '') return false;

		// Initialise any objects we need now or later
		// Create these now as $(this) will not be the real this in the response
		var parent = $(this).parent();
		var next = parent.next();

		// We need to put a loading gif in place of where the users drop down will be
		// We need to make sure we don't already have an AJAX loaded dropdown
		// otherwise we could end up with several - Disaster!
		if(next.hasClass('loaded-via-ajax')) {
			next.html(LOADING+' Loading users');
		} else {
			var p = new jQuery('&lt;p class=&quot;loaded-via-ajax&quot;&gt;'+LOADING+' Loading users&lt;/p&gt;');
			parent.after(p);
			// We need to update what &quot;next&quot; is so that it works within the AJAX response
			next = parent.next();
		}

		// Now use AJAX to fetch a dropdown with all the users
		$.ajax({
			type: 'GET',
			url: SITE_URL+'account/ajax/get_users_dropdown/'+account_id,
			success: function(response) {
				next.html(response);
			}
		});
	});
});
</pre>
<h3>The PHP</h3>
<p>I’ve used PHP here, but you could use any server side language you want here. The code which gets called by the AJAX function is</p>
<pre class="brush: php; title: ;">
$account = new Account_model($account_id);
$users = $account-&gt;get_users();

// We also need spit out a label
echo '&lt;label for=&quot;form_user&quot;&gt;User&lt;/label&gt;';
echo HTML::user_dropdown($users);
</pre>
<p>The user_dropdown function is similar to the client_dropdown function I used to generate the first dropdown and is shown below</p>
<pre class="brush: php; title: ;">
public static function user_dropdown($users, $selected = false, $attributes = array()) {
	// Merge the incoming attributes with the defaults
	$defaults = array(
		'name'=&gt;'user_id',
		'title'=&gt;'Select the user from this list',
		'id'=&gt;'form_user'
	);
	$attributes = array_merge($defaults, $attributes);

	// Take care of any attributes we have
	$tmp = '';
	foreach($attributes as $key=&gt;$value) {
		$tmp.= ' '.$key.'=&quot;'.$value.'&quot;';
	}

	// Build up the select item
	$str = '&lt;select'.$tmp.'&gt;';
	foreach($users as $user) {
		$str.= '&lt;option value=&quot;'.$user-&gt;id.'&quot;'.($selected == $user-&gt;id ? ' selected=&quot;selected&quot;' : '').'&gt;'.$user-&gt;first_name.' '.$user-&gt;last_name.'&lt;/option&gt;';
	}
	$str.= '&lt;/select&gt;';
	return $str;
}
</pre>
<p>And that&#8217;s all there is to it! I hope you find this useful</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gostomski.co.uk/jquery/easy-chained-select-using-jquery/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

