GBPro Posted April 26, 2022 Share Posted April 26, 2022 Bonjour, Voilà, j'ai un module avec un formulaire en admin permettant de choisir un client via un input (recherche ajax et autocomplete). Une fois le client sélectionné je souhaite avoir un champs juste après qui propose un dropdown avec ses références de commande. Comment puis-je faire pour conditionner la liste déroulante sur le choix de l'input précédent ? Sachant que je récupère l'id du customer dans un attribut name une fois qu'il est choisi. Je vous remercie. Link to comment Share on other sites More sharing options...
Eolia Posted April 26, 2022 Share Posted April 26, 2022 en js, on('change') => requête ajax qui récupère les infos voulues. Link to comment Share on other sites More sharing options...
GBPro Posted April 26, 2022 Author Share Posted April 26, 2022 Bonjour Eolia, Merci pour votre retour. Auriez-vous des détails à me donner sur la requête ajax à effectuer svp pour récupérer les commandes avec l'id_customer ? En vous remerciant Link to comment Share on other sites More sharing options...
Eolia Posted April 26, 2022 Share Posted April 26, 2022 votre requete ajax appelle un fichier php (getOrders.php par exemple) et celui-ci appelle la fonction Order::getCustomerOrders($id_customer); $id_customer que vous avez récupéré et envoyé en ajax Link to comment Share on other sites More sharing options...
GBPro Posted April 26, 2022 Author Share Posted April 26, 2022 D’accord je comprends le principe. je dois transmettre ma variable à mon ModuleAdminController. comment je peux faire pour la récupérer quand je suis dans ce controller ? dois passer par une méthode ? Link to comment Share on other sites More sharing options...
Eolia Posted April 26, 2022 Share Posted April 26, 2022 Vous l'envoyez en POST ou en GET (id_customer =XXXXX ) et vous la récupérez avec $id_customer = Tools::getValue('id_customer'); Link to comment Share on other sites More sharing options...
GBPro Posted April 26, 2022 Author Share Posted April 26, 2022 D’accord c’est ce que j’ai commencé à faire. dans la requête Ajax en jquery faut-il mettre des paramètres spécifiques ? Link to comment Share on other sites More sharing options...
Eolia Posted April 26, 2022 Share Posted April 26, 2022 Vous mettez ce dont vous avez besoin et éventuellement un token par sécurité Link to comment Share on other sites More sharing options...
GBPro Posted April 27, 2022 Author Share Posted April 27, 2022 J'ai fait ceci : $('#customer_autocomplete_input').on('focusout', function(){ if($('#inputCustomer').attr('value')){ let id_customer_selected = $('#inputCustomer').attr('value'); $.ajax({ type: 'POST', dataType: 'json', url: ???, // Url vers l'admin controller cache: false, data: { ajax: 1, controller: 'AdminModule', action: 'getcustomerid', 'id_customer_selected' : id_customer_selected, token: '{$token}' }, success: function (data) { var data = jQuery.parseJSON(data); id_customer_selected = data.id_customer_selected; console.log(id_customer_selected); }, error: function() { console.log('Erreur lors de l\'envoi ajax'); } }) console.log(id_customer_selected); } }); Le seul soucis c'est que je ne sais pas comment récupérer dynamiquement l'url vers l'admin controller. Avez-vous une suggestion svp ? Merci Link to comment Share on other sites More sharing options...
Eolia Posted April 27, 2022 Share Posted April 27, 2022 Depuis le php de votre module qui appelle ce js, affectez la variable Smarty au tpl concerné $ajax_link = $this->getModuleLink('NomDeVotreModule', 'NomDeVotreController', array(), Configuration::get('PS_SSL_ENABLED')); $this->smarty->assign('ajax_link', $ajax_link); et dans le tpl vous assignez cette variable Smarty en variable JS accessible depuis votre script {addJsDef ajax_link=$ajax_link|escape:'quotes':'UTF-8'} La variable JS ajax_link est à présent dispo dans votre script Link to comment Share on other sites More sharing options...
GBPro Posted April 27, 2022 Author Share Posted April 27, 2022 (edited) Ok je comprends, cependant le tpl en question c'est le renderForm() de mon adminController. Est-ce que je peux utiliser ceci ? Et où dois-je le mettre dans mon adminController svp ? : // Create a link with the path $ajax_link = $this->context->link->getAdminLink('AdminController'); //define js value to use in ajax url Media::addJsDef(array( "ajax_link" => $ajax_link )); Edited April 27, 2022 by GBPro (see edit history) Link to comment Share on other sites More sharing options...
Eolia Posted April 27, 2022 Share Posted April 27, 2022 public function setMedia() { Parent::setMedia(); $this->context->controller->addJsDef( array( 'ajax_link' => $this->context->link->getAdminLink('AdminNkmCustomerFile') ) ); } Link to comment Share on other sites More sharing options...
GBPro Posted April 27, 2022 Author Share Posted April 27, 2022 D'accord. Bon maintenant le soucis c'est quand regardant ce qu'il envoie (data), je constate qu'il envoi toute une page html ... Et quand je spécifie dataType: 'json' l'envoi échoue. $.ajax({ method: 'POST', url: ajax_link, cache: false, contentType: "application/json", processData: false, data: id_customer_selected, success: function (data) { console.log('Envoi réussi : ' + data); }, error: function() { console.log('Erreur lors de l\'envoi ajax'); } }) Je ne comprends pas pourquoi data correspond à tout une page html et pas id_customer_selected. Link to comment Share on other sites More sharing options...
Eolia Posted April 27, 2022 Share Posted April 27, 2022 data: 'id_customer='+id_customer_selected, dataType: 'json', il faut nommer le paramètre ("id_customer") et utiliser dataType et non ContentType processData ne sert à rien. Link to comment Share on other sites More sharing options...
GBPro Posted April 27, 2022 Author Share Posted April 27, 2022 ça ne fonctionne pas... quand je fais : $.ajax({ method: 'POST', url: ajax_link, cache: 'false', dataType: 'json', data: 'id_customer='+id_customer_selected, success: function (data) { console.log('Envoi réussi : ' + data); }, error: function(data) { console.log('Erreur lors de l\'envoi ajax : ' + data); } }) La requête ajax échoue et ça me retourne comme data : [object Object] Link to comment Share on other sites More sharing options...
GBPro Posted April 27, 2022 Author Share Posted April 27, 2022 Je commence un peu à être perdu. Dans mon formulaire du adminController généré via renderForm je récupère bien l'id_customer en javascript quand je sélectionne le client. Mais ensuite je n'arrive pas à envoyer cet id_customer de nouveau au adminController pour charger les options de la liste déroulante qui vient après, avec la liste de ses commandes. Je n'arrive pas à faire la bonne requête ajax pour renvoyer l'id au controller et je ne sais pas comment récupérer cet id dans le controller. Dois-je appeler une méthode au niveau des data de la requête ajax ? Link to comment Share on other sites More sharing options...
Eolia Posted April 27, 2022 Share Posted April 27, 2022 Dans votre controller, ajoutez cette fonction: public function ajaxProcessLoadOrders() { $id_customer = (int)Tools::getValue('id_customer'); // Votre fonction pour récupérer les commandes $orders = .... $this->context->smarty->assign( array( 'orders' => $orders, 'link' => $this->context->link ) ); die($this->module->display(_PS_MODULE_DIR_.$this->module->name.DIRECTORY_SEPARATOR.$this->module->name.'.php', 'order-list.tpl')); } Elle va se déclencher lors de l'appel de votre js (auquel je rajoute l'action) $.ajax({ method: 'POST', url: ajax_link, cache: 'false', dataType: 'json', data: { ajax: true, action: 'loadorders', id_customer: id_customer_selected }, success: function (data) { console.log('Envoi réussi : ' + data); }, error: function(data) { console.log('Erreur lors de l\'envoi ajax : ' + data); } }) Donc vous récupérez l'id_customer, vous l'envoyez à votre controleur en précisant l'action concernée (loadorders) et qu'on est en ajax. Celui-ci va déclencher la fonction ajaxProcessLoadOrders() qui va récupérer les commandes, en extraire ce dont vous avez besoin (ID,Ref, etc...) et envoyer le tableau à un tpl (à créer dans /votremodule/views/templates/hook/order-list.tpl) qui va vous mettre le select en forme. Le js va donc recevoir un js et il suffit de l'injecter à l'endroit voulu) Dans le tpl vous avez juste à faire une boucle {foreach} <select name="getRef"> {foreach $orders as $order} <option value="{$order.id}">{$order.reference}</option> {/foreach} </select> Link to comment Share on other sites More sharing options...
GBPro Posted April 27, 2022 Author Share Posted April 27, 2022 D'accord, mais dans mon cas je ne dois pas envoyer la variable à un tpl mais juste à mon adminController car je veux mettre les commandes dans un select : array( 'type' => 'select', 'label' => $this->l('Order reference'), 'name' => 'customer_orders', 'required' => true, 'options' => array( 'query' => $options, 'id' => 'id_order', 'name' => 'name' ) ), Est-ce que je dois aussi utiliser une fonction ajaxProcessLoadOrders ? Si oui est-ce que ajaxProcessLoadOrders doit retourner une valeur pour que je puisse l'utiliser en l'appellant et faire : array( 'type' => 'select', 'label' => $this->l('Order reference'), 'name' => 'customer_orders', 'required' => true, 'options' => array( 'query' => $this->ajaxProcessLoadOrders(), // Récupération des commandes dans la fonction 'id' => 'id_order', 'name' => 'name' ) ), Link to comment Share on other sites More sharing options...
Eolia Posted April 27, 2022 Share Posted April 27, 2022 Non car le code que vous me montrez est un bout de helperform donc il faut le construire, faire un fetchTemplate et le renvoyer avec un die(); Les 2 solutions sont possibles. Le helperform de base de votre controleur renvoie un contenu smarty à l'adminModule de Presta, dans votre cas vous voulez récupérer ce contenu pour l'injecter en js, ce n'est pas la même chose. Je vous ai donné presque tout le code, pourquoi chercher plus compliqué ? Link to comment Share on other sites More sharing options...
GBPro Posted April 27, 2022 Author Share Posted April 27, 2022 Parce que je ne comprends pas comment on peut modifier un template généré par le renderForm(). J'avoue ne pas comprendre... Link to comment Share on other sites More sharing options...
GBPro Posted April 27, 2022 Author Share Posted April 27, 2022 ça c'est la partie qui m'intéresse dans mon renderForm() : array( 'type' => 'customer_autocomplete', 'label' => $this->l('Customer'), 'name' => 'id_customer', 'lang' => false, 'col' => 5, ), array( 'type' => 'select', 'label' => $this->l('Order reference'), 'name' => 'customer_orders', 'required' => true, 'options' => array( 'query' => $options, 'id' => 'id_order', 'name' => 'name' ) ) $options doit contenir les commandes du client dynamiquement en fonction du champs customer_autocomplete du dessus (en se servant de la variable id_customer récupérée) Link to comment Share on other sites More sharing options...
Eolia Posted April 27, 2022 Share Posted April 27, 2022 il y a 8 minutes, GBPro a dit : Parce que je ne comprends pas comment on peut modifier un template généré par le renderForm(). J'avoue ne pas comprendre... En js, on injecte le contenu renvoyé par le controleur dans la page. Comme Prestashop le fait pour les produits par exemple: Link to comment Share on other sites More sharing options...
GBPro Posted April 28, 2022 Author Share Posted April 28, 2022 Ok donc il ne faut pas intégrer le champs select dans le renderForm() mais l'injection après en js ? mais le template du formulaire admin du module rendu par renderForm() se situe où pour injecter ceci : <select name="getRef"> {foreach $orders as $order} <option value="{$order.id}">{$order.reference}</option> {/foreach} </select> Link to comment Share on other sites More sharing options...
Eolia Posted April 28, 2022 Share Posted April 28, 2022 Il y a 17 heures, Eolia a dit : envoyer le tableau à un tpl (à créer dans /votremodule/views/templates/hook/order-list.tpl) Relisez mon post svp Link to comment Share on other sites More sharing options...
GBPro Posted April 28, 2022 Author Share Posted April 28, 2022 Ok je comprends mieux. Par contre comment injecter ce tpl créé, juste après le champs de sélection du customer ? Faut-il l'appeler dans le tableau fields_form de l'admin controller ? Comment lui dire précisément où aller ? Link to comment Share on other sites More sharing options...
Eolia Posted April 28, 2022 Share Posted April 28, 2022 Non, c'est votre js qui le fait au retour de l'ajax (seul le js peut modifier le DOM) $.ajax({ method: 'POST', url: ajax_link, cache: 'false', dataType: 'html', data: { ajax: true, action: 'loadorders', id_customer: id_customer_selected }, success: function (data) { console.log(data); if(data){ $(this).parent().append(data); } }, error: function(data) { console.log('Erreur lors de l\'envoi ajax : ' + data); } }) J'ai passé le retour en dataType html pour que ce soit plus simple pour vous $(this) correspond à l'élément cliqué Link to comment Share on other sites More sharing options...
GBPro Posted April 28, 2022 Author Share Posted April 28, 2022 D'accord très bien. Merci Donc si je veux par exemple modifier la valeur par défaut d'un autre input text en fonction de la référence de commande qui est sélectionnée parmi celles récupérées dans le select qui vient d'être injecté en js, je dois aussi le faire en js avec appel ajax c'est ça ? Link to comment Share on other sites More sharing options...
Eolia Posted April 28, 2022 Share Posted April 28, 2022 oui Link to comment Share on other sites More sharing options...
GBPro Posted April 28, 2022 Author Share Posted April 28, 2022 D'accord je comprends mieux, merci ! Et petite question : quelle est la méthode pour rafraichir une front page dans une méthode ajax dans un frontController avec le die svp ? Link to comment Share on other sites More sharing options...
Eolia Posted April 28, 2022 Share Posted April 28, 2022 Ca dépend. Si on veut "rafraichir" il faut regénérer le template et le renvoyer. Ce que fait Prestashop pour la page panier par exemple lorsque l'on modifie un des éléments du panier. Soit on écrase tout, soit on met à jour que les éléments qui nous intéressent (grâce à leur ID) Link to comment Share on other sites More sharing options...
GBPro Posted April 28, 2022 Author Share Posted April 28, 2022 D'accord. Dans le cas où on veut rafraichir la page car changement en BDD, il faut juste faire un setTemplate à la fin de la méthode ajax ? Link to comment Share on other sites More sharing options...
Eolia Posted April 28, 2022 Share Posted April 28, 2022 oui Link to comment Share on other sites More sharing options...
GBPro Posted April 28, 2022 Author Share Posted April 28, 2022 quand je fais un $this->setTemplate('module:monmodule/views/templates/front/display.tpl'); il ne rafraichit pas la page. Link to comment Share on other sites More sharing options...
Eolia Posted April 28, 2022 Share Posted April 28, 2022 il faut faire un die() ensuite pour le revoyer au js. Regardez comment est fait l'OrderOpcController par exemple: case 'cartReload': $this->_assignSummaryInformations(); if ($this->context->customer->id) { $this->context->smarty->assign('address_list', $this->context->customer->getAddresses($this->context->language->id)); } else { $this->context->smarty->assign('address_list', array()); } $this->context->smarty->assign('opc', true); $this->setTemplate(_PS_THEME_DIR_.'shopping-cart.tpl'); $this->display(); $this->ajaxDie(); break; Link to comment Share on other sites More sharing options...
GBPro Posted April 28, 2022 Author Share Posted April 28, 2022 Je vois dans le CartController, il utilise ceci ajaxRender(), est-ce que c'est applicable dans mon cas ? Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now