Jump to content

[Résolu] Récupérer une valeur avec une requête ajax (onChange) et l'utiliser dans un TPL


Recommended Posts

Bonjour (^-^)/

Je fais un formulaire en essayant d'utiliser un fields_form mais je ne suis pas très sure de la réalisabilité de ce que j'essaie de faire.

1) Est-ce qu'il est possible de récupérer la valeur du select n°1 (avec un onChange si possible) pour filtrer la liste d'option du select n°2 ? (En l'occurrence, choisir une catégorie de recette doit filtrer les recettes sélectionnables)

2) Autre question qui s'éloigne du sujet : peut-on changer la requête SQL de sauvegarde d'un fields_form ? Par défaut il se contente de la table "de base" du formulaire alors que j'ai besoin de traiter mes données et de les ranger dans plusieurs tables.

J'ai le code suivant :

 /**
  * Affichage du formulaire d'ajout / création de l'objet
  * @return string
  * @throws SmartyException
  */


  public function renderForm()
  {    
    $this->fields_form = [
      'legend' => [
          'title' => $this->l('Ajout d\'une nouvelle fabrication'),
      ],
        'input' => [
          [
            'type' => 'select',
            'label' => $this->l('Catégorie recette'),
            'name' => 'categorie_recette_selected',
            'required' => true,
            'options' => [
              'query' => CategorieRecette::getCategoriesRecette(),
              'id' => 'id_categorie_recette',
              'name' => 'nom_categorie_recette',
              'default' => [
               'label' => 'Choisir une catégorie',
               'value' => 0,
              ],
            ],
          ],
          [
            'type' => 'select',
            'label' => $this->l('Recette'),
            'name' => 'recette_selected',
            'required' => true,
            'options' => [
              'query' => Recette::getRecettes(),
              //'query' => Recette::getRecettesByCategorie($categorie_recette_selected),
              'id' => 'id_recette',
              'name' => 'nom_recette',
              'default' => [
               'label' => 'Choisir une recette',
               'value' => 0,
              ],
            ],
          ],
          [
            'type' => 'datetime',
            'label' => $this->l('Date de fabrication'),
            'name' => 'date_fabrication',
            'required' => true,
          ],
          [
            'type' => 'text',
            'label' => $this->l('N° de lot'),
            'name' => 'num_lot_fabrication',
            'required' => true,
        ],
          [
              'type' => 'text',
              'label' => $this->l('Quantité totale fabriquée'),
              'name' => 'quantite_totale_fabrication',
              'required' => true,
          ],
      ],
      'submit' => [
          'title' => $this->l('Save'),
      ],
  ];
    return parent::renderForm();
  }

(+) : getRecettesByCategorie() a besoin de l'id_categorie_recette en argument.

 

Merci de m'éclairer 😃

1.JPG

Edited by Allyta
Changement du titre (see edit history)
Link to comment
Share on other sites

Bon, j'ai tenté de mettre le .val() mais Jquery n'a pas envie de coopérer. 
J'ai choisi la simplicité en l'appelant au début de mon controller mais j'ai l'impression qu'il va falloir l'importer autrement...
 

<?php 
/* 
Controller lié à la gestion des réceptions.
Réalisé par : Allyta
*/
include '../modules/gestionProduction/classes/Fabrication.php';
include '../modules/gestionProduction/classes/CategorieRecette.php';
include '../modules/gestionProduction/classes/Recette.php';
include 'https://code.jquery.com/jquery-3.5.0.js'; // <= LE DEMON EST ICI


class AdminGestionFabricationController extends ModuleAdminController{
    
  ...


  /**
  * Affichage du formulaire d'ajout / création de l'objet
  * @return string
  * @throws SmartyException
  */


  public function renderForm()
  {    
    $this->fields_form = [
      'legend' => [
          'title' => $this->l('Ajout d\'une nouvelle fabrication'),
      ],
        'input' => [
          [
            'type' => 'select',
            'label' => $this->l('Catégorie recette'),
            'name' => 'categorie_recette_selected',
            'required' => true,
            'options' => [
              'query' => CategorieRecette::getCategoriesRecette(),
              'id' => 'id_categorie_recette',
              'name' => 'nom_categorie_recette',
              'default' => [
               'label' => 'Choisir une catégorie',
               'value' => 0,
              ],
            ],
          ],
          [
            'type' => 'select',
            'label' => $this->l('Recette'),
            'name' => 'recette_selected',
            'required' => true,
            'options' => [
              //'query' => Recette::getRecettes(),
              //'query' => Recette::getRecettesByCategorie($categorie_recette_selected),
              'query' => Recette::getRecettesByCategorie(${"select#categorie_recette_selected option:checked"}.val()),
              'id' => 'id_recette',
              'name' => 'nom_recette',
              'default' => [
               'label' => 'Choisir une recette',
               'value' => 0,
              ],
            ],
          ],
          [
            'type' => 'datetime',
            'label' => $this->l('Date de fabrication'),
            'name' => 'date_fabrication',
            'required' => true,
          ],
          [
            'type' => 'text',
            'label' => $this->l('N° de lot'),
            'name' => 'num_lot_fabrication',
            'required' => true,
        ],
          [
              'type' => 'text',
              'label' => $this->l('Quantité totale fabriquée'),
              'name' => 'quantite_totale_fabrication',
              'required' => true,
          ],
      ],
      'submit' => [
          'title' => $this->l('Save'),
      ],
  ];
    return parent::renderForm();
  }
}

 

1.JPG

Link to comment
Share on other sites

salut, je mettrais jquery dans la fonction setMedia du controlleur

 public function setMedia()
    {
        parent::setMedia();

        $this->addJS(_MODULE_DIR_ . 'monsuperModule/views/js/jquery-3.6.0.min.js');
        $this->addJS(_MODULE_DIR_ . 'monsuperModule/views/js/script.js');

    }

Mais il me semble qu'en BO il se charge deja,

cdt

Link to comment
Share on other sites

Bonjour,
Merci pour ta réponse 😃 

Je pensais aussi que c'était déjà implémenté en BO mais visiblement il ne trouve pas mon val().
Sinon j'ai un peu changé ton setMedia car il y avait un conflit avec le theme.
 

public function setMedia($isNewTheme = false)
{
  parent::setMedia($isNewTheme);

	$this->addJS(_MODULE_DIR_ . 'gestionProduction/views/js/jquery-3.6.0.min.js');
	$this->addJS(_MODULE_DIR_ . 'gestionProduction/views/js/script.js');
}

Mais au final je retombe sur la même erreur avec ou sans. 
Je dois mal appeler la fonction val(), je ne vois que ça...

1.JPG

Link to comment
Share on other sites

Faudrait pas tout mélanger ... la question 1 était sur onChange evènement javascript donc ma réponse concerne javascript ($(this).val())

PHP ne connaît bien sûr pas val(), vous appelez en ajax (js) votre controller après avoir récupéré la valeur  dans l'event change js et cela devient un paramètre (query-string) de l'appel ajax.

 

 

 

Link to comment
Share on other sites

Merci pour vos réponses.

Je pense que je vais faire mes formulaires dans un tpl à chaque fois que j'aurais du ajax à mettre et utiliser le helperForm seulement pour les petits formulaires légers non-dynamiques.
Je voulais utiliser au maximum Symfony et la génération des formulaires depuis le controller mais j'ai l'impression d'atteindre les limites de la technologie avec ce formulaire-ci.

(L'étape 2 c'est qu'une fois une recette sélectionnée, la liste des ingrédients nécessaires apparait ligne par ligne, permettant l'ajout d'inputs (n° lot, quantité, etc..) pour chaque ingrédient de la fabrication. Bref, un sacré bazar à mettre en place sans tpl. 😃 )

Je teste et je reviens vers vous ;)

  • Thanks 1
Link to comment
Share on other sites

Bon, je me suis battue un bon moment mais visiblement j'ai mal call quelque chose à un moment parce qu'il n'arrive pas à trouver le model CategorieRecette.php si je ne lui indique pas et quand je le lui donne il essaie de déclarer la classe une seconde fois.

Je vous mets mon massacre code ici :
(J'ai mis le JS dans le tpl. Je sais, c'est pas bien, mais j'en suis à l'étape juste avant pleurer du sang donc on ne fera pas de remarque là-dessus)

PHP

<?php 
/* 
Controller lié à la gestion des réceptions.
Réalisé par : Allyta
*/
include '../modules/gestionProduction/classes/Fabrication.php';
include '../modules/gestionProduction/classes/CategorieRecette.php';
include '../modules/gestionProduction/classes/Recette.php';
include '../modules/gestionProduction/classes/Unite.php';
//include 'https://code.jquery.com/jquery-3.5.0.js';

class AdminGestionFabricationController extends ModuleAdminController{
    
  // Instanciation de la classe
  public function __construct(){

    $this->bootstrap = true; //Gestion de l'affichage en mode bootstrap
    $this->table = 'gp_fabrication'; //Table de l'objet
    $this->identifier = 'id_fabrication'; //Clé primaire de l'objet
    $this->className = Fabrication::class; //Classe de l'objet
    $this->lang = false; //Flag pour dire si utilisation de langues ou non

    // Range la liste par date décroissante
    $this->_orderBy = 'date_fabrication';
    $this->_orderWay = 'DESC';
        
    //Récupère le nom de la recette à partir de l'id_recette
    $this->_join .= ' INNER JOIN '._DB_PREFIX_. 'GP_' . 'recette r ON (a.id_recette = r.id_recette)';
    $this->_select .= 'r.nom_recette AS `recette_reception`';

    //Liste des champs de l'objet à afficher dans la liste
    $this->fields_list = array(
      'recette_reception' => array('title' => 'Recette', 'width' => 'auto'), 
      'date_fabrication' => array('title' => 'Date', 'width' => 'auto'),
      'num_lot_fabrication' => array('title' => 'N° de lot', 'width' => 'auto'), 
      'quantite_totale_fabrication' => array('title' => 'Quantité totale fabriquée', 'width' => 'auto'),
    );

    //Ajout d'actions sur chaque ligne
    //$this->addRowAction('view');
    $this->addRowAction('edit');
    $this->addRowAction('delete');
   
    parent::__construct();
  }

  public function setMedia($isNewTheme = false)
    {
        parent::setMedia($isNewTheme);

        $this->addJS(_MODULE_DIR_ . 'gestionProduction/views/js/jquery-3.6.0.js');
        $this->addJS(_MODULE_DIR_ . 'gestionProduction/views/js/ajax.js');
    }

  /**
  * Affichage du formulaire d'ajout / création de l'objet
  * @return string
  * @throws SmartyException
  */
  public function renderForm()
  {
    return $this->module->display(_PS_MODULE_DIR_.'gestionProduction', 'views/templates/admin/ajoutFabrication.tpl');
    return parent::renderForm();
  }
}

TPL :

{*
* Affichage du formulaire d'ajout d'une fabrication.
*}
<div class="panel">
<!-- FORMULAIRE A REMPLIR -->
<div class="form_formulaire_reception">
    <form name="fabrication" method="post" action="">
    <div class="form-group col">
      <label for="categorieRecetteDataList">Catégorie recette :</label>
      {assign var=categoriesRecette value=CategorieRecette::getcategoriesRecette()}
      <select name="categorieRecette" class="form-select" id="categorieRecetteSelect">
      <option selected="selected">Choisir une catégorie</option>
      {foreach from=$categoriesRecette item=categorieRecette}
        <option value="{$categorieRecette.id_categorie_recette}">{$categorieRecette.nom_categorie_recette}</option>
      {/foreach}
      </select>
    </div>
    <div class="form-group col">
      <label for="recetteDataList">Nom de la recette :</label>
      {*{assign var=recettes value=Recette::getRecettes()}*}
      {assign var=recettes value=Recette::getRecettesByCategorie(id_categorie_recette_selected)}
      {*{assign var=recettes value=Recette::getRecettesByCategorie($("select#categorie_recette_selected option:checked").val())}*}
      <select class="form-control" id="recetteDataList">
      <option selected="selected">Choisir une recette</option>
      {foreach from=$recettes item=recette}
        <option value="{$recette.id_recette}">{$recette.nom_recette}</option>
      {/foreach}
      </select>
    </div> 
    <div class="form-group col">
        <label for="date_fabrication">Date de fabrication :</label>
        <input type="date" name="date_fabriation" required/> 
    </div>
    <div class="form-group col">
        <label for="num_lot_farication">N° de lot : </label>
        <input type="text" name="num_lot_farication" required/> 
    </div>
    <div class="form-group col">
        <label for="quantite_meo">Quantité totale mise en oeuvre : </label>
        <input type="text" name="quantite_meo" required/> 
    </div>
    <label for="recetteDataList">Unité de mesure :</label>
    {assign var=unites value=Unite::getUnites()}
    <select class="form-control" id="uniteDataList">
    <option selected="selected">Choisir une unité</option>
    {foreach from=$unites item=unite}
      <option value="{$unite.id_unite}">{$unite.nom_unite}</option>
    {/foreach}
    </select>
   <p></p>
    <input type="submit" class="btn btn-lg btn-block" style="background-color: #4CAF50;color: white;" name="validerAjoutFabrication" value="VALIDER"/>
  </form>
  </div>
</div>


<script>
$(document).ready(function(){

  load_data();

  function load_data(query=''){
    $.ajax({
      url:"AdminGestionFabricationController.php",
      method:"POST"
    })
  }

  //Récupération et attribution de la catégorie sélectionnée à la variable $id_categorie_recette_selected
  function getFilterId(){
    $('#categorie_recette_selected ').change(function(){
      var id_categorie_recette_selected = null;

      id_categorie_recette_selected == $(this).val();
      return id_categorie_recette_selected;
    })
  }
});

</script>

Utilisation de $id_categorie_recette_selected par getRecetteByCategorie() :

  /**
  * Return recettesByCategorie.
  *
  * @return array recettesbyCategorie
  */
  public static function getRecettesByCategorie($id_categorie_recette)
  {
    $query = new DbQuery();
    $query->select('s.*');
    $query->from('gp_recette', 's');
    $query->join(Shop::addSqlAssociation('recette', 's'));
    $query->orderBy(' s.`nom_recette` ASC');
    
    if($id_categorie_recette != null){
      $query->where('s.`id_categorie_recette` = $id_categorie_recette');
    }
    else {}

    $recettesbyCategorie = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($query);
    if ($recettesbyCategorie === false) {
      return false;
    }
    return $recettesbyCategorie;
  }


J'ai vu quelques tutos faire la query qui filtre dans la requête ajax mais je trouve que c'est plus propre de la ranger dans le model et de juste passer en argument l'id de filtrage. 

Je continue de bidouiller de mon côté. Merci aux courageux qui tenteront de me débloquer. 😃 

PS Je peux aussi vous passer le module si vous êtes vraiment déterminés. Il s'installe et se désinstalle tout seul comme un grand. ;)
 

Edited by Allyta (see edit history)
Link to comment
Share on other sites

J'ai un peu avancé.
Visiblement la requête ajax ne s'active pas ou bien elle n'arrive pas à transmettre la variable $id_categorie_recette_selected à mon select (dans le formulaire tpl).
Si quelqu'un voit une erreur, je suis preneuse ;)

 Ajax (dans le tpl, oui je sais c'est pas bien) :

<script>
$(document).ready(function(){

  load_data();

  function load_data(query=''){
    $.ajax({
      url:"AdminGestionFabricationController.php",
      method:"POST"
    })
  }

  //Récupération et attribution de la catégorie sélectionnée à la variable $id_categorie_recette_selected
  function getFilterId(){
    $('#categorieRecetteSelect').change(function(){
      var id_categorie_recette_selected = null;

      id_categorie_recette_selected = $("#categorieRecetteSelect").val();
      return id_categorie_recette_selected;
    })
  }
});

</script>

Appel de la variable dans le formulaire :

<div class="form-group col">
      <label for="recetteDataList">Nom de la recette :</label>
      {if isset($id_categorie_recette_selected) != null}
      {assign var=recettes value=Recette::getRecettesByCategorie($id_categorie_recette_selected)}
      {else}
      {assign var=recettes value=Recette::getRecettes()}
      {/if}
      <select class="form-control" id="recetteDataList">
      <option selected="selected">Choisir une recette</option>
      {foreach from=$recettes item=recette}
        <option value="{$recette.id_recette}">{$recette.nom_recette}</option>
      {/foreach}
      </select>
    </div> 

Update :
J'ai tenté 3 variations pour mon ajax mais j'ai aucun retour dans la console ni d'alerte donc visiblement ça ne passe jamais dans ce code =/
 

$(document).ready(function(){
  load_data();
  function load_data(query=''){
    $.ajax({
      url:"AdminGestionFabricationController.php",
      method:"POST"
    })
  }
  //Récupération et attribution de la catégorie sélectionnée à la variable $id_categorie_recette_selected
  function getFilterId(){
    $('#categorieRecetteSelect').change(function(){
      console.log('onChange');
      alert("onChange");
      var $id_categorie_recette_selected = null;
      $id_categorie_recette_selected = $("#categorieRecetteSelect").val();
      console.log('Selected : '. $id_categorie_recette_selected);
      return $id_categorie_recette_selected;
    })
  }
});

/////////////////////////////////////////////////////////

$(document).ready(function(){
  $( "#categorieRecetteSelect" ).change(function() {
    var id_categorie_recette = $('#categorieRecetteSelect :selected').val();
    console.log('Selected value : ' + id_categorie_recette);
    var id_categorie_recette = $(this).val();
    $.ajax({
			method : POST,
			url: '../modules/gestionProduction/controllers/admin/AdminGestionFabricationController.php',
      data: 'id_categorie_recette='+ id_categorie_recette, 
      dataType: 'html',
      success: function(json) {
        return id_categorie_recette_selected;
      }
    });
	  console.log('Data : ' + return $id_categorie_recette_selected);
    return id_categorie_recette_selected;
  });
}

////////////////////////////////////////////////////////////

$( document ).ready(function() {
  $("#categorieRecetteSelect").change(function(){
    console.log('onChange');
    alert("onChange");
     
    $.ajax({
      url : '../modules/gestionProduction/controllers/admin/AdminGestionFabricationController.php', // La ressource ciblée
      type : 'GET', // Le type de la requête HTTP.
      data : 'id_categorie_recette=' + id_categorie_recette,
      dataType : 'html' // Le type de données à recevoir, ici, du HTML.
    });
  });
}

 

Edited by Allyta
Update (see edit history)
Link to comment
Share on other sites

J'arrive enfin à récupérer l'id du 1er select \(^-^)/
Maintenant il faut que je parvienne à l'injecter dans ma variable $id_categorie_recette_selected

Le JS qui "fonctionne" :

$(document).ready(function(){
  $( "#categorieRecetteSelect" ).change(function() {
    var id_categorie_recette_selected = $('#categorieRecetteSelect :selected').val();
    console.log('Selected value : ' + id_categorie_recette_selected);
    var id_categorie_recette_selected = $(this).val();
    $.ajax({
			method : 'POST',
			url: '../modules/gestionProduction/controllers/admin/AdminGestionFabricationController.php',
      data: 'id_categorie_recette='+ id_categorie_recette_selected, 
      dataType: 'html',
      success: function(json) {
        return id_categorie_recette_selected;
      }
    });
	  console.log('Data : ' + id_categorie_recette_selected);
    return id_categorie_recette_selected;
  });
});

 

1.JPG

Edit :

Après une petite correction, je n'ai plus d'erreur en rouge mais le second select ne traite jamais la variable.
 

Edit :

J'ai modifié le nom de la variable dans le ajax pour qu'il corresponde au nom dans le select. L'id est bien assigné à la variable en sortie d'ajax mais il n'est pas utilisé dans mon select car $id_categorie_recette_selected est undefined...

<label for="recetteDataList">Nom de la recette :</label>
      {if isset($id_categorie_recette_selected) != null}
      {assign var=recettes value=Recette::getRecettesByCategorie($id_categorie_recette_selected)}
      {else}
      {assign var=recettes value=Recette::getRecettes()}
      {/if}
      {*{assign var=recettes value=Recette::getRecettesByCategorie($("select#categorie_recette_selected option:checked").val())}*}
      <select class="form-control" id="recetteDataList">
      <option selected="selected">Choisir une recette</option>
      {foreach from=$recettes item=recette}
        <option value="{$recette.id_recette}">{$recette.nom_recette}</option>
      {/foreach}
      </select>

 

Edited by Allyta
Correction (see edit history)
Link to comment
Share on other sites

Update
Je suis pas loin du tout d'y arriver.
L'ajax fonctionne, le filtrage du select fonctionne mais la variable ne récupère pas la valeur de $id_categorie_recette_selected (qui est bien récupérée) dans l'ajax du coup le filtrage ne rentre jamais dans la condition if($id_categorie_recette_selected != null).

Une idée ? 😃

{*
* Affichage du formulaire d'ajout d'une fabrication.
*}
<div class="panel">
<!-- FORMULAIRE A REMPLIR -->
<div class="form_formulaire_reception">
    <form name="fabrication" method="post" action="">
    <div class="form-group col">
      <label for="categorieRecetteDataList">Catégorie recette :</label>
      {assign var=categoriesRecette value=CategorieRecette::getcategoriesRecette()}
      <select name="categorieRecette" class="form-select" id="categorieRecetteSelect">
      <option selected="selected">Choisir une catégorie</option>
      {foreach from=$categoriesRecette item=categorieRecette}
        <option value="{$categorieRecette.id_categorie_recette}">{$categorieRecette.nom_categorie_recette}</option>
      {/foreach}
      </select>
    </div>
    <div class="form-group col">
      <label for="recetteDataList">Nom de la recette :</label>
      {$id_categorie_recette_selected = 2} <= "2" doit être remplacé par la valeur de $id_categorie_recette_selected provenant du return dans l'ajax
      {if isset($id_categorie_recette_selected) != null}
      {assign var=recettes value=Recette::getRecettesByCategorie($id_categorie_recette_selected)}
      {else}
      {assign var=recettes value=Recette::getRecettes()}
      {/if}
      <select class="form-control" id="recetteDataList">
      <option selected="selected">Choisir une recette</option>
      {foreach from=$recettes item=recette}
        <option value="{$recette.id_recette}">{$recette.nom_recette}</option>
      {/foreach}
      </select>
    </div> 
    <div class="form-group col">
        <label for="date_fabrication">Date de fabrication :</label>
        <input type="date" name="date_fabriation" required/> 
    </div>
    <div class="form-group col">
        <label for="num_lot_fabrication">N° de lot : </label>
        <input type="text" name="num_lot_farication" required/> 
    </div>
    <div class="form-group col">
        <label for="quantite_meo">Quantité totale mise en oeuvre : </label>
        <input type="text" name="quantite_meo" required/> 
    </div>
    <label for="recetteDataList">Unité de mesure :</label>
    {assign var=unites value=Unite::getUnites()}
    <select class="form-control" id="uniteDataList">
    <option selected="selected">Choisir une unité</option>
    {foreach from=$unites item=unite}
      <option value="{$unite.id_unite}">{$unite.nom_unite}</option>
    {/foreach}
    </select>
   <p></p>
    <input type="submit" class="btn btn-lg btn-block" style="background-color: #4CAF50;color: white;" name="validerAjoutFabrication" value="VALIDER"/>
  </form>
  </div>
</div>

<script>
$(document).ready(function(){
  $( "#categorieRecetteSelect" ).change(function() {
    var id_categorie_recette_selected = $('#categorieRecetteSelect :selected').val();
    $.ajax({
			method : 'POST',
			url: '../modules/gestionProduction/controllers/admin/AdminGestionFabricationController.php',
      data: id_categorie_recette_selected, 
      dataType: 'html',
      success: function(json) {
        return id_categorie_recette_selected;
      }
    });
	  console.log('Selected value : ' + id_categorie_recette_selected);
    return id_categorie_recette_selected;
  });
});

</script>

 

Edited by Allyta (see edit history)
Link to comment
Share on other sites

  • Allyta changed the title to Récupérer une valeur avec une requête ajax (onChange) et l'utiliser dans un TPL

Bonjour,
Toujours en train de plancher sur ce tpl qui ne récupère pas la variable...
J'ai fais pas mal de tests sans succès.
En console, je vois que mon Ajax récupère bien $id_categorie_recette_selected mais le tpl n'arrive pas à récupérer sa valeur.
Pour mon tpl, $id_categorie_recette_selected = 0 quoi que je fasse.

Petit aperçu de mes tentatives :
Dans le tpl

 <label for="recetteDataList">Nom de la recette :</label>
      {*{$id_categorie_recette_selected = (int)Tools::getValue('id_categorie_recette_selected')}*}
      {*<script>id_categorie_recette_selected = $_POST['id_categorie_recette_selected'];</script>*}
      {assign var=id_categorie_recette_selected value=(int)Tools::getValue('id_categorie_recette_selected')}
      {$id_categorie_recette_selected} 
      {if isset($id_categorie_recette_selected) != null}
      {assign var=recettes value=Recette::getRecettesByCategorie($id_categorie_recette_selected)}
      {else}
      {assign var=recettes value=Recette::getRecettes()}
      {/if}

Dans le controller

  public function renderForm()
  {
    $id_categorie_recette_selected = (int)Tools::getValue('id_categorie_recette_selected');
    //$id_categorie_recette_selected = $_POST['id_categorie_recette_selected'];
    //$smarty->assign('id_categorie_recette_selected', $id_categorie_recette_selected);
    echo $id_categorie_recette_selected;
    return $this->module->display(_PS_MODULE_DIR_.'gestionProduction', 'views/templates/admin/ajoutFabrication.tpl');
    return parent::renderForm();
  }

Bientôt 1 mois que je suis bloquée là-dessus =/
Si quelqu'un a une idée de ce que je peux encore tenter, je prends.

Link to comment
Share on other sites

Merci doekia et coeos.pro pour vos réponses 😃

doekia :
Si je comprends bien, je mets ça dans mon tpl :

 <label for="recetteDataList">Nom de la recette :</label>
      {assign var=id_categorie_recette_selected value=id_categorie_recette}
      {$id_categorie_recette_selected} 
      {if isset($id_categorie_recette_selected) != null}
      {assign var=recettes value=Recette::getRecettesByCategorie($id_categorie_recette_selected)}
      {else}
      {assign var=recettes value=Recette::getRecettes()}
      {/if}
      <select class="form-control" id="recetteDataList">
      <option selected="selected">Choisir une recette</option>
      {foreach from=$recettes item=recette}
        <option value="{$recette.id_recette}">{$recette.nom_recette}</option>
      {/foreach}
      </select>

et ça dans le controller :

public function renderForm()
  {
    $id_categorie_recette = (int)Tools::getValue('id_categorie_recette_selected');
    echo $id_categorie_recette;

    return $this->module->display(_PS_MODULE_DIR_.'gestionProduction', 'views/templates/admin/ajoutFabrication.tpl');
    return parent::renderForm();
  }

J'ai changé id_categorie_recette_selected par id_categorie_recette dans l'assign et à l'attribution de la valeur dans le controller sinon il me sort une erreur SQL (Champ 'id_categorie_recette_selected' inconnu dans where clause<br /><br /><pre>SELECT s.* FROM `ps_gp_recette` s WHERE (s.`id_categorie_recette` =id_categorie_recette_selected) ORDER BY s.`nom_recette` ASC </pre>).
En utilisant le code que j'ai mis au dessus, j'obtiens "0" en retour du echo $id_recette et "id_categorie_recette" en retour de {$id_categorie_recette_selected}.

Est-ce qu'il faut résoudre un bug de communication entre le tpl et le controller ou est-ce qu'il fallait que je garde id_categorie_recette_selected et que je résolve l'erreur SQL ?

coeos.pro :
Tu penses que l'url ne permet pas d'atteindre la ressource ciblée ?
Je ne suis pas sure de ce que tu proposes, déplacer tout le controller en front ? Ou juste la partie du controller qui traite l'ajax en front ? 
Dans le dernier cas, est-ce qu'il sera possible de renvoyer la valeur récupérée dans le frontController vers le tpl ?

Je vais tester toutes ces possibilités pour ne pas perdre de temps.

Link to comment
Share on other sites

Honnêtement on ne comprend rien à ta logique. Cela fait 1 mois que tu patauges en essayant au petit bonheur la chance de faire fonctionner quelque chose d'élementaire alors que si tu avais investi 1/4 de ce temps à lire la documentation smarty et analyser des modules existants (par exemple blockcms) tu aurais déjà atteint ton but.

Moi je lâche l'affaire

Link to comment
Share on other sites

j'ai le souvenir d'un controller admin qui ne passait pas du tout, j'ai fait plein de tests, perdu un temps pas possible, ça ma saoulé du coup j'ai passé le controller entier en front (avec un token pour le protéger) et en 5 minutes c'était réglé. Du coup maintenant je n'utilise que des controllers front.

oui pour le tpl, dans le fichier php du module je rajoute la fonction


    public function displayTemplate($datas, $tpl)
    {
        $this->smarty->assign($datas);
        return $this->display(__FILE__, $tpl);
    }

 

et depuis le controller

$module = new MonModule();
echo $module->displayTemplate($datas, $template);

 

exemple pour $template : 'module:monmodule/views/templates/admin/prestui/le_fichier_tpl.tpl';

 

Link to comment
Share on other sites

Ces 2 lignes n'ont aucun sens:

      {assign var=id_categorie_recette_selected value=id_categorie_recette}
      {$id_categorie_recette_selected} 

Ou est le assign ici et que vient faire cet echo?

public function renderForm()
  {
    $id_categorie_recette = (int)Tools::getValue('id_categorie_recette_selected');
    echo $id_categorie_recette;

    return $this->module->display(_PS_MODULE_DIR_.'gestionProduction', 'views/templates/admin/ajoutFabrication.tpl');
    return parent::renderForm();
  }

 

Link to comment
Share on other sites

Merci pour vos réponses et désolée du délais de retour.
(Officiellement je suis stagiaire, officieusement je suis la totalité du service informatique de ma boite)

coeos.pro 
Je termine de tester ton idée de front controller cet après-midi et je reviens vers toi.

doekia
J'ai appliqué tes remarques. Malheureusement je n'ai pas trouvé d'Ajax dans le module blockcsm. Ma version était peut-être trop ancienne (2.1.2 / prestashop 1.5).
J'ai légèrement modifié l'ajax en m'inspirant de ceci et cela :


$(document).ready(function(){
  $( "#categorieRecetteSelect" ).change(function() {
    var id_categorie_recette_selected = $('#categorieRecetteSelect :selected').val();
    $.ajax({
      type : 'POST',
      dataType : 'json',
      //url : '../modules/gestionProduction/index.php',
      url : 'index.php',
      data : {
        //required parameters
        ajax : true,
        controller : 'AdminGestionFabricationController',
        action : 'ajaxProcessGetId',
        id_categorie_recette_selected: id_categorie_recette_selected,
        token : '{$token}'
      }
    })
    .done(function(){
      console.log('success');
    })
    .fail(function(){
      console.log('fail');
    });
    console.log('Selected value : ' + id_categorie_recette_selected);
  });
});

La console m'affiche bien l'id de la catégorie avec le dernier console.log mais l'ajax fail à chaque fois.
 

Mon admin controller :

 public function ajaxProcessGetId(){
	// Ajax query
	$id_categorie_recette_selected = Tools::getValue('id_categorie_recette_selected');
	die(Tools::JsonEncode($id_categorie_recette_selected));
 } 

  /**
  * Affichage du formulaire d'ajout / création de l'objet
  * @return string
  * @throws SmartyException
  */
  public function renderForm()
  {
    $id_categorie_recette_selected = (int)Tools::getValue('id_categorie_recette_selected');
    $this->context->smarty->assign('id_categorie_recette_selected', $id_categorie_recette_selected);

    return $this->module->display(_PS_MODULE_DIR_.'gestionProduction', 'views/templates/admin/ajoutFabrication.tpl');
    return parent::renderForm();
  }

Si quelque chose te choque, n'hésite pas à me le signaler.

Link to comment
Share on other sites

Edit

coeos.pro 

J'ai testé avec de faire un front controller mais je dois mal faire la liaison vers celui-ci.
Comme je suis plutôt proche d'arriver à débugger avec un AdminController classique, je vais mettre de côté le front pour le moment.

doekia
J'ai retiré done et fail pour remettre success dans ma requête ajax.

$(document).ready(function(){
  $( "#categorieRecetteSelect" ).change(function() {
    var id_categorie_recette_selected = $('#categorieRecetteSelect :selected').val();
    $.ajax({
      type : 'POST',
      dataType : 'json',
      url : '../modules/gestionProduction/ajaxId.php',
      data : {
        ajax : true,
        controller : 'AdminGestionFabricationController',
        action : 'ajaxProcessGetId',
        id_categorie_recette_selected: id_categorie_recette_selected,
        token: {$token}
      },
      success:function(data){
        $('#categorieRecetteSelect').html(data);
      }
    })
    console.log('Selected value : ' + id_categorie_recette_selected);
  });
});


Je retrouve bien l'envoi de mon id dans la console mais elle n'est pas exploitée par mon back.1.thumb.JPG.5bfb76e63a2d5c6912127b463b4ae5cd.JPG

 

Je pense que mon URL dans l'ajax n'est pas bonne mais je suis un peu perdue car en fonction des explications ils préconisent des fichiers ciblés différents :

url : '../modules/gestionProduction/index.php',
url : '../modules/gestionProduction/ajaxId.php',
url: '../modules/gestionProduction/views/templates/admin/ajoutFabrication.tpl', (403 - FORBIDDEN)
url: '../modules/gestionProduction/controllers/admin/AdminGestionFabricationController.php',

Mon ajaxId.php

<?php 
require_once('../config/config.inc.php');
require_once('../init.php');

class AjaxId{
	public function ajaxProcessGetId(){
		// Ajax query
		$id_categorie_recette_selected = Tools::getValue('id_categorie_recette_selected');
		echo ($id_categorie_recette_selected);
		die(Tools::JsonEncode($id_categorie_recette_selected));
    } 
}

 

Edited by Allyta (see edit history)
Link to comment
Share on other sites

Salut, je te partage mon code qui permet:

en fonction de la valeur d'un 1er select (ici une categorie mère), requete ajax pour réaffichage d un 2eme select (sous categorie)

  var url_ajaxbabaMarketplace = "{$link->getModuleLink('babaMarketplace', 'ajax', array())}";

dans javascript.tpl je declare le lien vers l'ajax de mon module

ici le js appellé

$(document).ready(function() {
    
    $('.selectCat1').on('change', function(e) {
        e.preventDefault();

        var id_category = $(this).find(":selected").val();
        var id_product = $(this).attr('id').replace('selectCat1_', '');
        $('#selectCat2_'+id_product).hide();
        $('#label2_'+id_product).hide();
        $('#selectCat3_'+id_product).hide();
        $('#label3_'+id_product).hide();


        $.ajax({
            type: 'POST',
            url: url_ajaxbabaMarketplace,
            cache: false,
            data: {
                action: 'createProductCategorisation',
                id_category: id_category,
                id_product: id_product,
                ajax: true
            },
            success: function (data) {

                var data = jQuery.parseJSON(data);
                var id_product = data.id_product;

                var option ='<option>-Pas de catégorisation</option>';

                if (data.false!==1)
                $.each(data.categories, function(k, v) {
                  
                    option += "<option value="+v['id_category']+">"+v['name']+"</option>";
                });
                
                if (data.categories.length!==0)
                $('#second-level-'+id_product).html('<label id="label2_'+id_product+'">2eme niveau</label><select id="selectCat2_'+id_product+'" class="selectCat2 form-control">'+ option +'</select>');
            
            },

            error: function() {
                alert('Une erreur s\'est produite :(');
            }
        });

        }
    );

    $('body').on('change', '.selectCat2', function(e) {
        e.preventDefault();

        var id_category = $(this).find(":selected").val();
        var id_product = $(this).attr('id').replace('selectCat2_', '');

        $.ajax({
            type: 'POST',
            url: url_ajaxbabaMarketplace,
            cache: false,
            data: {
                action: 'createProductCategorisation',
                id_category: id_category,
                id_product: id_product,
                ajax: true
            },
            success: function (data) {

                var data = jQuery.parseJSON(data);
                var id_product = data.id_product;
                console.log(data.categories);

                var option ='<option>--Pas de catégorisation</option>';

                $.each(data.categories, function(k, v) {
                    option += "<option value="+v['id_category']+">"+v['name']+"</option>";
                });
                
                if (data.categories.length!==0)

                $('#third-level-'+id_product).html('<label id="label3_'+id_product+'">3eme niveau</label><select id="selectCat3_'+id_product+'" class="selectCat3 form-control">'+ option +'</select>');
            
            },

            error: function() {
                alert('Une erreur s\'est produite :(');
            }
        });

        }
    );

.... reste du js ....

une partie du controlleur ajax.php de mon module

elseif ($action == 'createProductCategorisation') { 

            $id_category = (int)Tools::getValue('id_category');
            $id_product = (int)Tools::getValue('id_product');

            // on veut trouver toutes les catégories enfants
            if ($id_category != 0) {
                $categories = Category::getChildren($id_category, 1, true, 1);
                die(Tools::jsonEncode(array('categories' => $categories,'id_product' => $id_product)));
            } else {
                die(Tools::jsonEncode(array('false' => 1)));
            }

la partie du tpl concerné

<div><br/><strong><small>Catégorisation:</small></strong></div>
                    <div class="col-md-3">
                        <label>1er niveau</label>
                        <select class="selectCat1 form-control" id="selectCat1_{$product.product_id}">
                            <option value="0">Selectionner...</option>
                            <option value="849">Cheveux</option>
                            <option value="858">Visage</option>
                            <option value="850">Corps</option>
                            <option value="860">Mains et pieds</option>
                            <option value="1047">Accessoires</option>
                            <option value="863">Bien-être</option>
                            <option value="861">Bronzage</option>
                            <option value="862">Complément alimentaire</option>
                            <option value="859"> Huile essentielle</option>
                        </select>
                    </div>
                    <div id="second-level-{$product.product_id}" class="col-md-3">
                    </div>
                    <div id="third-level-{$product.product_id}" class="col-md-3">
                    </div>
                </div>

 

en esperant que ca t'aidera,

cdt

Capture d’écran 2021-07-04 à 19.09.59.png

Edited by Alexandre Carette (see edit history)
Link to comment
Share on other sites

C'est fonctionnel \(^-^)/

Merci Alexandre pour ton code. 

Il fallait définir l'url vers index.php et j'ai arrêté de passer l'id de la catégorie pour passer une liste des objets "recettes" dont l'id_categorie correspondait à mon id_categorie_selected.

Ce qui donne: 
 

$(document).ready(function(){
  $( "#categorieRecetteSelect" ).change(function() {
    var id_categorie_recette_selected = $('#categorieRecetteSelect :selected').val();
    $.ajax({
      type : 'POST',
      dataType : 'json',
      url: 'index.php',
      data : {
        ajax : 1,
        controller : 'AdminGestionFabrication',
        action : 'getId',
        id_categorie_recette_selected: id_categorie_recette_selected,
        token : '{$token}'
      },
      success:function(data){
        
        var listeRecettes = document.getElementById('recetteDataList');

        // Clear les options
        listeRecettes.innerHTML = '';
        listeRecettes.disabled = false;

        // Ajouter les options
        data.forEach((currentData) => {
          
          var opt = document.createElement('option');
            opt.value = currentData.id_recette;
            opt.innerHTML = currentData.nom_recette;
            listeRecettes.appendChild(opt);
        });
      }
    })
    console.log('Selected value : ' + id_categorie_recette_selected);
  });
});

 

1.JPG

  • Like 1
Link to comment
Share on other sites

  • Allyta changed the title to [Résolu] Récupérer une valeur avec une requête ajax (onChange) et l'utiliser dans un TPL

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...