Вопрос

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

Приложение, над которым я работаю, состоит из опросов зданий, которые содержат различное количество вопросов.Каждый вопрос связан с различными массивами ответов.В конечном счете, моя цель - динамически создавать массивы кнопок радио / чекбокса на стороне сервера.

Я ищу красивый способ сгенерировать свою форму, но я не уверен в лучшем способе загрузки модели в форму.Должна ли модель загружаться в контроллер, а затем передаваться (каким-то образом, через параметр?) непосредственно в форму, или лучше загрузить модель с помощью метода Form init()?Где лучше всего разместить логику, должна ли она быть внутри класса form, или внутри контроллера, или внутри модели?

Моя идея состоит в том, чтобы извлечь свойства элемента формы (имя, правила, фильтры и т.д.) Из базы данных, затем выполнить итерацию и, наконец, отобразить форму.Что вы думаете о таком подходе?В конечном счете элементы будут добавлены динамически (на стороне клиента), на этот раз с использованием AJAX и библиотеки JavaScript (такой как jQuery).

Вот пара полезных ссылок, которые я нашел через Google, но я думаю, что все они отвечают на несколько иной вопрос, чем мой:

О создании динамических форм на стороне сервера:

О создании динамических форм на стороне клиента с обработкой AJAX:

Это было полезно?

Решение

Вы могли бы расширить Zend_Form .

Zend form - неподходящее место для логики, только для представления формы.

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

Другие советы

Я думаю, что я нашел возможное решение, оно включает в себя передачу массива Элементы формы Zend к тому Форма Zend::__construct() способ.Конструктор принимает массив параметров, один из которых называется "элементы".Взгляните на исходный код в библиотеке Zend Framework.

Я закодировал новый закрытый метод внутри контроллера, называемый buildSurveyForm().Примечание :объект, передаваемый в качестве параметра, создается на основе огромного SQL-запроса с полудюжиной операторов JOIN, извлекающих данные из нескольких таблиц (опросы, вопросы, ответы и т.д.) в базе данных.Один из общедоступных атрибутов для этого класса состоит из массива вопросов, хранящихся в виде объектов (также с общедоступными методами / атрибутами и т.д.).То же самое и с ответами.Код для создания этих классов довольно тривиален и не соответствует теме здесь.

Вот код внутри контроллера опроса.Я скопировал / вставил и отредактировал / убрал несколько строк, чтобы сделать это намного понятнее :

private function buildSurveyForm(MyApp_Object_Survey $survey)
{
    foreach ($survey->questions as $question)
    {
        $element = new Zend_Form_Element_MultiCheckbox($question->order);
        $element->addMultiOptions($question->getAnswersLabels());
        $element->setName($question->order);
        $element->setLabel($question->title);

        $elements[] = $element;
    }

    // Here's the trick :
    $formOptions = array('elements' => $elements);

    $surveyForm = new MyApp_Survey_Form($formOptions);

    $urlHelper = $this->_helper->getHelper('url');
    $surveyForm->setAction($urlHelper->url(array(
            'controller' => 'survey',
            'action' => 'vote'),
        'default'
    ));
    $surveyForm->setMethod('post');

    $this->_forms['survey'] = $surveyForm;

    return $this->_forms['survey'];
}

В Форма опроса MyApp класс содержит только кнопку Отправки в методе init().Динамически сгенерированные элементы с приведенным выше кодом добавляются ПЕРЕД этой кнопкой отправки (что неожиданно, но полезно).Этот класс просто расширяет Zend_Form.

Затем, в рамках действия контроллера опроса / просмотра :

public function viewAction()
{
    $surveyModel =    $this->_model['survey'];
    $survey =        $surveyModel->getFullSurvey($this->_getParam('id'));
    $survey =        new MyApp_Object_Survey($survey);
    // Calls above private method :
    $surveyForm =    $this->buildSurveyForm($survey);

    $this->view->assign(array(
         'surveyForm' => $surveyForm,
    ));
}

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top