如何在Zend Framework 1中为表单使用自定义视图助手?

时间:2015-05-06 09:18:01

标签: php zend-framework

我尝试创建一个自定义ViewHelper来集成Dennis D。的代码:

label = '<label ' . $this->_htmlAttribs($label_attribs) . ' for="' . $optId . '">'
           . $opt_label 
           .'</label>';

    // Wrap the radios in labels
    $radio =  '<input type="' . $this->_inputType . '"'
            . ' name="' . $name . '"'
            . ' id="' . $optId . '"'
            . ' value="' . $this->view->escape($opt_value) . '"'
            . $checked
            . $disabled
            . $this->_htmlAttribs($attribs)
            . $endTag;

    if ('prepend' == $labelPlacement) {
        $radio = $label . $radio;
    }
    elseif ('append' == $labelPlacement) {
        $radio .= $label;
    }

我的想法是,我想创建具有该结构的单选按钮。

<input type="radio" />
<label>Yes</label>

所以我创建了文件,我称之为FormRadio。路径是:&#34; Library / Application / View / Helper / FormRadio.php&#34;。 代码:

class Application_View_Helper_FormRadio extends Zend_View_Helper_FormRadio{

protected $_inputType = 'radio';
protected $_isArray = false;
public function formRadio($name, $value = null, $attribs = null,
    $options = null, $listsep = "<br />\n")
{

    $info = $this->_getInfo($name, $value, $attribs, $options, $listsep);
    extract($info); // name, value, attribs, options, listsep, disable

    // retrieve attributes for labels (prefixed with 'label_' or 'label')
    $label_attribs = array();
    foreach ($attribs as $key => $val) {
        $tmp    = false;
        $keyLen = strlen($key);
        if ((6 < $keyLen) && (substr($key, 0, 6) == 'label_')) {
            $tmp = substr($key, 6);
        } elseif ((5 < $keyLen) && (substr($key, 0, 5) == 'label')) {
            $tmp = substr($key, 5);
        }

        if ($tmp) {
            // make sure first char is lowercase
            $tmp[0] = strtolower($tmp[0]);
            $label_attribs[$tmp] = $val;
            unset($attribs[$key]);
        }
    }

    $labelPlacement = 'append';
    foreach ($label_attribs as $key => $val) {
        switch (strtolower($key)) {
            case 'placement':
                unset($label_attribs[$key]);
                $val = strtolower($val);
                if (in_array($val, array('prepend', 'append'))) {
                    $labelPlacement = $val;
                }
                break;
        }
    }

    // the radio button values and labels
    $options = (array) $options;

    // build the element
    $xhtml = '';
    $list  = array();

    // should the name affect an array collection?
    $name = $this->view->escape($name);
    if ($this->_isArray && ('[]' != substr($name, -2))) {
        $name .= '[]';
    }

    // ensure value is an array to allow matching multiple times
    $value = (array) $value;

    // Set up the filter - Alnum + hyphen + underscore
    require_once 'Zend/Filter/PregReplace.php';
    $pattern = @preg_match('/\pL/u', 'a')
        ? '/[^\p{L}\p{N}\-\_]/u'    // Unicode
        : '/[^a-zA-Z0-9\-\_]/';     // No Unicode
    $filter = new Zend_Filter_PregReplace($pattern, "");

    // add radio buttons to the list.
    foreach ($options as $opt_value => $opt_label) {

        // Should the label be escaped?
        if ($escape) {
            $opt_label = $this->view->escape($opt_label);
        }

        // is it disabled?
        $disabled = '';
        if (true === $disable) {
            $disabled = ' disabled="disabled"';
        } elseif (is_array($disable) && in_array($opt_value, $disable)) {
            $disabled = ' disabled="disabled"';
        }

        // is it checked?
        $checked = '';
        if (in_array($opt_value, $value)) {
            $checked = ' checked="checked"';
        }

        // generate ID
        $optId = $id . '-' . $filter->filter($opt_value);

        $label = '<label'
                 . $this->_htmlAttribs($label_attribs) . ' for="' . $optId . '">'
                 . $opt_label
                 . '</label>';
        $endTag = "/>";
        // Create the radio button
        $radio = '<input type="' . $this->_inputType . '"'
                 . ' name="' . $name . '"'
                 . ' id="' . $optId . '"'
                 . ' value="' . $this->view->escape($opt_value) . '"'
                 . $checked
                 . $disabled
                 . $this->_htmlAttribs($attribs)
                 . $endTag;

        // Combine the label and the radio button
        if ('prepend' == $labelPlacement) {
            $radio = $label . $radio;
        } else {
            $radio = $radio . $label;
        }
        // add to the array of radio buttons
        $list[] = $radio;
    }

    // XHTML or HTML for standard list separator?
    if (!$this->_isXhtml() && false !== strpos($listsep, '<br />')) {
        $listsep = str_replace('<br />', '<br>', $listsep);
    }

    // done!
    $xhtml .= implode($listsep, $list);

    return $xhtml;
}

}

在表单中我调用了新的ViewHelper:

class Application_Form_Registration extends Zend_Form{
public function init()
{
    $radio = new Zend_Form_Element_Radio('two');
    $radio->setLabel('Two')->setRequired(true);
    $radio->setMultiOptions(array('yes'=>'Yes', 'no'=>'No'))
             ->addDecorators(array(array('ViewHelper',array('helper' => 'formRadio'))));;

    $submit = new Zend_Form_Element_Submit('submit');
    $submit->setValue('Submit')
            ->setAttribs(array('class' => 'btn btn-success btn-lg'));

    $this->addElements(array($radio,$submit));


    $submit->setDecorators(array('ViewHelper',
        array(array('data' => 'HtmlTag'),  array('tag' =>'div', 'class'=> 'element')),
        array(array('emptyrow' => 'HtmlTag'),  array('tag' =>'div', 'class'=> 'element', 'placement' => 'PREPEND')),
        array(array('row' => 'HtmlTag'), array('tag' => 'div'))
        ));

    $this->setDecorators(array(
        'FormElements',
        array('HtmlTag', array('tag' => 'div', 'class' => 'myForm')),
        'Form'
    ));
}

}

但什么都没发生。我哪里错了?提前谢谢。

1 个答案:

答案 0 :(得分:2)

我的自定义表单类型有点不同。我没有将装饰器添加到现有的Zend_Form_Element_Radio元素,而是扩展该类并将$_helper设置为我创建的新视图助手。

所以对于你的课程,它可能是这样的:

class Application_Form_Element_NewRadios
    extends Zend_Form_Element_Radio
{
    $_helper = 'newRadios';
}

问题的根源在于您的视图助手与Zend的结尾具有相同的结尾,框架首先查看Zend。有两个选项,要么告诉表单首先查找您的视图助手,要么给它一个不会与Zend视图助手冲突的新名称。

所以你的视图助手会变成这样:

class Application_View_Helper_NewRadios
    extends Zend_View_Helper_FormRadio
{
    // .......
}

您可能需要告诉您的表单在哪里查找新的表单元素类,因此在您的Application_Form_Registration::init方法中,您可能需要添加以下内容:

$this->addPrefixPath(
    'Application_Form_Element',
    'Library/Application/Form/Element',
    'element'
);

在您的application.ini文件中,您可能还需要告诉应用程序在哪里查找新的视图助手类。

resources.view.helperPath.Application_View_Helper = Library/Application/View/Helper