简体   繁体   中英

Zend Framework Forms, subforms, and decorators

I currently have a zend framework application with multiple modules. Each module should be using the same Zend_Form_Decorator_ViewScript , located in the default modules /views/scripts folder.

Without any changes, modules by default only look for form decorator viewscripts in their own /views/scripts folder located under each module, so to get them to load them from default modules folder, I first need to apply this within the form:

$view = new Zend_View();
$view->setScriptPath(APPLICATION_PATH . '/views/scripts');
$this->setView($view);

Within that same form, I create multiple Zend_Form_SubForm s, for which I need to apply that same code again. If that isn't enough, I need to apply that path to each individual element in each SubForm as well as the parent form. Additionally, each element has to have its ViewScript defined each time like:

$username->setDecorators(array(array('ViewScript', array('viewScript' => '/formScripts/wizardElement.phtml'))));

Now, it all works if I define all of that for each element/subform/form within the same file, but it just seems so much unnecessary work/code.

  • Can the process be simplified firstly by just having the parent form define the scriptPath for itself, its elements, its subforms, and the subforms elements?
  • Can new elements created automatically have specific ViewScripts defined for them, based on what type of element it is (ie input box, checkbox, selectbox, textarea, button etc)?

I am currently extending my form directly from the default Zend_Form , I won't have a problem of creating an own abstract form to extend my forms from, but especially with the scriptPath problems, I am not entirely sure how I should approach this whole problem.

Applying:

$this->setSubFormDecorators(array(
            'Form',
            array('ViewScript', array('viewScript' => '/formScripts/wizardSubForm.phtml'))            
));

overwrites all the element specific decorators I've applied before it.

Suggestions?

May be I didn't get your case in details but I would suggest you create base form, then base form classes for each module then your specific forms extend the respective module form

My_Base_Form extends Zend_Form
{
   public function init()
   {
     //if you need to init something for all forms
     parent::init();
   }

   public function _createSelect($name)
   {
      $element=new Zend_Form_Element_Select($name);
      $element->setDecorators(
             //decorators for select
         )
      $element->viewScript='select.phtml';
      return $element;
   }
}

My_Default_Form extends My_Base_Form
{
   public function init()
   {

     //what you do to init dirs for this module
     $view = new Zend_View();
     $view->setScriptPath(APPLICATION_PATH . '/views/scripts');
     $this->setView($view);
     parent::init();
   }

   //called automatically by Zend_Form
   public function loadDefaultDecorators()
   {

       parent::loadDefaultDecorators();
       $this->setDefaultFormDecorators($this);
       $this->setButtonDecorators($this);
   }

}
My_Admin_Form extends My_Base_From{}

To not repeat setting element decorators you may create helper methods that do that for you and put it in the base form class or in the module form class

Default_Form_Register extends My_Default_Form
{
     public function init()
     {
         $el=$this->_createSelect($name);
         $el->setLabel('Select');
         $this->addElement($el);
         parent::init();
     }
}

you may need to use the same approach for subforms, then put the base classes in your library and you should be ok.

You are will be free to make common changes based on module or element type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM