Use zend-decorator to format Zend_Form_Element_Radio in a table column with oher Zend_Form_Elements in rows

前端 未结 4 948
南笙
南笙 2021-01-20 19:17

I want use decorators to format as table the following Zend_Form, placing a description in the first column and the Zend_Form_Element_Radio\'s opti

4条回答
  •  南笙
    南笙 (楼主)
    2021-01-20 20:03

    Well here my version of the answer.

    Into the init I've add a custom decorator RadioTable to the form, and prefix path to load the decorator

    then I decorate all the elements as a normal table, this's important because all my efforts are to keep the facilities offer by standard decorators like "Error"

    Please note the Custom_Form_Element_FirstSelect and the ->setSeparator in the radio element

    I also add the submit button

    public function init()
    {
        $_please_select = array("" => " please select ");
    
        // I add a my custom decorator
        $this->addPrefixPath('Custom_Form_Decorator',
                                 'Custom/Form/Decorator',
                                 'decorator');
    
        $this->setMethod(Zend_Form::METHOD_POST);
    
        $input_lunch = new Zend_Form_Element_Radio('lunch');  
        $input_lunch ->setMultiOptions(self::$KINDS)
                     ->setSeparator("\t__RADIO_SEPARATOR__\t")  //set custom separator I'll use in custom decorator
                     ->setDecorators(array(
                         'ViewHelper',  // add a standard decorator
                         'Label', // I'll use the label decorator to show text
                       ));
    
        $this->addElement($input_lunch );
    
        foreach (self::$KINDS as $k => $_description) {
            // to "mark" the first select I extend the Zend_Form_Element_Select
            // with Custom_Form_Element_FirstSelect
            $input_drink = new Custom_Form_Element_FirstSelect('drink_' . $k);
            $input_drink->addMultiOptions(self::$DRINKS)                    
                        ->setDecorators(array(
                                        'ViewHelper', // add a standard decorator
                                        array(array('data' => 'HtmlTag'),array('tag' => 'td')), // add a standard decorator
                                            ));
    
            $input_food = new Zend_Form_Element_Select('food_' . $k);
            $input_food->addMultiOptions($_please_select)
                ->addMultiOptions(self::$FOODS)
                ->setDecorators(array(
                                'ViewHelper',
                                array(array('data' => 'HtmlTag'),array('tag' => 'td')),
                                ));
    
            $this->addElement($input_drink);
            $this->addElement($input_food);
        }
    
        // add a the submit button
        $submit = new Zend_Form_Element_Submit('submit');
            $submit->setLabel('SUBMIT');
            $submit->setDecorators(array(
                                    'ViewHelper',
                                    'Errors',
                                    array(array('data' => 'HtmlTag'), array('tag' => 'td', )),
                                    array(array('row' => 'HtmlTag'), array('tag' => 'tr')),
                                ));
            $this->addElement($submit);
    
        // add the custom decorators to the whole form
        $this->setDecorators(array(
            'RadioTable',
            array('HtmlTag', array('tag' => 'table', )),
            'Form'
        ));
    }
    

    the Custom_Form_Element_FirstSelect

    class Custom_Form_Element_FirstSelect extends Zend_Form_Element_Select{
    
    }
    

    the Custom_Form_Decorator_RadioTable

    class Custom_Form_Decorator_RadioTable extends Zend_Form_Decorator_Abstract {
    
        public function render($content){
    
            $wrap = '';
            // I'll take the element
            $radioElement  = $this->getElement()->getElement('lunch');
            // then I render it and explode in array using the separator
            $arrayRadio = explode("\t__RADIO_SEPARATOR__\t", $radioElement->__toString());
    
    
    
            $count = 0;
            $arrayElement  = $this->getElement()->getElements(); 
            // loop on all form elements and I render them
            foreach ($arrayElement as $keyForm => $element){
                // I skip the radio element 
                if($element instanceof Zend_Form_Element_Radio){
                    continue;
                }
    
                if($element instanceof Custom_Form_Element_FirstSelect ){
                    // when I found the custom select element I'll prefix with "open-row-tag" and radio button in column
                    $wrap .= "". "". $arrayRadio[$count++] . "" .  $element->__toString();
                    // note that the select elements are already decorated
                } else if($element instanceof Zend_Form_Element_Select){
                    // after the last select I close the row
                    $wrap .= $element->__toString() ."";
    
                }
    
                if($element instanceof Zend_Form_Element_Submit){
                    // add the SUBMIT button
                    $wrap .=  $element->__toString() ;
    
                }
            }
    
            return $content.$wrap;
        }
    }
    

    Of course I can use the name of the element instead of use a custom element class to open the table row, but in this way I'm feel more flexible.

提交回复
热议问题