-
Notifications
You must be signed in to change notification settings - Fork 0
Dependent Select Dropdown
Sometimes you will need to create a dropdown that relies on another dropdown. A great example is when you have a list of countries that may display a list of states in another dropdown.
###Setting up the form Selects We will need two different dropdowns. Since the first drop down is independent and doesn't rely on anything else, we can automatically populate the dropdown with data.
$nationDropDown = new Select('nation_id', Nations::find(array(
"columns" => "nation_id, nation_name",
"cache" => array("key" => "nations", "lifetime" => 86400)
)), array(
'useEmpty' => true,
'emptyText' => 'None Specified',
'using' => array('nation_id', 'nation_name')
));
The second dropdown, we won't specify anything, since it is dependent on the first dropdown. Javascript will automatically populate this dropdown with the correct values.
$statesSelect = new Select('states_id', array(null=>'None Specified'));
###In the view file Since I like to keep my javascript separate from the rest of the view I typically put the javascript in its own file. So there are three changes in the view.
<script type="text/javascript">
/*Define URLS to use in actions*/
var getResultsUrl = "{{ grabResults }}";
</script>
The first javascript call allows us to grab the controller URL that will do the processing of the ajax request for the dependent dropdown.
{{ javascript_include("js/referrals.js") }}
$("#nation_id").change(function() {
var value = $(this).val();
$.ajax({
type: "POST",
url: getResultsUrl,
data: {"id": value},
success: function(response){
$("#states_id option")
.not(":first").remove();
parsed = $.parseJSON(response);
$.each(parsed, function(key, value) {
$("#states_id")
.append($("<option></option>")
.attr("value",value.id)
.text(value.name));
});
}
});
});
This javascript file contains all the magic behind the first dropdown. The logic behind it is: Once the user selects a value from the dependent dropdown, we grab the user value, and make an ajax request with the user id. That request will be to the controller we setup later. If the request is successful, we get a response back. We remove all of the options in the dependent dropdown except the first one. We parse the response as JSON. After we parse the JSON, we append the result into the select field.
{{ form.render('nationDropDown') }}
{{ form.render('statesSelect') }}
Setting up the dropdowns in the view
###The Controller
public function grabStatesAction()
{
$id = $this->request->getPost("id", "int");
$data = States::find(array(
"columns" => array("state_id, state_name"),
"conditions"=> "state_parent_id = :id:",
"bind" => array("id"=>$id)
));
foreach ($data as $result) {
$resData[] = array("id"=>$result->state_id, "name"=>$result->state_name);
}
echo json_encode($resData);
}
The controller then grabs the id and finds the records in the database that match that nation id.
After that is done we loop through each result and store it in an array. Finally, we spit out the date.