Im using Zend_Dojo_Data and in a controller for my datasource but it still
can't filter, Im sure having issues with the onchange
'dojo.data.ItemFileReadStore ' url. Is possible to break the onchange url
down me, that only seems to be the problem now. Thanks
denormalized wrote:
>
> I've spent hours trying to figure out all the pieces to the puzzle of
> dependent selects. Here's my solution, in part gathered form messages on
> the zend framework mailing list.
>
> Typical problem: A form with country and city selects. Selecting a
> country should automatically populate the city select. Pre-existing
> values for country and city should automatically be shown in the form.
>
>
> Step 1. Define a country data source.
>
> Country select will be based on data from a Zend_Db_Table_Abstract. I've
> defined a generic "lookup table" resource which defines a getLookup method
> for returning name/value pairs:
>
> public function getLookup($filterName = null, $filterValue = null)
> {
> $select = $this->select();
> if (null !== $filterName && null !== $filterValue)
> {
> $select->where($filterName.' = '.$filterValue);
> }
> $select->order($this->_order);
> return $this->fetchAll($select);
> }
>
> So when you add your options in the form:
>
> $country = new Community_Resource_Country();
> $countrySelect = new
> Zend_Dojo_Form_Element_FilteringSelect('countryId');
> foreach ($country->getLookup() as $c) {
> $countrySelect->addMultiOption($c->countryId, $c->name);
> }
>
>
> Step 2. Define a city data source which can be filtered by country ID.
>
> You need a way to query and return JSON-formatted data sets. Create a
> specialized controller or add an action to a controller that handles this:
>
> public function lookupAction()
> {
> $filterName = $this->_request->getParam('filterName');
> $filterValue = $this->_request->getParam('filterValue');
>
> // Again we're using a generic lookup table class
> $_model = new Community_Resource_City();
> $data = $_model->getLookup($filterName, $filterValue);
>
> if (null !== $data) {
> $items = array();
> foreach ($data as $row) {
> $items[] = array('label' => $row->name, 'name' => $row->name, 'key' =>
> $row->cityId);
> }
>
> $final = array(
> 'identifier' => 'key',
> 'items' => $items,
> );
> echo Zend_Json_Encoder::encode($final);
> }
>
> Because this controller or controller action doesn't need to return any
> fancy stuff (layout, css, etc.), we can disable the layout and view
> renderer:
>
> public function preDispatch()
> {
> // Disable for entire controller. Otherwise, put these calls into
> your action function
> $this->_helper->layout()->disableLayout();
> $this->_helper->viewRenderer->setNoRender(true);
> }
>
>
> Step 3. Ensure your form is dojo-enabled.
>
> class Myproject_Form_Member_Base extends SF_Form_Abstract
> {
> public function init()
> {
> // Dojo-enable the form:
> Zend_Dojo::enableForm($this);
>
>
> Step 4. Configure your form elements to use the data sources:
>
> // Country select using a lookup resource
> $country = new Community_Resource_Country();
> $countrySelect = new
> Zend_Dojo_Form_Element_FilteringSelect('countryId');
> $countrySelect->setLabel('Location')
> ->setRequired(true);
> $countrySelect->addMultiOption('', '');
> foreach ($country->getLookup() as $c) {
> $countrySelect->addMultiOption($c->countryId, $c->name);
> }
> // IMPORTANT: Whenever the country is changed, the data store
> // for the dependent city select should also change
> $countrySelect->setAttrib('onchange', 'dijit.byId("cityId").store =
> new dojo.data.ItemFileReadStore({ url:
> "/data/lookup/table/city/filterName/countryId/filterValue/" +
> dijit.byId("countryId").value });');
> $this->addElement($countrySelect);
>
>
> $city = new Community_Resource_City();
> $citySelect = new Zend_Dojo_Form_Element_FilteringSelect('cityId');
> $citySelect->setAutocomplete(true);
> $citySelect->setLabel('City');
> $citySelect->setRequired(true);
> $citySelect->setStoreId('city');
> $citySelect->setStoreType('dojo.data.ItemFileReadStore'); //
> important!
> $this->addElement($citySelect);
>
>
> Step 5. Pre-populate the city select with data.
>
> At this point the city select won't be populated until the country select
> is changed. But what if we already know the initial country ID?
> Zend_Form won't automatically populate the city select for us!
>
> Therefore, in the controller of our action, after we create the form we
> need to programmatically populate the city select:
>
> // set the dojo city lookup based on country id
> $countryId = $this->_getParam('countryId',false);
> // Note that for my project, id's can never be 0, so I can use the
> empty function
> if (!empty($countryId)) {
> // memberForm is a reference to the form we will display
>
> $this->view->memberForm->getElement('cityId')->setStoreParams(array('url'
> =>
> '/data/lookup/table/city/filterName/countryId/filterValue/'.$memberValues['countryId']));
> $this->view->defaultCityId = $countryId;
> }
>
>
> Step 6. Set the value of the city select. What if we already have a
> value for city? (For instance, a user is editing his profile, which
> already has a city value.)
>
> Unfortunately, simply calling $citySelect->setValue($cityId) won't work!
> (This is currently a bug listed in Zend.) This may be due to the fact
> that the city FilteringSelect has not yet been populated with data.
>
> So, we need some way to set the value of the select AFTER it has been
> populated.
>
> In our controller, set a variable in the view with the value of our
> country:
>
> $this->view->defaultCityId = $this->_getParam('cityId',false);
>
> In our view script that shows the form:
>
> <?=$this->memberForm ?>
>
> <? if (!empty($this->defaultCityId)) : ?>
> <script type="text/javascript">
> dojo.addOnLoad(function() {
> dijit.byId('cityId').attr('value','<?=$this->defaultCityId; ?>');
> });
> </script>
> <? endif; ?>
>
> Note that I put this script AFTER I output the form. Why? Zend will
> automatically output a dojo.addOnLoad which loads your city select
> ItemFileReadStore. You cannot set the value of your select BEFORE the
> ItemFileReadStore is loaded, so we need to set the city value later.
>
> Check the source of your page in the browser. Make sure you set the value
> of your city select AFTER the dojo.addOnLoad which loads your
> ItemFileReadStore.
>
>
> Now your form should not only have dependent selects, but also
> pre-populate the city select correctly.
>
> Derek
>
>
>
--
View this message in context:
http://old.nabble.com/How-to%3A--Zend-Dojo-Form-Dependent-Selects-%28e.g.-Country-City%29-tp25269984p26266681.html
Sent from the Zend Framework mailing list archive at Nabble.com.