Foros del Web

Foros del Web (http://www.forosdelweb.com/)
-   Zend (http://www.forosdelweb.com/f182/)
-   -   Formulario -> Proceso -> Resultado (http://www.forosdelweb.com/f182/formulario-proceso-resultado-885794/)

jerkan 14/02/2011 02:52

Formulario -> Proceso -> Resultado
 
Hola,

¿alguien sabría decirme cómo se puede implementar en Zend Framework la arquitectura clásica de formulario > proceso > resultado (las tres, páginas diferentes) de manera que el formulario reciba los datos necesarios para mostrar posibles errores?

Busqué por internet pero 'todo' el mundo hace el proceso en la misma página que el formulario. De esta manera, si el usuario actualiza la página aparece la horrible ventana de 'se van a volver a enviar datos' que no quiero que salga.

Gracias.

masterpuppet 14/02/2011 03:26

Respuesta: Formulario -> Proceso -> Resultado
 
No entiendo muy bien tu problema jerkan, si hay errores en el formulario se renderiza con los errores y en caso de contrario redirigiendo se soluciona tu problema, igualmente podes tener 3 action's diferentes, uno para mostrar el form, otro sin vista para procesar los datos y otro para mostar el resultado.

Saludos.

jerkan 14/02/2011 03:39

Respuesta: Formulario -> Proceso -> Resultado
 
Cita:

Iniciado por masterpuppet (Mensaje 3744334)
No entiendo muy bien tu problema jerkan, si hay errores en el formulario se renderiza con los errores y en caso de contrario redirigiendo se soluciona tu problema, igualmente podes tener 3 action's diferentes, uno para mostrar el form, otro sin vista para procesar los datos y otro para mostar el resultado.

Saludos.

Pero, ¿cómo pasas los datos necesarios a la página 'formulario' dese la página 'proceso'?

masterpuppet 14/02/2011 03:50

Respuesta: Formulario -> Proceso -> Resultado
 
Envia el post a proceso, en proceso evaluas y bien redirigis a resultado o volves al formulario mostrando los errores.

jerkan 14/02/2011 04:03

Respuesta: Formulario -> Proceso -> Resultado
 
Cita:

Iniciado por masterpuppet (Mensaje 3744358)
Envia el post a proceso, en proceso evaluas y bien redirigis a resultado o volves al formulario mostrando los errores.

Esa es la idea. Pero, ¿cómo se pasan los errores al formulario con los métodos del Zend Framework?

masterpuppet 14/02/2011 04:31

Respuesta: Formulario -> Proceso -> Resultado
 
Setea los datos y dispara el isValid, esta es la razón por la cual siempre se hace sobre el mismo action, lo que no entiendo es porque no redirigis a resultado cuando todo es correcto y listo, saltar de action en action tiene sentido en un multipage form.

jerkan 14/02/2011 04:42

Respuesta: Formulario -> Proceso -> Resultado
 
Redirigir a 'resultado' no es el problema.

O yo no me explico o tu no me entiendes :P

masterpuppet 14/02/2011 05:27

Respuesta: Formulario -> Proceso -> Resultado
 
Cita:

Iniciado por jerkan (Mensaje 3744392)
Redirigir a 'resultado' no es el problema.

O yo no me explico o tu no me entiendes :P

Te lo aclare en el primer post que no te entendia muy bien :-).
Voy de nuevo, en proceso si hay errores guarda el post en un Zend_Session_Namespace y en formulario, comproba que exista el namespace, si este existe, llamas a Zend_Form::isValid con los datos del namespace(osea los datos del post).
Si no lo ves, te hago un ejemplo basico.

Saludos.

jerkan 14/02/2011 05:38

Respuesta: Formulario -> Proceso -> Resultado
 
Pongo un poco de código para ver si así me explico mejor.
Código PHP:

    public function signAction() 
    { 
        
$request $this->getRequest(); 
        
$form = new Application_Form_Guestbook(); 
        
$form->setAction(Zend_Controller_Front::getInstance()->getBaseUrl() . '/guestbook/process'); 
         
        
Zend_Session::start(); 
        
$session = new Zend_Session_Namespace('guestbook'); 
         
        
// check session stored errors 
        
if ($session->errors) { 
 
            
// add error messages to form 
            
$form->setErrors($session->errors); 
            
$form->populate($session->data); 
             
            
// unset session vars 
            
unset($session->data); 
            unset(
$session->errors); 
        } 
        
$this->view->form $form
    } 
 
 
    public function 
processAction() 
    { 
        
$request $this->getRequest(); 
        
$form = new Application_Form_Guestbook(); 
         
        if (
$request->isPost()) { 
            if (
$form->isValid($request->getPost()) === false) { 
 
               
Zend_Session::start(); 
               
$session = new Zend_Session_Namespace('guestbook'); 
               
$session->data $request->getPost(); 
               
$session->errors $form->getErrors(); 
 
            } 
        } 
        return 
$this->_helper->redirector->gotoSimple('sign'); 
    } 

En el action 'sign' es dónde se muestra el formulario. Pero, además, quiero mostrar errores si se han producido en el 'process'.
En el action 'process' es dónde se llama al conocido método isValid. Lo que estoy intentando ahí es guardar los errores en una variable sesión. Luego, en 'sign' le paso al formulario los errores guardados en sesión.

Esta aproximación no funciona de igual manera que si tuviera el formulario y el proceso en el mismo action.

masterpuppet 14/02/2011 06:13

Respuesta: Formulario -> Proceso -> Resultado
 
Ves, con codigo la gente se entiende mejor :-), deberia ser algo asi:

Bootstrap.php
Código PHP:
Ver original
  1. public function _initSession()
  2. {
  3.     Zend_Session::start(); 
  4. }

por recomendacón de Zend, cuando manipulas sesiones, el start debe ir en el bootstrap(para evitar errores)

TuController.php
Código PHP:
Ver original
  1. public function signAction()
  2. {
  3.     $form = new Application_Form_Guestbook();
  4.     $form->setAction(Zend_Controller_Front::getInstance()->getBaseUrl() . '/guestbook/process');
  5.     if(Zend_Session::namespaceIsset('formErrors')) {
  6.         $ns = new Zend_Session_Namespace('formErrors');
  7.         $form->isValid($ns->data);
  8.     }        
  9.     $this->view->form = $form;
  10. }
  11.  
  12. public function processAction()
  13. {
  14.     if (!$this->_request->isPost()) {
  15.         $this->_helper->redirector->gotoSimple('index');
  16.     }
  17.     $form = new Application_Form_Guestbook();
  18.     $post = $this->_request->getPost();                  
  19.     if (!$form->isValid($post)) {                
  20.         $ns = new Zend_Session_Namespace('formErrors');
  21.         $ns->setExpirationHops(1);
  22.         $ns->data = $post;
  23.         $this->_helper->redirector->gotoSimple('sign');
  24.     }
  25.     //do something
  26.     ...
  27.     $this->_helper->redirector->gotoSimple('result');
  28. }

que diferencia tenes a hacer algo como esto ?

Código PHP:
Ver original
  1. public function signAction()
  2. {      
  3.     $form = new Application_Form_Guestbook();
  4.     if($this->_request->isPost() &&
  5.         $form->isValid($this->_request->getPost())){
  6.         //do something
  7.        ...
  8.        $this->_helper->redirector->gotoSimple('result');  
  9.     }
  10.     $this->view->form = $form;        
  11. }

jerkan 14/02/2011 06:50

Respuesta: Formulario -> Proceso -> Resultado
 
Cita:

Iniciado por masterpuppet (Mensaje 3744454)
que diferencia tenes a hacer algo como esto ?

Código PHP:
Ver original
  1. public function signAction()
  2. {      
  3.     $form = new Application_Form_Guestbook();
  4.     if($this->_request->isPost() &&
  5.         $form->isValid($this->_request->getPost())){
  6.         //do something
  7.        ...
  8.        $this->_helper->redirector->gotoSimple('result');  
  9.     }
  10.     $this->view->form = $form;        
  11. }

El problema con esa solución es que si se ha producido un error, se mostrará el formulario de nuevo con los errores y, entonces, si el usuario actualiza la página saldrá la ventana de aviso del navegador explicándole que se van a volver a enviar datos. Esa es la ventana que quiero prevenir.

masterpuppet 14/02/2011 07:31

Respuesta: Formulario -> Proceso -> Resultado
 
Ahora si entendi lo que querias evitar, dios que estoy leeeento :Zzz:, pudiste adaptar el codigo anterior, te sirvio ?

Saludos.

jerkan 14/02/2011 07:47

Respuesta: Formulario -> Proceso -> Resultado
 
Cita:

Iniciado por masterpuppet (Mensaje 3744513)
Ahora si entendi lo que querias evitar, dios que estoy leeeento :Zzz:, pudiste adaptar el codigo anterior, te sirvio ?

Saludos.

No, todavía no. Luego a la noche lo pruebo.

Muchas gracias :arriba:

jerkan 15/02/2011 09:41

Respuesta: Formulario -> Proceso -> Resultado
 
Lo probé y me resultó a medias.

Sé que esa solución tiene un punto negativo y es que, en caso de errores, se valida el formulario dos veces.

Pero lo que no es aceptable es el error que da del campo csrf. Yo entiendo el por qué ocurre (cuando se valida por segunda vez, el valor que tenía el campo csrf no corresponde con el nuevo valor) pero no se me ocurre una manera de evitarlo.

¿Alguna idea?

masterpuppet 15/02/2011 11:05

Respuesta: Formulario -> Proceso -> Resultado
 
A ver esta es una versión mejorada,

Código PHP:
Ver original
  1. public function signAction()
  2. {
  3.     $form = new Application_Form_Guestbook();
  4.     $form->setAction(Zend_Controller_Front::getInstance()->getBaseUrl() . '/guestbook/process');
  5.     if(Zend_Session::namespaceIsset('formErrors')) {
  6.         $ns = new Zend_Session_Namespace('formErrors');
  7.         foreach($ns->errors as $field => $errors) {
  8.             $form->getElement($field)->addErrors($errors);             
  9.         }
  10.     }        
  11.     $this->view->form = $form;
  12. }
  13.  
  14. public function processAction()
  15. {
  16.     if (!$this->_request->isPost()) {
  17.         $this->_helper->redirector->gotoSimple('index');
  18.     }
  19.     $form = new Application_Form_Guestbook();
  20.     if (!$form->isValid( $this->_request->getPost())) {                
  21.         $ns = new Zend_Session_Namespace('formErrors');
  22.         $ns->setExpirationHops(1);
  23.         $ns->errors = $form->getMessages();
  24.         $this->_helper->redirector->gotoSimple('sign');
  25.     }
  26.     //do something
  27.     ...
  28.     $this->_helper->redirector->gotoSimple('result');
  29. }

Saludos.

jerkan 17/02/2011 09:27

Respuesta: Formulario -> Proceso -> Resultado
 
Funciona! Y encima no se valida el formulario dos veces!

Muchas gracias!


La zona horaria es GMT -6. Ahora son las 19:11.

Desarrollado por vBulletin® Versión 3.8.7
Derechos de Autor ©2000 - 2024, Jelsoft Enterprises Ltd.