This has been shown on many sites, but it took the combination of several articles for me to figure this one out…maybe it’s just me, dunno.
Also, it drove me nuts how the states list would disappear if the page was refreshed. I learned how to handle that as well, using jQuery cookies.
By the way, here’s the versions of cakephp, jquery and plugins I am using:
CakePHP version 1.3.7
jQuery version 1.5 (I just used the minified version, not that is should matter)
jQuery cookie plugin version 1.0
Not that it matters at all, but for those who may have problems and are wondering what database I’m running, it’s MySQL version 5.1.41 (at least that’s the client I’m running…the server number may or may not be different). I am testing this using XAMPP 1.7.3 for Windows in Windows 7.
Here’s the steps:
***********************
STEP 1
***********************
Add the following to your view file (whatever file contains the form that houses country and state select fields):
<?php
echo $this->Form->input('country_id',array('id' => 'country_id','label' => 'Country','error' => false,'empty' => false));
echo $this->Form->input('state_id',array('id' => 'state','label' => 'State/Province','error' => false,'empty' => 'Select Country First'));
?>
***********************
STEP 2
***********************
Create a model file for country and one for state:
— /app/models/country.php —
<?php
# /app/models/country.php
class Country extends AppModel {
var $name = 'Country';
var $hasMany = array('NameOfYourControllerModelGoesHere');
}
?>
— /app/models/state.php —
<?php
# /app/models/state.php
class State extends AppModel {
var $name = 'State';
var $hasMany = array('NameOfYourControllerModelGoesHere');
}
?>
***********************
STEP 3
***********************
Add the following action to your controller.php file (whichever controller file you are using to control the form)
function get_states($country_id = null){
$this->layout = 'ajax';
$this->set('states',$this->NameOfYourControllerModelGoesHere->State->find('list',array('conditions'=>array('State.country_id' => $country_id))));
}
***********************
STEP 4
***********************
Create a view file for the action you just created, inside /app/views/NameOfYourControllerGoesHere/get_states.ctp
then, add the following to that file:
<?php
# /app/views/NameOfYourControllerGoesHere/get_states.ctp
?>
<option>Select a State/Province</option>
<?php
foreach($states as $stateId=>$stateName){
echo '
<option value="'.$stateId.'">'.$stateName.'</option>'."\n";
}
?>
***********************
STEP 5
***********************
Download the jQuery cookie plugin from
http://plugins.jquery.com/files/jquery.cookie.js.txt
copy the contents of jquery.cookie.js.txt into /app/webroot/js/jquery.cookie.js
***********************
STEP 6
***********************
If you don’t already have jQuery installed, you can download the latest version by going to www.jquery.com and click the download button (I’m using version 1.5, but I would imagine this code will still work with future versions)
Once you have both jQuery and jQuery cookie plugin installed, add this to the view file containing your form:
<?php
echo $this->Html->script('jquery', false);
echo $this->Html->script('jquery.cookie',false);
?>
***********************
STEP 7
***********************
Add the following to either your layout file or to the view file that contains your form:
<script type="text/javascript">
$(document).ready(function() {
if($.cookie("selectedCountry") == null){
/* default to United States */
$("#country_id").val( 1 ).attr('selected',true);
$('#state').load('NameOfYourControllerGoesHere/get_states/1');
}else{
$("#country_id").val( $.cookie("selectedCountry") ).attr('selected',true);
$('#state').load('NameOfYourControllerGoesHere/get_states/'+$.cookie("selectedCountry"));
}
$('#country_id').change(function() {
/* load last selected country using a cookie, in case page was refreshed...this also makes sure the state dropdown is populated with the last selected country's states/provinces */
var country_data = $(this).val();
$.cookie("selectedCountry", country_data);
var country_select = $.cookie("selectedCountry");
$('#state').load('NameOfYourControllerGoesHere/get_states/'+$(this).val());
});
});
</script>
Obviosuly, you need to have countries and states inserted into the appropriate tables in your database for this to work. Here’s the structure I used for my tables:
— For countries Table —
id int(11) auto_increment primary_key,
name varchar(50)
— For states Table —
id int(11) auto_increment primary_key,
country_id int(11),
name varchar(50)
———————————————————–
If I missed something, please send me a comment and I’ll be happy to fix it. If you have any problems, let me know and I’ll try to help the best I can.
Thanks for reading