2009-03-08 16 views
4

J'essaie de créer un formulaire en utilisant le composant Zend_Form, mais le nombre d'éléments varie. Les informations pour chaque élément Zend_Form sont stockées dans une base de données (nom, options, validateurs, filtres, etc.).Chargement de modèles dans Zend_Form à l'aide de Zend Framework

L'application sur laquelle je travaille consiste à construire des enquêtes qui contiennent un nombre variable de questions. Chaque question est associée à différents tableaux de réponses. En fin de compte, mon but est de construire des tableaux de boutons radio/checkbox, dynamiquement, côté serveur.

Je suis à la recherche d'une jolie façon de générer mon formulaire, mais je ne suis pas sûr de la meilleure façon de charger le modèle dans le formulaire. Le modèle doit-il être chargé dans le contrôleur, puis passé (en quelque sorte, via un paramètre?) Directement au formulaire, ou est-il préférable de charger le modèle dans la méthode Form init()? Où est le meilleur endroit pour mettre la logique, devrait-il être dans la classe de formulaire, ou dans le contrôleur, ou dans le modèle?

Mon idée est d'extraire les propriétés des éléments de formulaire (nom, règles, filtres, etc.) dans la base de données, puis de parcourir et de restituer le formulaire. Que pensez-vous de cette approche? En fin de compte, les éléments seront ajoutés dynamiquement (côté client), cette fois, en utilisant AJAX et une bibliothèque JavaScript (comme jQuery).

Voici quelques liens utiles que j'ai trouvé via Google, mais je pense tous répondre à une question légèrement différente de la mienne:

Sur la construction de formes dynamiques, côté serveur:

Sur la construction de formes dynamiques, côté client, avec traitement AJAX:

Répondre

2

Vous pouvez étendre Zend_Form.

La forme Zend n'est pas un bon endroit pour la logique, seule la représentation de forme. Par conséquent, chargez tous les éléments nécessaires à l'aide du modèle dans le contrôleur et transmettez-les à la forme dans le constructeur en tant que paramètres.

4

Je pense avoir trouvé une solution, il consiste à faire passer un tableau de éléments Zend Form au formulaire Zend :: __ construct() méthode. Le constructeur prend un tableau d'options, l'un d'eux est appelé "éléments". Regardez le code source dans la bibliothèque Zend Framework.

J'ai codé une nouvelle méthode privée dans le contrôleur, appelée buildSurveyForm(). Remarque: l'objet, passé en paramètre, est construit à partir d'une énorme requête SQL avec une demi-douzaine d'instructions JOIN, récupérant des données de quelques tables (enquêtes, questions, réponses, etc.) dans la base de données. L'un des attributs publics de cette classe consiste en une série de questions, stockées en tant qu'objets (avec des méthodes/attributs publics, etc.). Pareil pour les réponses. Le code pour construire ces classes est assez trivial et hors sujet ici.

Voici le code dans le contrôleur de levé.Je copier/coller et édité/abandonné quelques lignes pour le rendre beaucoup plus clair:

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

Le MyApp formulaire d'enquête classe contient uniquement un bouton Soumettre dans la méthode init(). Les éléments générés dynamiquement avec le code ci-dessus sont ajoutés AVANT ce bouton d'envoi (ce qui est inattendu, mais utile). Cette classe étend simplement Zend_Form.

Ensuite, dans le contrôleur enquête/action de la vue:

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

filtres Ajout, validateurs et décorateurs pour former des éléments est maintenant trivial. Ma proposition est un peu sale, mais je pense que le travail est fait. Je vais ajouter une nouvelle proposition si je trouve quelque chose de plus élégant. N'hésitez pas à poster différentes réponses/solutions.

+0

wow, c'est quelque chose que je cherchais partout. Heads up mate pour partager cette logique. –