Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Salut,
je cherche, comme font pas mal de monde, à faire une redirection sous Ajax.
Exemple, le formulaire de connexion. Celui-ci est géré en ajax. Si le compte n'a pas été trouvé, j'affiche un message d'erreur sous le formulaire, autrement je souhaite rediriger l'utilisateur vers une page membre par exemple. Mais avec Ajax ça foire, car c'est le contenu de la page de redirection qui s'affiche a la place du message d'erreur. Et donc j'aimerais pouvoir forcer la direction dans le navigateur. Je ne sais pas si je m'exprime bien ce soir ?
Merci,
Dernière modification par Cidrolin (30-10-2008 18:49:22)
Hors ligne
Bonsoir,
Si tu charges la vue qui contient le formulaire de connexion dans une div ou autre grâce à une XmlHttpRequest(), tu dois gérer la redirection en javascript.
Donc,
Soit tu gères le contexte dans ton controller, c'est à dire que tu passes à l'url de ta requête ajax, le paramètre "format=xml" (voir la doc), et une vue "truc.xml.phtml" dans laquelle tu fais ta redirection en javascript.
Soit tu utilises la fonction isXmlHttpRequest de l'objet _request pour tester si tu viens d'une requête Ajax et tu renvoies un echo en réponse, que tu gères ensuite côté javascript.
dans tous les cas, ce sera un "top.location.replace()", le top permettant de charger la page demandée dans le parent le plus haut au niveau du client.
Exemple avec les contextes :
Controller
function init() { $this->initView(); $this->view->baseUrl = $this->_request->getBaseUrl(); $contextSwitch = $this->_helper->getHelper('contextSwitch'); $contextSwitch->addActionContext('truc', 'xml') ->initContext(); } function trucAction() { // le traitement // puis la vue truc.xml.phtml est rendue }
Exemple avec test de la requête :
function trucAction() { // le traitement // Je ne suis pas sur que cette méthode fonctionne correctement // dans certains cas il risque d'essayer de charger la vue quand même // Perso je préfère utiliser les contextes. Pe le NoRender à placer dans l'init() if ($this->getRequest()->isXmlHttpRequest()) { // Si erreurs echo du/des message(s) d'erreur // Sinon $this->_helper->viewRenderer->setNoRender(); echo 'OK'; } }
Requête Ajax
function jsSendRequest(pUrl, pParams, pForm, pContext, pRedirect) { var eval; var context; var redirect; redirect = pRedirect || false; context = (pContext) ? '?format='+pContext : ''; eval = (pContext) ? true : false; var myAjax = new Ajax.Request ( pUrl + context, { method: "post", evalScripts: eval, parameters : pForm.serialize(true), onLoading : function () { new LoadingIndicator.base({pic:'ajax-loading.gif'}); }, onComplete: function transResult (response) { LoadingIndicator.hideAll(); if (response.responseText == 'OK') { if (pRedirect) { top.location.replace(pRedirect); } //traitement } else { // erreur var error = response.responseText; // traitement } } } ); return false; }
Il faut vérifier la requête Ajax, j'ai peut-être fait une erreur de syntaxe en l'écrivant. Et évidemment certainement l'améliorer, elle n'est peut-être pas à utiliser dans l'état, c'est un exemple.
A+ benjamin.
Dernière modification par Delprog (30-10-2008 19:58:21)
Hors ligne
Salut,
merci pour ta réponse. Je suis donc obligé de passer par JS. Je pensais qu'il y aurait pu y avoir un composant magique Zend pour outrepasser ça ou bien simplement un helper intégré permettant de faire une redirection JS. A présent tout marche, merci.
Hors ligne
Bonjour
Désolé d'upper ce vieux topic, mais j'ai une question relative à celle de Cidrolin. J'ai essayé d'ajouter un peu de Javascript à mon formulaire d'inscription, en utilisant Prototype. Tout cela fonctionne très bien : si je détecte des erreurs (via la fonction processAjax de Zend_Form), je n'envoie pas le formulaire, je ne fais qu'ajouter des erreurs dans le code HTML. Si au contraire il n'y a aucune erreur, j'envoie le formulaire.
J'ai donc au début bêtement effectué un Ajax.Request avec les données de mon formulaire, en espérant que l'action du contrôleur puisse faire la redirection, avant de me rendre compte que ce n'est pas possible.
Mais c'est un peu gênant car mon code Javascript pour gérer les formulaires est relativement générique, or en faisant la redirection dans le code Javascript, je suis OBLIGE de connaître la page vers laquelle je souhaite rediriger, qui est différente d'un formulaire à l'autre. N'y a t-il donc aucun moyen de gérer ça de manière un peu plus propre ?
Voici le code de mon contrôleur (j'utilise AjaxContext). Dans le code Javascript il faut regarder la fonction checkForm, qui effectue la redirection. Comme vous voyez cela m'impose d'écrire explicitement que je souhaite rediriger vers register-complete. L'idéal aurait été de pouvoir initier une redirection vers registerAction (car je connais cette adresse à travers this.register.action), en envoyant des variables POST. Mais je ne sais pas s'il est possible d'envoyer des variables post avec une redirection JS.
// Initialisation du contrôleur public function init() { $this->request = $this->getRequest(); // Définit les actions pouvant recevoir des requêtes AJAX $this->ajaxContext = $this->_helper->getHelper('AjaxContext'); $this->ajaxContext->addActionContext('register', 'json') ->initContext(); } // Crée un nouvel utilisateur public function registerAction() { $form = new Default_Form_AccountRegister(); if ($this->request->isPost()) { // S'il s'agit d'une requête AJAX, on retourne les messages d'erreurs dans le format JSON switch ($this->ajaxContext->getCurrentContext()) { case 'json': $this->view->result = $form->processAjax($this->request->getPost()); return; default: if ($form->isValid($this->request->getPost())) { $userMapper = new Default_Model_UserMapper(); $user = new Default_Model_User($form->getValues()); $userMapper->insert($user); // On finalise l'inscription $session = new Zend_Session_Namespace('registerComplete'); $session->email = $user->email; $this->_helper->redirector('register-complete'); } } } // Variables de vue $this->view->form = $form; }
Et une partie du code Javascript :
var CustomForm = Class.create({ initialize: function(name) { this.form = $(name); this.setObservers(); }, setObservers: function() { this.form.observe('submit', this.onSubmit.bind(this)); }, onSubmit: function(event) { event.stop(); var options = {method: 'post', parameters: {format: 'json'}, onSuccess: this.checkForm.bind(this)}; this.form.request(options); }, checkForm: function(transport) { var response = transport.responseJSON; if (response.result == 'true') { this.form.request({method: 'post'}); top.location.href = '/account/register-complete'; } else //this.showErrors(response).bind(this); } });
Merci de votra die
Dernière modification par bakura (20-02-2010 11:33:54)
Hors ligne