如何设置 Zend Form Elements 的顺序并避免重复

问题描述 投票:0回答:4

在 Zend Form 中,如果两个元素具有相同的顺序,那么 Zend 将完全忽略第二个元素(而不是将其显示在第一个元素下面)。 以下面的代码为例。请注意,

City
Zip Code
元素具有相同的 4

顺序
    $address = new Zend_Form_Element_Textarea('address');
    $address->setLabel('Address')
            ->setAttrib('cols', 20)
            ->setAttrib('rows', 2)
            ->setOrder(3)
            ;

    $city = new Zend_Form_Element_Text('city');
    $city->setLabel('City')
         ->setOrder(4)
          ;

    $postal = new Zend_Form_Element_Text('postal');
    $postal->setLabel('Zip Code')
           ->setOrder(4);

当呈现此表单时,找不到

Zip Code
元素。

如果我想动态设置按钮等元素,但告诉它在表单末尾渲染,我该如何执行此操作而不遇到两个元素具有相同顺序的问题?

public function addSubmitButton($label = "Submit", $order = null)
{
    $form_name = $this->getName();

    // Convert Label to a lowercase no spaces handle
    $handle = strtolower(str_replace(" ","_",$label));

    $submit = new Zend_Form_Element_Submit($handle);
    $submit->setLabel($label)
           ->setAttrib('id', $form_name . "_" . $handle)
            ;

    /////////    Set the button order to be at the end of the form   /////////
    $submit->setOrder(??????);


    $this->addElement($submit);

}
php zend-framework zend-form
4个回答
7
投票

如果您确实需要使用 setOrder() 方法,我会使用订单号 10、20、30、40...,这样就可以很容易地在已设置的元素之间添加元素。

此外,为了避免两次使用订单号,您可以使用一个数组,在其中存储从 1 到 X 的所有数字。每当您设置订单号时,都可以通过名为 getOrderNumberFromArray() 的方法进行设置,该方法返回下一个更高或更低的阶数在数组中仍然可用,并取消设置该数组元素。

或者,也许甚至更好,您可以在新元素之前对想要拥有的元素执行 getOrder() ,然后将此订单号增加 X,然后循环遍历现有表单元素并检查订单号是否不存在还存在。

或者您可以在要在新元素之前和之后显示的元素上使用 getOrder() ,并确保新元素不使用相同的订单号。


3
投票

抱歉迟到了。我所做的是扩展 Zend_Form 并重写 _sort() 方法,如下所示:

/**
 * Sort items according to their order
 *
 * @return void
 */
protected function _sort()
{
    if ($this->_orderUpdated) {
        $items = array();
        $index = 0;
        foreach ($this->_order as $key => $order) {
            if (null === $order) {
                if (null === ($order = $this->{$key}->getOrder())) {
                    while (array_search($index, $this->_order, true)) {
                        ++$index;
                    }
                    $items[$index][]= $key;
                    ++$index;
                } else {
                    $items[$order][]= $key;
                }
            } else {
                $items[$order][]= $key;
            }
        }
        ksort($items);
        $index = 0;
        foreach($items as $i=>$item){
            foreach($item as $subItem){
                $newItems[$index++]=$subItem;
            }
        }
        $items = array_flip($newItems);
        asort($items);
        $this->_order = $items;
        $this->_orderUpdated = false;
    }
}

这与原始排序方法不同,它根据索引将项目放入数组中,然后进行深度优先遍历以展平数组。


0
投票

试试这个代码:

$elements = array(); 
$elements[] = new Zend_Form_Element_Textarea('address'); 
...... 
$elements[] = new Zend_Form_Element_Text('city'); 
....... 
$elements[] = new Zend_Form_Element_Submit($handle); 
..... 
$this->addElements($elements);

您所需要做的就是按照您希望它们显示的顺序添加它们


0
投票

我要做的是 - 为此使用临时数组 - 让元素名称保持所需的顺序(不介意键)。然后像这样使用 foreach :

foreach(array_values($tempArray) as $order => $name) {
    $form->$name->setOrder($order+1);
}

注意 array_values - 它将以编号数组的形式返回值;)不确定 setOrder(0) 是否有效 - 这就是为什么有

+1

© www.soinside.com 2019 - 2024. All rights reserved.