获取Zend中自定义选择表单字段的数据库字段


Get database field for custom select form field in Zend

我有一个可以工作的表单。我创建了一个新的表单元素,它是日期的多选择字段。它将日、月和年组合成一个表单元素,如下所示:

表单项:

$this->addElement('date', 'new_date', array(
    'label'         => 'Expires as New on?'
));

表单元素:

<?php
require_once 'Zend/Form/Element/Multi.php';
class Zend_Form_Element_Date extends Zend_Form_Element_Multi
{
    public $helper = 'formDate';
    protected $_registerInArrayValidator = false;
    private $data;
    public function isValid ($data) {
        $this->data=$data;
        return true;
    }
    public function getValue () {
         return $this->data[2].'-'.$this->data[0].'-'.$this->data[1];
    }
}

辅助元素:

<?php
require_once 'Zend/View/Helper/FormElement.php';
class Zend_View_Helper_FormDate extends Zend_View_Helper_FormElement
{
    public function formDate($name, $value = null, $attribs = null,
        $options = null, $listsep = "<br />'n")
    {

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

        // force $value to array so we can compare multiple values
        // to multiple options.
        $value = array_map('strval', (array) $value);
        //Zend_Debug::dump($value);
        $olddata = explode("-",$value[0]);  
        //Zend_Debug::dump($olddata);   
        // check if element may have multiple values
        $multiple = '';
        if (substr($name, -2) == '[]') {
            // multiple implied by the name
            $multiple = ' multiple="multiple"';
        }
        if (isset($attribs['multiple'])) {
            // Attribute set
            if ($attribs['multiple']) {
                // True attribute; set multiple attribute
                $multiple = ' multiple="multiple"';
                // Make sure name indicates multiple values are allowed
                if (!empty($multiple) && (substr($name, -2) != '[]')) {
                    $name .= '[]';
                }
            } else {
                // False attribute; ensure attribute not set
                $multiple = '';
            }
            unset($attribs['multiple']);
        } 
        // now start building the XHTML.
        $disabled = '';
        if (true === $disable) {
            $disabled = ' disabled="disabled"';
        }
        // Build the surrounding select element first.
        $xhtml = '<select'
                . ' name="' . $this->view->escape($name) . '[]"'
                . ' id="' . $this->view->escape($id) . '"'
                . $multiple
                . $disabled
                . $this->_htmlAttribs($attribs)
                . ">'n    ";
        // build the list of options
        // month
        $month = array();
        $month[] = $this->_build('MM', 'MM');
        for($i = 1; $i<= 12; $i++){
            $m = date("M", mktime(0,0,0,$i));
            $month[] = $this->_build($i<10?'0'.$i:$i, $m, $olddata[1]);
        }
        $day = array();
        $day[] = $this->_build('DD', 'DD');
        for($i = 1; $i<=31; $i++){
            $day[] = $this->_build($i<10?'0'.$i:$i, $i<10?'0'.$i:$i, $olddata[2]);
        }
        $year = array();
        $year[] = $this->_build('YYYY','YYYY');
        for($i = (int)date("Y"); $i < (int)date("Y")+11; $i++){
            $year[] = $this->_build($i, $i, $olddata[0]);
        }
        // add the options to the xhtml and close the select
        $month = $xhtml.implode("'n    ", $month) . "'n</select>";
        $day = $xhtml.implode("'n    ", $day) . "'n</select>";
        $year = $xhtml.implode("'n    ", $year) . "'n</select>";
        return $month.$day.$year;
    }
    protected function _build($value, $label, $selected)
    {
        $opt = '<option'
             . ' value="' . $this->view->escape($value) . '"'
             . ' label="' . $this->view->escape($label) . '"';
       if ($value == $selected) {
            $opt .= ' selected="selected"';
        }
        $opt .= '>' . $this->view->escape($label). "</option>";
        return $opt;
    }
}

我已经能够将数据从这个表单元素保存到数据库中。然而,当我尝试加载表单时,除了我的自定义表单元素外,所有表单元素都接收数据库值。谁能告诉我我做错了什么吗?

从我可以看到的,在你的Zend_View_Helper_FormDate::_build($value, $label, $selected)你有第三个参数,用于添加selected="selected"到你的HTML,但在你的formDate方法你只传递前2个参数ie。$this->_build('MM', 'MM');

必须在第三个参数中传递值。另外,为自定义元素使用Zend名称空间也要减10分。这是一个大禁忌。: P

编辑

替换帮助器:

$value = array_map('strval', (array) $value);
//Zend_Debug::dump($value);
$olddata = explode("-",$value[0]);  
//Zend_Debug::dump($olddata);

:

if ( !empty($value)) {
    $value = array_map('strval', (array) $value);
    $olddata = explode("-",$value[0]);
} else {
    $olddata = array('','','');
}
然后

protected function _build($value, $label, $selected)

:

protected function _build($value, $label, $selected = null)

添加到自定义元素:

public function setValue($value)
{
    /** Assuming format Y-m-d and need m-d-Y**/
    list($year,$month,$day) = explode('-', $value);
    $this->data = array($month,$day,$year);
    // Almost forgot
    return $this;
}

注意:我只是拿Zend命名空间取笑你。