Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Bonjour à tous,
je rencontre une difficulté que je peine à surmonter, alors je viens ici en quête d'un coup de main
Présentation de mon code
J'affiche à l'écran un formulaire via une requête ajax: ce formulaire est en partie constitué de listes déroulantes enrichies grâce au plugin JQuery "Chosen" (http://harvesthq.github.io/chosen/).
Voici l'aide de vue associée à cet élément de formulaire (à noter que l'aide de vue se charge d'ajouter les fichiers de la librairie Chosen au container jQuery):
[lang=php]<?php require_once "ZendX/JQuery/View/Helper/UiWidget.php"; class Evz_JQuery_View_Helper_ChosenSelect extends ZendX_JQuery_View_Helper_UiWidget { /** * Ensure ressources are only registered once * @var bool */ protected $_ressourcesAreRegistered = false; /** * chosenSelect() * * @todo Minimiser les scripts css et js * @todo Implémenter l'événement RESET * @link http://harvesthq.github.com/chosen/ * @tutorial available options: allow_single_deselect / disable_search_threshold / no_results_text / width * @param string $id * @param mixed $value * @param array $attribs * @param string $options * @param string $listsep * @return string */ public function chosenSelect($id, $value = null, array $attribs = array(), $options = null, $listsep = '<br />\n') { if ( ! $this->_ressourcesAreRegistered ) { $this->jquery->addJavascriptFile($this->view->baseUrl() . $this->jquery->pluginPath . '/chosen/chosen.jquery.min.js') ->addStylesheet($this->view->baseUrl() . $this->jquery->pluginPath . '/chosen/chosen.css'); $this->_ressourcesAreRegistered = true; } $id = $this->_normalizeId($id); $params = array(); if ( isset($attribs['jQueryParams']) ) { $params = $attribs['jQueryParams']; unset($attribs['jQueryParams']); } $this->jquery->addOnLoad(sprintf( '%s("#%s").chosen(%s);', ZendX_JQuery_View_Helper_JQuery::getJQueryHandler(), $id, ZendX_JQuery::encodeJson($params) )); if ( array_key_exists('options', $attribs) ) $options = $attribs['options']; if ( array_key_exists('listsep', $attribs) ) $listsep = $attribs['listsep']; return $this->view->formSelect($id, $value, $attribs, $options, $listsep); } }
Du côté du controller, voici de quelle manière est servie le formulaire (il s'agit de l'action "fabrique" qui peut-être appelée avec ou sans ajax, d'où l'usage de l'aide d'action "AjaxContext"):
[lang=php] <?php class Commun_ModeleController extends Zend_Controller_Action { /** * AjaxContext Helper * * @var Zend_Controller_Action_Helper_AjaxContext */ private $_ajaxContext = null; public function init() { $this->_ajaxContext = $this->_helper->getHelper('AjaxContext'); $this->_ajaxContext->addActionContext('fabrique', 'html') ->initContext('html'); } public function fabriqueAction() { if ( $this->_ajaxContext->getCurrentContext() == 'html' ) { $objet = $this->_getParam('objet'); $form = $this->_getObject($objet); $form->addElement('hidden', 'objet', array('value' => $objet)); $this->view->form = $form; } else { $request = $this->getRequest(); if ( $request->isPost() ) { $objet = $request->getPost('objet'); if ( $objet == 'interne' ) { $this->_helper->flashMessenger->addMessage(Zend_Debug::dump($request->getPost()) . 'Agencement sauvegardé avec succès'); } else { $form = $this->_getObject($objet); if ( $form->isValid($request->getPost()) ) { $this->_helper->flashMessenger->addMessage(Zend_Debug::dump($form->getValues()) . 'Objet ajouté avec succés'); } } $this->_helper->redirector('fabrique'); } } } private function _getObject($suffix, $type = 'form') { switch ( $type ) { case 'form': $class = 'Commun_Form_Modele_'; break; case 'model': $class = 'Commun_Model_DbTable_Modele_'; break; default: throw new Zend_Exception(sprintf('Type %s is unknown', $type)); } $class .= ucfirst($suffix); if ( ! class_exists($class) ) throw new Zend_Exception(sprintf('Class %s does not exist', $class)); return new $class; } }
Et voici le script de vue associé à l'action "fabrique" lors d'une requête de type ajax (fabrique.ajax.phtml):
[lang=php] <?php echo $this->jQuery(); // <----- Affichage de l'helper jQuery echo $this->form;
Description du résultat attendu
Lors de l'appel à l'action "fabrique" via ajax, l'aide d'action "AjaxContext" se charge de désactiver le layout.
Habituellement l'aide de vue jQuery est affichée dans mon layout: pour ce cas particulier d'un appel ajax où la layout doit être absent de la réponse j'affiche donc l'helper jQuery dans mon script de vue (indispensable pour la librairie "Chosen" utilisée dans mon formulaire).
Globalement tout fonctionne à merveille: le formulaire est correctement appelé, le controller répond comme il se doit. Le pépin est le chargement de la librairie "Chosen": les listes déroulantes de mon formulaire ne sont pas chosen-ifiées...
On en vient maintenant à mon problème
l'helper jQuery ne renvoie rien du tout!. Il devrait contenir les fichiers js et css de "Chosen" mais ce n'est pas le cas (d'où le titre jQuery perd la mémoire): un dump de l'objet jQuery confirme que les fichiers de chosen y sont effectivement absents.
Mais si j'indique à l'aide d'action AjaxContext de conserver le layout bizarrement l'helper jQuery retrouve toute sa mémoire.
Je ne comprend pas le lien entre le layout et l'helper jQuery.
Si par hasard l'un d'entre vous se sent plus inspiré que moi... je suis tout ouïe
Merci beaucoup!
PS - un lien vers le post d'une personne ayant eu le même soucis que moi:
http://forums.zend.com/viewtopic.php?f=69&t=53288
Dernière modification par criseconomix (25-07-2013 16:04:37)
Hors ligne
Bon eh bien je suis tout penaud mais néanmoins content car j'ai trouvé la solution!
Attention c'est du lourd
je reprend le code de mon script de vue
[lang=php] <?php echo $this->jQuery(); // <----- Affichage de l'helper jQuery echo $this->form;
Solution
bon ben si j'inverse les deux lignes c'est gagné...
[lang=php] <?php echo $this->form; echo $this->jQuery(); // <----- Affichage de l'helper jQuery
En effet c'est lorsque que la méthode "render()" de l'objet form est appelé que les helpers associés à chaque élément du formulaire sont exécutés... et pour mon cas le chargement de la librairie "Chosen" dans l'helper jQuery.
Voilà voilà, c'était trop simple pour que ce soit facile à trouver
Hors ligne