2009-03-08 5 views
4

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

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

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

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

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

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

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

ответ

2

Вы можете расширить Zend_Form.

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

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

4

Я думаю, что я нашел возможное решение, оно включает в себя передачу массива Zend Form элементов к Zend Form :: __ конструкт() метода. Конструктор принимает набор параметров, один из которых называется «элементов». Посмотрите исходный код в библиотеке 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 Форма обследования класс содержит только кнопку Submit в рамках метода 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, 
    )); 
} 

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

+0

Вау, это то, что я искал повсюду. Направляет помощника для обмена этой логикой. –