Pregunta

Estoy intentando crear un formulario utilizando el componente Zend_Form, pero la cantidad de elementos varía. La información de cada elemento Zend_Form se almacena en una base de datos (nombre, opciones, validadores, filtros, etc.).

La aplicación en la que estoy trabajando consiste en crear encuestas que contienen un número variable de preguntas. Cada pregunta está asociada a diferentes matrices de respuestas. En última instancia, mi objetivo es crear matrices de botones de radio / casilla de verificación, dinámicamente, del lado del servidor.

Estoy buscando una forma bonita de generar mi formulario, pero no estoy seguro de cuál es la mejor manera de cargar el modelo dentro del formulario. ¿Se debe cargar el modelo en el controlador y luego pasar (de alguna manera, a través de un parámetro?) Directamente al formulario, o es mejor cargar el modelo dentro del método Form init ()? ¿Dónde está el mejor lugar para colocar la lógica, debería estar dentro de la clase de formulario, dentro del controlador o dentro del modelo?

Mi idea es obtener las propiedades del elemento del formulario (nombre, reglas, filtros, etc.) en la base de datos, luego iterar y finalmente representar el formulario. Que piensas de esta aproximación? En última instancia, los elementos se agregarán dinámicamente (del lado del cliente), esta vez, utilizando AJAX y una biblioteca de JavaScript (como jQuery).

Aquí hay un par de enlaces útiles que encontré a través de Google, pero creo que todos responden a una pregunta ligeramente diferente a la mía:

En la creación de formularios dinámicos, servidor:

En la creación de formularios dinámicos, del lado del cliente, con procesamiento AJAX:

¿Fue útil?

Solución

Podrías extender Zend_Form.

La forma Zend no es un buen lugar para la lógica, solo forma la representación.

Entonces, cargue todos los elementos necesarios usando el modelo en el controlador y páselos al formulario en el controlador como parámetros.

Otros consejos

Creo que encontré una posible solución, implica pasar una matriz de elementos de Zend Form al Zend Form :: __ construct () . El constructor toma una serie de opciones, una de ellas se llama "elementos " ;. Eche un vistazo al código fuente dentro de la biblioteca de Zend Framework.

Codifiqué un nuevo método privado dentro del controlador, llamado buildSurveyForm (). Nota: el objeto, pasado como un parámetro, se construye a partir de una gran consulta SQL con media docena de declaraciones de JOIN, obteniendo datos de algunas tablas (encuestas, preguntas, respuestas, etc.) dentro de la base de datos. Uno de los atributos públicos para esta clase consiste en una serie de preguntas, almacenadas como objetos (también con métodos / atributos públicos, etc.). Lo mismo para las respuestas. El código para construir estas clases es bastante trivial y está fuera de tema aquí.

Aquí está el código dentro del controlador de encuesta. Copié / pegué y edité / solté algunas líneas para que sea mucho más claro:

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'];
}

La clase Formulario de encuesta de MyApp solo contiene un botón Enviar dentro del método init (). Los elementos generados dinámicamente con el código anterior se agregan ANTES de este botón de envío (lo cual es inesperado, pero útil). Esta clase simplemente extiende Zend_Form.

Luego, dentro del controlador de encuesta / ver acción:

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,
    ));
}

Añadir filtros, validadores y decoradores para formar elementos ahora es trivial. Mi propuesta está un poco sucia, pero creo que hace el trabajo. Añadiré una nueva propuesta si encuentro algo más elegante. Siéntase libre de publicar diferentes respuestas / soluciones.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top