2010-10-06 25 views
2

Cela peut sembler un scénario étrange, mais j'ai deux formulaires sur une page. L'un est en train de poster sur lui-même. J'ai fait le deuxième message à une autre action pour garder le code plus propre. Le problème n'est peut-être pas le bon ...Zend Framework: Publier une action différente puis revenir à l'action d'origine si la validation échoue ET conserver les champs de formulaire

Le problème que j'ai maintenant est que si cette deuxième forme ne valide pas, je redirige vers la page avec le formulaire mais je ne sais pas comment garder ma forme champs remplis avec les informations d'origine que l'utilisateur a saisies. Existe-t-il un moyen de le faire et de continuer à poster deux actions distinctes, ou dois-je juste mordre la balle et faire en sorte que les deux formulaires reviennent à la même action et traitent la logique désordonnée?

Répondre

3

Je soumettrais les deux formes à la même action. Il ne devrait vraiment pas y avoir quelque chose de trop compliqué à ce sujet. Dans chaque formulaire inclure un champ caché pour signifier quel formulaire est soumis.

Application_Form_Login:

/* other form elements */ 
$this->addElement('hidden', 'login', array(
     'value' => 1 
)); 

Application_Form_Register:

/* other form elements */ 
$this->addElement('hidden', 'register', array(
     'value' => 1 
)); 

Controller:

$loginForm = new Application_Form_Login(); 
$registerForm = new Application_Form_Register(); 

if($this->_request->isPost()) { 
    if($this->_request->getPost('login')) { 
     if($loginForm->isValid($this->_request->getPost())) { 
      // validated, redirect 
      $this->_helper->redirector('profile', 'user'); 
     } 
    } 
    if($this->_request->getPost('register')) { 
     if($registerForm->isValid($this->_request->getPost())) { 
      // validated, proceed as needed 
     } 
    } 
} 

$this->view->loginForm = $loginForm; 
$this->view->registerForm = $registerForm; 

Vue:

echo $this->loginForm; 

echo $this->registerForm; 

Avec ce type de configuration, si l'un de vos formulaires échoue à la validation, isValid() conservera toutes les données qui ont été saisies et vous redirigerez toujours sur la validation réussie d'un ou des deux formulaires.

+0

L'hypothèse que vous faites, et c'est ma faute parce que je n'étais pas clair, c'est que ces formulaires ne contiennent pas de données pour commencer. L'utilisation d'un exemple de formulaire de connexion/enregistrement est logique dans votre scénario. Cependant, dans ma situation, ce sont des formulaires qui sont déjà pré-remplis avec des données. Ainsi, au lieu de rediriger, ils afficheront toujours la page d'origine à nouveau après le traitement. Ça ne complique pas trop les choses, mais c'est une différence. –

+0

Ah, ça le clarifie un peu. Si les deux formulaires sont affichés sur la même page, il semble tout à fait logique de garder les actions dirigées vers le même contrôleur. Je pense que j'ai déjà rencontré ce même problème auparavant, et jongler entre les données par le biais d'un autre contrôleur et revenir à l'ancien me semblait être plus compliqué pour moi. – Lee

0

Comment redirigez-vous? Je ne vois pas le problème si vous affichez à nouveau la page de formulaire. Vous pouvez pré-remplir vos formulaires en utilisant Zend_Form :: populate().

+0

On dirait que je n'ai pas bien lu vos questions. Je dirais que le moyen le plus propre est de poster à la même action. Tout le reste compliquerait le code de votre contrôleur. – BlueDog

+0

Je ne redirige pas. Je veux afficher à nouveau la même page. Je pense que je devrais juste pré-remplir le formulaire (comme vous le suggérez) qui n'est pas soumis puis laisser Zend Form faire son truc pour garder les champs de formulaire modifiés sur le formulaire qui a été soumis. –

1

Personnellement, je pense que chaque formulaire devrait poster sur son propre contrôleur, comme vous l'avez fait. Cela conserve le code pour le traitement de ce formulaire dans un seul endroit. Le problème ici est que vous voulez revenir à la page d'origine en cas de validation échouée. Mais pourquoi? Pourquoi ne pas simplement réafficher le formulaire dans le contrôleur cible, comme vous le feriez s'il y avait un seul formulaire sur la page? Par exemple, considérez un formulaire de connexion qui apparaît sur chaque page d'un dossier (peut-être parce qu'il se trouve dans le modèle/la mise en page du site). Il poste à quelque chose comme AuthController::loginAction(). Si la connexion échoue, vous ne le renvoyez généralement pas à la page d'où il vient. Vous le laissez à la page de connexion, avec le formulaire comme pré-rempli du $_POST comme vous le souhaitez (probablement un nom d'utilisateur, mais pas son mot de passe).

Voir this answer pour une discussion similaire.

Mise à jour: Avait une autre idée dans ce. Si vous voulez vraiment gérer le traitement dans deux contrôleurs différents afin de le garder sur la page à partir de laquelle il a posté le formulaire, au moins extraire ce traitement de formulaire dans un action helper. De cette façon, vous pouvez au moins conserver ce traitement de formulaire DRY.

Mise à jour: Rob Allen vient d'écrire un billet de blog "A form in your layout" dans lequel il décrit une méthode qui utilise une action auxiliaire avec une méthode preDispatch() qui instancie et traite la forme. Très agréable.

+0

Voir mon commentaire pour le poste ci-dessus de pourquoi je ré-afficher la page d'origine à nouveau. –

0

Eh bien, je voudrais simplement garder les deux formulaires soumis sur la même page.

Je ne vois pas pourquoi votre code devrait être moins lisible. Apprenez à utiliser les aides d'action et vos contrôleurs regarderont soudainement extrêmement simple et lisible:

public function indexAction() 
{ 
    $request = $this->getRequest(); 

    // send forms to view, so we can print them 
    // but also so we can access them in action helpers 
    $this->view->form = $this->_getForm('Form1', '/'); 
    $this->view->form2 = $this->_getForm('Form2', '/'); 

    if ($request->isPost()) 
    { 
     // process the first form 
     if (isset($_POST['form_submit_button']) && $this->view->form->isValid($_POST)) 
     { 
      $this->_helper->form($this->view->form->getValues()); 
     } 
     // process the second form 
     else if (isset($_POST['form2_submit_button']) && $this->view->form2->isValid($_POST)) 
     { 
      $this->_helper->form2($this->view->form2->getValues()); 
     } 
} 

de traitement de chaque forme aurait son propre aide d'action.

+0

N'est-ce pas l'un des principaux points de la création d'une aide à l'action client pour permettre la réutilisation du code - vous avez donc quelque chose que vous pouvez utiliser dans de nombreux contrôleurs? Dans cette situation, je peux voir comment cela décluterait le code, mais je pourrais vraiment le faire en créant simplement une fonction d'aide dans mon contrôleur. Peut-être que je ne comprends pas cela correctement. –

+0

Eh bien, oui. Mais il est toujours préférable d'avoir des contrôleurs simples et de déplacer une certaine logique d'application vers des helpers d'action (plus assurez-vous d'avoir toute la validation en dehors des contrôleurs, étendez Zend_Form, vous pouvez aussi écrire des validateurs personnalisés si nécessaire). J'utilise souvent des contrôleurs d'action comme ça parce que dans certaines applications j'ai participé à des tâches compliquées dans certaines actions de contrôleurs (nous avions beaucoup d'actions avec plus de 300 lignes de code même après avoir délégué beaucoup de logique à des bibliothèques tierces ou nos propres classes) et nous devions juste les rendre plus lisibles ... –

+0

... pour des raisons de maintenabilité. De plus, ce n'est pas si mal en cas de manipulation de formulaire car rien ne dit qu'un formulaire apparaîtra dans votre application une seule fois. Il pourrait y avoir des formulaires qui seront utilisés dans plus de contrôleurs ou même des formulaires à l'échelle du site qui seront utilisés à travers des modules entiers (comme le formulaire de recherche, le formulaire de connexion), ce n'est donc pas si mal. –