i need this , i try,

 thanks derek

On Wed, Sep 2, 2009 at 10:23 PM, denormalized <[email protected]>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://www.nabble.com/How-to%3A--Zend-Dojo-Form-Dependent-Selects-%28e.g.-Country-City%29-tp25269984p25269984.html
> Sent from the Zend Framework mailing list archive at Nabble.com.
>
>

Reply via email to