Как я могу установить порядок элементов формы Zend и избежать дублирования - PullRequest
4 голосов
/ 24 марта 2011

В 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);

}

Ответы [ 4 ]

7 голосов
/ 25 марта 2011

Если вам действительно нужно использовать метод setOrder (), я бы работал с порядковыми номерами 10, 20, 30, 40, ... Таким образом, будет легко добавить элементы между уже установленными Элементами.

Кроме того, чтобы избежать использования номеров заказов дважды, вы можете использовать массив, в котором хранятся все числа от 1 до X. Каждый раз, когда вы устанавливаете номер заказа, вы устанавливаете его с помощью метода getOrderNumberFromArray () возвращает следующий номер более высокого или более низкого порядка, все еще доступный в массиве, и сбрасывает этот элемент массива.

В качестве альтернативы, а может быть, даже лучше, вы можете сделать getOrder () для элемента, который вы хотите иметь перед новым элементом, затем увеличить этот номер заказа на X, а затем перебрать существующие элементы формы и проверить, что номер заказа не еще не существует.

Или вы можете просто использовать getOrder () для элемента, который вы хотите показать до и после нового элемента, и убедиться, что вы не используете одинаковые порядковые номера для нового элемента.

3 голосов
/ 12 мая 2011

Извините, что опоздал на вопрос.Что я сделал, так это расширил 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 голосов
/ 25 марта 2011

что я хотел бы сделать - использовать временный массив для этого - в этом держать имена элементов в нужном порядке (не обращайте внимания на ключи). Затем используйте foreach так:

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

Обратите внимание на array_values ​​- он будет возвращать значения в виде пронумерованного массива;) Не уверен, что setOrder (0) работает - поэтому есть +1

0 голосов
/ 25 марта 2011

Попробуйте этот код:

$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);

Все, что вам нужно сделать, это добавить их в том порядке, в котором вы хотите, чтобы они отображались

...