Zend_Form,默认覆盖装饰器,不工作

问题描述:

I am having issues with zend_form and zend_decorator.

I have created a decorator class to default all forms to use list elements, however it doesn't seem to be working!

Essentially my_decorator_design extends zend_form and then my forms extend the decorator.

Ideas?

class My_Decorator_Design extends Zend_Form {

 public function loadDefaultDecorators() {
  $this->addDecorator('FormElements')
  ->addDecorator('HtmlTag', array('tag' => 'ul')) //this adds a <ul> inside the <form>
  ->addDecorator('Form');

 $this->setElementDecorators(array(
  'ViewHelper',
  'Label',
  'Errors',
  new Zend_Form_Decorator_HtmlTag(array('tag' => 'li')) //wrap elements in <li>'s
 ));

 $this->setDisplayGroupDecorators(array(
  'FormElements',
  'Fieldset',
  new Zend_Form_Decorator_HtmlTag(array('tag' => 'li')), //wrap groups in <li>'s too
  new Zend_Form_Decorator_HtmlTag(array('tag' => 'ul'))
 )); 

 $this->setDisplayGroupDecorators(array(
  'FormElements',
  'Fieldset',
  new Zend_Form_Decorator_HtmlTag(array('tag' => 'li')) //wrap groups in <li>'s too
  ));
 }

}

class Forms_User_Update extends My_Decorator_Design {
  public function __construct($options=array()) {
    parent::__construct($options);//if we ever want to pass on things to zend_form
    $this->setName('user_update');
    $this->loadDefaultDecorators();

    //user_name, first_name, email, password, date_of_birth
    $user_name          = new Zend_Form_Element_Text('user_name');
    $first_name         = new Zend_Form_Element_Text('first_name');
    $email              = new Zend_Form_Element_Text('email');
    $password           = new Zend_Form_Element_Password('password');   
    $password2          = new Zend_Form_Element_Password('password2');
    $submit             = new Zend_Form_Element_Submit('Submit');

    $user_name->setRequired(true)
              ->setLabel('Username');
    $first_name->setRequired(false)
               ->setLabel('First Name');
    $email->setRequired(true)
          ->setLabel('Email:')
          ->addFilter('StringToLower')
          ->addValidator('NotEmpty', true)
          ->addValidator('EmailAddress');
    $password->setLabel('Password:')
             ->setRequired(false)
             ->setIgnore(false)
             ->addValidator('stringLength', false, array(6));
    $password2->setLabel('Confirm Password:')
              ->setRequired(false)
              ->setIgnore(true);
    $submit->setLabel("Submit")
           ->setIgnore(true);

    $this->addElements(array(
        $user_name, $first_name, $email, $password, $password2, $submit
    ));
    //$this->Submit->removeDecorator('Label');
    //$this->addElementPrefixPath('My_Decorator', 'My/Decorator/', 'decorator');
    $this->setMethod('post');
    $this->setAction('/update-account');    
  }
}

You call loadDefaultDecorators in the constructor, and call setElementDecorators from there.

But addElement uses the element decorators only when you construct elements from strings, not when you pass a ready made element, while setElementDecorators only sets the decorators for the already existing controls (which are none in the constructor).

As you create the elements first and then pass them as Elements the element decorators are never set.

Remove the call to loadDefaultDecorators in the constructor.

I have also faced these types of problems but finally I have customized the zend form for both file element and other input elements.

Use the following code to apply file decorator with other elements in the zend form .

<?php 
   public function init()
   {
    // Set the method for the display form to POST
     $this->setMethod('post');
         $this->setElementDecorators(array(
                    'ViewHelper',
                    array('HtmlTag',array('tag' =>'div' ,'class'=>'field')),
                    array('Label',array('tag' =>'div','class'=>'label')),
                ));

    // Add an email element
    $this->addElement('text','name',array('label'=>'Name:',
            'required'=>true,


    $this->addElement('text','username',array('label'=>'User Name:','id'=>'user_name',
            'required'=>true,

            ));

    $this->addElement('password','password',array('label'=>'Password:',
                    'required'=>true,

                    ));

    $this->addElement('password','cpassword',array('label'=>'Password Again:',
                    'required'=>true,

                    ));

    $this->addElement('text','phone',array('label'=>'Phone:',
                    'required'=>true,

                    ));

    $this->addElement('text', 'email', array(
                        'label'      => 'Email:',
                         'value'     =>'test',


                        ));
    $this->addElement('file', 'photo', array(
                        'label'      => 'Profile Photo:',
                        'decorators' =>array('file',array('HtmlTag',array('tag'=>'div','class'=>'field'))
                                            ,array('Label',array('tag'=>'div','class'=>'label')))
                        ));

    $this->addElement('submit', 'save',array('label'=>'Register Me','class'=>'submitbtn','style'=>'margin-left:150px;'));



}

?>

I hope that will work fine