Reputation: 817
I have a need for chained select boxes in my zend framework project: Countries->Regions->Provinces->Towns.
I am using zend form and intend to resubmit to reload the contents of the of the chained select boxes when one of them is changed. I have written some code in a PHPunit test to simulate what I will need in my controllers. I will require to use this regional structure in quite a few different forms on my site and also plan to enhance with AJAX.
I don't want to be duplicating this code, so where should I store it and how should it be structured so that I can reuse its functionality. I thought perhaps an action helper?
public function testCanGetRegionalStructureFromUser() {
$user = new \Entities\User;
$user = $this->em->getRepository('Entities\User')->findOneByEmail('[email protected]');
$town = new \Entities\Town;
$town = $user->getTowns_id();
// if user has not town input, then use the default
if (is_null($town)) {
$config = Zend_Registry::get('config');
$defaulttownid = $config->towns->defaultid;
$town = $this->em->getRepository('Entities\Town')->find($defaulttownid);
}
// get the town id
$townid = $town->getId();
//get the province
$province = $town->getProvinces_id();
$provinceid = $province->getId();
//get the region
$region = $province->getRegions_id();
$regionid = $region->getId();
//get the country
$country = $region->getCountries_id();
$countryid = $country->getId();
$countrylist = $this->em->getRepository('Entities\country')->findActiveCountries();
$regionlist = $this->em->getRepository('Entities\Region')->findActiveRegions($countryid);
$provincelist = $this->em->getRepository('Entities\Province')->findActiveProvinces($regionid);
$townlist = $this->em->getRepository('Entities\Town')->findActiveTowns($provinceid);
}
countrylist,regionlist etc. are ready to be injected into my form as options that will be used to populate the select boxes.
Upvotes: 0
Views: 376
Reputation: 69957
I think that for this case, creating a composite Zend_Form_Element makes the most sense.
This way, you can easily add the element to your forms with only a few lines of code, you can have validators built into the element so you aren't repeating that logic, and with your own decorator you can easily control the layout of the selections and only have to change one file to reflect the changes to all forms.
For one of my projects I created a composite element that had a plain text box that used autocomplete to search customers in real time as the user types. Once a customer is selected from the autocomplete list, an ajax call is made that fetches a list of properties owned by that customer and a dropdown box is updated with the new list.
The element provides access to the data values (customer, property) and the decorator renders the individual elements in a group, and set up the necessary event handlers and ajax calls (most of that code is in an external .js file.
Creating and Rendering Composite Elements
Similar to the above reference, by Matthew Weier O'Phinney
Video: Creating composite elements
Upvotes: 1