Отрисовка элементов Zend_Form в неправильном порядке

После добавления элементов в мою форму я получаю их отрисовку в странном порядке, получая кнопку отправки перед одним флажком. Буду признателен за подсказки, где можно найти быстрое исправление.

class SomeForm extends My_Form {
    public function init() {
        $this->addElements();
        //add a few elements (#1)

        $this->addElements($otherForm->getElements());
        //borrow some elements from another form (#2)

        if ($trueCondition=true) {
            $this->addElements();
            //add one more element which will render at end of form (#3)
        }

        $this->addElements();
        //some more, including submit button (#4)

        parent::init();
        //call My_Form to register custom decorator; culprit?
    }
}

Вывод:

<inputs from addElements() #1 />
<inputs from addElements() #2 />
<inputs from addElements() #4 />   <-
<inputs from addElements() #3 />   <- mixed up order

Все другие формы, использующие настраиваемый декоратор, отображают элементы в том порядке, в котором они были добавлены. Я не выкладываю декоратор, так как он довольно грязный. Надеюсь, ошибка в другом.


person bububaba    schedule 17.04.2012    source источник
comment
Элементы должны быть упорядочены в соответствии с тем, когда вы добавляете их в форму. Может, вы где-то используете setOrder()?   -  person Liyali    schedule 17.04.2012
comment
Неа. Проверенная форма, контроллер и код представления, не соответствует setOrder   -  person bububaba    schedule 17.04.2012
comment
Вы используете ZS / Eclipse? На вашем месте я бы запустил форму (с несколькими точками останова) и проверил, что происходит в перспективном режиме отладки. Обычно это хороший (и быстрый) способ увидеть, как выполняется ваш код.   -  person Liyali    schedule 17.04.2012
comment
Было бы полезно увидеть некоторый код из My_Form, например метод addElements ().   -  person vascowhite    schedule 17.04.2012
comment
@Liyali - Я не использую ZS / Eclipse, но я повторял 1, 2, 3 и 4 под каждым addElements(), и они повторяются по порядку. @vascowhite - My_Form расширяет только init(), isValid() и render() (последнее из-за специального декоратора; он просто отображает значение вместо метки на кнопке и переводит, если перевод доступен). addElements() вызывается для родительского класса, то есть ванильного Zend_Form   -  person bububaba    schedule 17.04.2012
comment
Я предполагаю, что @vascowhite имел в виду то, что вы передаете в качестве аргумента addElements()?   -  person Liyali    schedule 17.04.2012
comment
За исключением элементов, заимствованных из другой формы, это всегда array(new Zend_Form_Element_Xxx()). Только для заимствованных элементов $otherForm->getElements(). И теперь, когда я думаю об этом, я думаю, что это больше всего отличается от других форм, где все работает хорошо. Я просто не знаю, как это может повлиять.   -  person bububaba    schedule 17.04.2012


Ответы (1)


Я попытался воспроизвести вашу проблему с помощью этого кода: -

$formA = new Zend_Form();
$formB = new Zend_Form();
$formA->addElement(new Zend_Form_Element_Text('formA_text1'));
$formA->addElement(new Zend_Form_Element_Text('formA_text2'));
$formB->addElement(new Zend_Form_Element_Text('formB_text1'));
$formB->addElement(new Zend_Form_Element_Text('formB_text2'));

$formA->addElements($formB->getElements());
$formA->addElement(new Zend_Form_Element_Text('formA_text3'));
$formA->addElement(new Zend_Form_Element_Submit('submit'));
echo $formA->render();

Что дало мне этот результат (декораторы удалены)

<input type="text" name="formA_text1" id="formA_text1" value="">
<input type="text" name="formA_text2" id="formA_text2" value="">
<input type="text" name="formB_text1" id="formB_text1" value="">
<input type="text" name="formB_text2" id="formB_text2" value="">
<input type="text" name="formA_text3" id="formA_text3" value="">
<input type="submit" name="submit" id="submit" value="submit">

Это то, чего вы ожидаете. Единственный способ воспроизвести вашу проблему - установить порядок элементов в $formB

$formA = new Zend_Form();
$formB = new Zend_Form();
$formA->addElement(new Zend_Form_Element_Text('formA_text1'));
$formA->addElement(new Zend_Form_Element_Text('formA_text2'));
$formB->addElement(new Zend_Form_Element_Text('formB_text1'));
$formB->addElement(new Zend_Form_Element_Text('formB_text2'));
$formB->getElement('formB_text2')->setOrder(10);
$formA->addElements($formB->getElements());
$formA->addElement(new Zend_Form_Element_Text('formA_text3'));
$formA->addElement(new Zend_Form_Element_Submit('submit'));
echo $formA->render();

Что дало мне этот результат

<input type="text" name="formA_text1" id="formA_text1" value="">
<input type="text" name="formA_text2" id="formA_text2" value="">
<input type="text" name="formB_text1" id="formB_text1" value="">
<input type="text" name="formA_text3" id="formA_text3" value="">
<input type="submit" name="submit" id="submit" value="submit">
<input type="text" name="formB_text2" id="formB_text2" value="">

Вот что вы получаете. Мне кажется, что вы должны установить порядок элементов в $otherForm.

person vascowhite    schedule 17.04.2012
comment
Большое спасибо за ваши усилия! Ваш вывод о том, что порядок должен быть указан где-то в $otherForm, согласуется с моим открытием, что если я удалю заимствованные элементы, то порядок будет правильным. Мое хакерское решение - setOrder() для каждого элемента индивидуально (мне пришлось сбросить addElements($otherForm->getElements()) и пойти с foreach()). А зачем использовать хакерское решение? Потому что я не мог найти ни setOrder() вызовов, ни 'order' => X свойств. Я принимаю ваш ответ, поскольку он кажется наилучшим из возможных, не сидя перед своей машиной разработчика;) - person bububaba; 17.04.2012