Partage
  • Partager sur Facebook
  • Partager sur Twitter

Calculs à partir des données de 2 tables

    24 mars 2017 à 11:37:22

    Bonjour,

    J'ai 2 tables de ma base de données liées entre elles par un id. Dans ma vue j'affiche certaines données (numériques ou textuelles) de la table 1 (qui est préremplie), ainsi que certaines données de la table 2 (un ou plusieurs id(s) ainsi qu'un poids par id que l'utilisateur à choisi auparavant).

    Mon souci : je dois effectuer un calcul pour chaque id ainsi que la somme de ces calculs. En fonction du poids que l'utilisateur à choisi pour chaque id, l'affichage des données de la table 1 doit être modifié.

    Exemple :
    L'utilistateur à choisi un poids de 50gr pour un aliment 1 (table 2)
    Puis il a choisi un poids de 120gr pour un aliment 2 (table 2)
    etc...

    Les valeurs affichées par défaut (table 1) sont les valeurs pour 100gr

    Dans ma vue j'aimerais afficher dans un tableau avec les valeurs calculées pour chaque aliment (valeur calculée = valeur initiale x poids choisi / 100) ainsi que la somme des valeurs calculées.

    Voici mon script (qui fonctionne) lorsque l'utilisateur choisi son poids :

    <script type="text/javascript">
      $(function () {
        $("#calcul").click(function (e) {
          e.preventDefault();
          var valeur = $("#myTextBox").val();
          if (valeur == "" || valeur == 0) {
            alert('Entrez une valeur dans la cellule !');
            return;
          }
    
          $("#nutrition > tbody > tr").each(function () {
            var valeurOrigin = parseFloat($(this).find("td").eq(1).text().replace(",", "."));
            var newValeur;
            if ($.isNumeric(valeurOrigin) === true) {
              newValeur = valeurOrigin*valeur/100;
              newValeur = Math.ceil(newValeur*1000)/1000;
              //newValeur = "<"+(valeurOrigin*valeur/100);
            } else {
              newValeur = $(this).find("td").eq(1).text();
            }
    
            $(this).find("td").eq(2).html(newValeur);
          });
        });
      });

    et un bout de ma vue :

    <table class="table table-striped" id="nutrition">
      <thead>
        <tr>
          <th>Aliments</th>
          <th>Poids</th>
          <th>Energie kJ</th>
          <th>Vitamine B12</th>
        </thead>
    
          <tbody class="text-primary">
          @foreach ($menu->ciquals as $menuCiqual)
          <tr><td>{{ $menuCiqual->ciqual->name}}:</td><td><strong>{{ $menuCiqual->quantite}}gr</strong></td>
            <td onload="">{{ $menuCiqual->ciqual->energie_kJ  }}</td>
            <td>{{ $menuCiqual->ciqual->vit_b12 }}</td>
          </tr>
          @endforeach
          <tr><td>Total</td><td><strong>{{ $menuCiqual->where('menu_id', $menuCiqual->menu->id)->sum('quantite')}}gr</strong></td></tr>
        </tr>
          </tbody>
        </table>

    Je ne sais pas comment modifier mon code pour arriver au résultat souhaité.
    Je ne maitrise pas du tout le javascript, je débute...si quelqu'un pouvait m'aider ?
    Merci d'avance !

    • Partager sur Facebook
    • Partager sur Twitter
      24 mars 2017 à 14:11:13

      Salut,

      Peut tu nous mettre un rendu html de ton code php ?

      • Partager sur Facebook
      • Partager sur Twitter
        24 mars 2017 à 14:44:54

        Voilà le rendu html : je récupère bien les valeurs de la table 1 mais avec les valeurs par défaut pour 100gr 

        • Partager sur Facebook
        • Partager sur Twitter
          24 mars 2017 à 15:49:27

          Je me suis mal exprimé, je parlé du rendu texte html, pas en image :D.

          Désolé 

          • Partager sur Facebook
          • Partager sur Twitter
            24 mars 2017 à 17:25:52

            excuse moi, je dois être un peu bête, mais je ne comprend pas comment tu le veux ? 

            Tu veux parler des foreach ? 

            J'ai 2 tables de ma base de données:

            1 "ciquals" : préremplie avec plus de 500 lignes (id) et des valeurs par défaut pour 100gr

            1 "menuCiqual" qui contient les valeurs choisies par l'utilisateur, notamment certains ids de la table "ciquals" mais avec ses propres quantités 

            Les 2 tables sont liées par l'id 

            Dans mon foreach j'appelle les colonnes de la table "ciquals" avec le contenu des ids choisis par l'utilisateur (table "menuCiqual"). Dans cette même table (menuCiqual), je stoque les quantités personnalisées.

            J'ai besoin de récupérer le résultat de la valeur par défaut (table ciquals) x la quantité (table menuCiqual) / 100.

            Je pensais qu'avec un code js un peu similaire à celui que j'ai mis plus haut je pourrais y arriver...mais je ne trouve pas

            • Partager sur Facebook
            • Partager sur Twitter
              24 mars 2017 à 17:55:34

              Ce que je voulais c'etait le html. Faire click droit sur la page -> Afficher la source.

              Sa me permet d'avoir la base html pour comprendre et corrigé le javascript.

              • Partager sur Facebook
              • Partager sur Twitter
                24 mars 2017 à 19:37:31

                Ah d'accord ! excuse moi. Le voilà :

                <!DOCTYPE html>
                <html lang="en">
                <head>
                    <meta charset="utf-8">
                    <meta http-equiv="X-UA-Compatible" content="IE=edge">
                    <meta name="viewport" content="width=device-width, initial-scale=1">
                
                
                    <!-- CSRF Token -->
                    <meta name="csrf-token" content="mvdo9U8yPhx4OZ5JMi8PYtgyIvrZhBY5PUTkStnQ">
                
                    <title>JM&#039;MB</title>
                
                    <!-- Styles -->
                    <!-- Latest compiled and minified CSS -->
                    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/css/bootstrap.min.css" integrity="sha384-AysaV+vQoT3kOAXZkl02PThvDr8HYKPZhNT5h/CXfBThSRXQ6jW5DO2ekP5ViFdi" crossorigin="anonymous">
                    <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet">
                    <!-- Latest compiled and minified JavaScript -->
                
                    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/js/bootstrap.min.js" integrity="sha384-BLiI7JTZm+JWlgKa0M0kGRpJbF2J8q+qreVrKBC47e3K6BW78kGLrCkeRX6I9RoK" crossorigin="anonymous"></script>
                    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
                
                    <script>
                        window.Laravel = {"csrfToken":"mvdo9U8yPhx4OZ5JMi8PYtgyIvrZhBY5PUTkStnQ"}    </script>
                </head>
                <body>
                
                        <div class="container">
                        <script type="text/javascript">
                
                  $(function () {
                      $("#nutrition > tbody > tr").each(function () {
                        var valeurOrigin = parseFloat($(this).find("td").eq(1).text().replace(",", "."));
                        var newValeur;
                        if ($.isNumeric(valeurOrigin) === true) {
                          newValeur = valeurOrigin*valeur/100;
                          newValeur = Math.ceil(newValeur*1000)/1000;
                          //newValeur = "<"+(valeurOrigin*valeur/100);
                        } else {
                          newValeur = $(this).find("td").eq(1).text();
                        }
                
                        $(this).find("td").eq(2).html(newValeur);
                      });
                    });
                  });
                </script>
                
                <div class="container">
                  <div class="row col-md-offset-2 col-md-14">
                    <div class="card card-heading">
                      <h2>Critères</h2>
                    </div>
                
                <input class="btn btn-primary pull-right" type="submit" value="Retour" onclick="history.go(-1)" /></p>
                <h2>Menu1</h2>
                <div style="overflow-x:scroll;;">
                <table class="table table-striped" id="nutrition">
                  <thead>
                    <tr>
                      <th>Aliments</th>
                      <th>Poids</th>
                      <th>Energie kJ</th>
                      <th>Energie kcal</th>
                      <th>Proteines</th>
                
                    </thead>
                      <tbody class="text-primary">
                            <tr><td>Pain grillé, domestique:</td><td><strong>20gr</strong></td>
                        <td>1430</td>
                        <td>336</td>
                        <td>9,56</td>
                
                      </tr>
                            <tr><td>Cabillaud, cuit à la vapeur:</td><td><strong>40gr</strong></td>
                        <td>350</td>
                        <td>82,7</td>
                        <td>18,6</td>
                
                      </tr>
                            <tr><td>Total</td><td><strong>60gr</strong></td></tr>
                    </tr>
                      </tbody>
                    </table>
                   </div>
                  </div>
                </div>
                      </div>
                    </div>
                    <!-- Scripts -->
                    <script src="/js/app.js"></script>
                </body>
                </html>



                -
                Edité par Armelle2703 31 mars 2017 à 10:54:26

                • Partager sur Facebook
                • Partager sur Twitter
                  28 mars 2017 à 9:45:45

                  En fait ce que j'aimerais faire mais je n'y arrive pas car je suis trop novice en js, c'est modifier ce code :

                    $(function () {
                      $("#calcul").click(function (e) {
                        e.preventDefault();
                        var valeur = $("#myTextBox").val();
                        if (valeur == "" || valeur == 0) {
                          alert('Entrez une valeur dans la cellule !');
                          return;
                        }
                  
                        $("#nutrition > tbody > tr").each(function () {
                          var valeurOrigin = parseFloat($(this).find("td").eq(1).text().replace(",", "."));
                          var newValeur;
                          if ($.isNumeric(valeurOrigin) === true) {
                            newValeur = valeurOrigin*valeur/100;
                            newValeur = Math.ceil(newValeur*1000)/1000;
                            //newValeur = "<"+(valeurOrigin*valeur/100);
                          } else {
                            newValeur = $(this).find("td").eq(1).text();
                          }
                  
                          $(this).find("td").eq(2).html(newValeur);
                        });
                      });
                    });
                  

                  qui fonctionne très bien lorsque je rentre une valeur dans la textbox.

                  J'aimerai le modifier en disant au lieu de rentrer une valeur dans la textbox, je récupère ma valeur existante (dans ma table) et j'effectue le calcul.

                  Et je fais la même chose pour chaque ligne

                  Et enfin je fais le total de chaque colonne.

                  Quelqu'un pourrait m'aider ?

                  • Partager sur Facebook
                  • Partager sur Twitter
                    31 mars 2017 à 14:43:30

                    Re,

                    Dans le code html fourmis, il n'y a pas de bouton, n'y de champ modifiable (#myTextBox).
                    Sinon a quoi correspond la valeur de myTextBox, au poids total ou un la valeur d'une ligne ?
                     

                    • Partager sur Facebook
                    • Partager sur Twitter
                      2 avril 2017 à 16:32:34

                      Bonjour GannoN,

                      Merci d'essayer d'aider une vrai novice en js...

                      La valeur de myTextBox correspond à la valeur d'une ligne.

                      Le bouton, je l'avais retiré car il ne devait pas me servir pour cette page. Je sais que la première partie du code était une textbox à remplir et le bouton sert à valider le poids rentré dans la textbox. C'est cette partie que je veux modifier :

                      - récupérer les valeurs des lignes concernées :

                      <tr><td>Pain grillé, domestique:</td><td><strong>20gr</strong></td>
                              <td>1430</td>
                              <td>336</td>
                              <td>9,56</td>
                       
                            </tr>
                                  <tr><td>Cabillaud, cuit à la vapeur:</td><td><strong>40gr</strong></td>
                              <td>350</td>
                              <td>82,7</td>
                              <td>18,6</td>

                      etc...

                      - effectuer pour chaque ligne la deuxième partie du calcul (#nutrition)

                      - puis effectuer pour chaque colonne le total des valeurs récupérées (par exemple : pain grillé 1430 + cabillaud 350 + etc.. pour la première colonne, et ainsi de suite pain grillé 336 + cabillaud 82.7 + etc..)

                      • Partager sur Facebook
                      • Partager sur Twitter
                        2 avril 2017 à 23:53:10

                        Re, 

                        Je test un peut ton truc je croi d'apres ce que j'ai comprit,
                        Regarde et adapte, si ta des question va-y ! pose les.

                        https://www.w3schools.com/code/tryit.asp?filename=FE038IB4AR9B

                        <!DOCTYPE html>
                        <html lang="en">
                          <head>
                            <meta charset="utf-8">
                            <meta http-equiv="X-UA-Compatible" content="IE=edge">
                            <meta name="viewport" content="width=device-width, initial-scale=1">
                            <!-- CSRF Token -->
                            <meta name="csrf-token" content="mvdo9U8yPhx4OZ5JMi8PYtgyIvrZhBY5PUTkStnQ">
                            <title>JM&#039;MB</title>
                            <!-- Styles -->
                            <!-- Latest compiled and minified CSS -->
                            <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/css/bootstrap.min.css" integrity="sha384-AysaV+vQoT3kOAXZkl02PThvDr8HYKPZhNT5h/CXfBThSRXQ6jW5DO2ekP5ViFdi" crossorigin="anonymous">
                            <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet">
                            <!-- Latest compiled and minified JavaScript -->
                            <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/js/bootstrap.min.js" integrity="sha384-BLiI7JTZm+JWlgKa0M0kGRpJbF2J8q+qreVrKBC47e3K6BW78kGLrCkeRX6I9RoK" crossorigin="anonymous"></script>
                            <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
                            <script>
                              window.Laravel = {"csrfToken":"mvdo9U8yPhx4OZ5JMi8PYtgyIvrZhBY5PUTkStnQ"}    
                            </script>
                          </head>
                          <body>
                            <div class="container">
                              <div class="container">
                                <div class="row col-md-offset-2 col-md-14">
                                  <div class="card card-heading">
                                    <h2>Critères</h2>
                                  </div>
                                  <input class="btn btn-primary pull-right" type="submit" value="Retour" onclick="history.go(-1)" /></p>
                                  <h2>Menu1</h2>
                                  <div style="overflow-x:scroll;;">
                        
                        
                        <table class="table table-striped" id="nutrition">
                            <thead>
                            <tr>
                                <th>Aliments</th>
                                <th>Poids (Gr)</th>
                                <th>Energie kJ</th>
                                <th>Energie kcal</th>
                                <th>Proteines</th>
                            </thead>
                            <tbody class="text-primary">
                            <tr>
                                <td>Pain grillé, domestique:</td>
                                <td><input type="text" value="20gr"></td>
                                <td data-for100="1430">1430</td>
                                <td data-for100="336">336</td>
                                <td data-for100="9.56">9,56</td>
                            </tr>
                            <tr>
                                <td>Cabillaud, cuit à la vapeur:</td>
                                <td><input type="text" value="40gr"></td>
                                <td data-for100="350">350</td>
                                <td data-for100="82.7">82,7</td>
                                <td data-for100="18.6">18,6</td>
                            </tr>
                            </tbody>
                            <tfoot>
                                <td>Total</td>
                                <td><strong>60gr</strong></td>
                                <td data-for100="350">350</td>
                                <td data-for100="82.7">82,7</td>
                                <td data-for100="18.6">18,6</td>
                            </tfoot>
                        
                        </table>
                        
                        
                        
                                  </div>
                                </div>
                              </div>
                            </div>
                            </div>
                        
                        <script>
                            (function(){
                                let table = document.querySelector('#nutrition')
                                let tBodyElems = table.querySelector('tbody')
                                let trElems = [...tBodyElems.querySelectorAll('tr')].map(tr => {
                                    let td = [...tr.querySelectorAll('td')]
                                    td.input = tr.querySelector('input')
                                    td.tr = tr
                                    return td
                                })
                        
                        
                                let tFoot = table.querySelector('tfoot')
                                let tFootTd = [...tFoot.querySelectorAll('td')]
                        
                                const updateTotal = function () {
                                    tFootTd.forEach( (tdFoot, i) => {
                                        if (i === 0) { return }
                                        if (i === 1) {
                                            let total = trElems.reduce( (a, e) => {
                                                return a + ( parseInt(e.input.value))
                                            }, 0)
                                            tdFoot.textContent = total
                                        } else {
                                            let total = trElems.reduce( (a, e) => {
                                                return a + ( parseFloat(e[i].dataset.curValue) || parseInt(e.input))
                                            }, 0)
                                            tdFoot.textContent = Math.round(total * 100) / 100 
                                        }
                                        
                                    })
                                }
                        
                                const updateRow = function (trElement) {
                                    let value = parseFloat(trElement.input.value.replace(',','.'))
                                    if (value === NaN) { return }
                        
                                    [...trElement].splice(2).forEach( e => {
                                        let newValue = Math.round(parseFloat(e.dataset.for100) * value) / 100
                                        e.textContent = newValue
                                        e.dataset.curValue = newValue
                                    })            
                                }
                        
                                const updateAll = function () {
                                    trElems.forEach(updateRow)
                                    updateTotal()
                                }
                        
                                const debounce = function (func, wait, immediate) {
                                    var timeout;
                                    return function() {
                                        var context = this, args = arguments;
                                        var later = function() {
                                            timeout = null;
                                            if (!immediate) func.apply(context, args);
                                        };
                                        var callNow = immediate && !timeout;
                                        clearTimeout(timeout);
                                        timeout = setTimeout(later, wait);
                                        if (callNow) func.apply(context, args);
                                    };
                                };
                        
                                window.addEventListener('DOMContentLoaded', updateAll)
                                trElems.forEach( tr => {
                                    tr.input.addEventListener('keydown', debounce(() => { updateRow(tr), updateTotal() }, 250 ))
                                })
                        
                            })()
                        </script>
                        
                          </body>
                        </html>



                        • Partager sur Facebook
                        • Partager sur Twitter
                          16 mai 2017 à 18:59:04

                          @GannoN, désolée pour le délai de réponse... merci beaucoup pour ce script, ça fonctionne ! Je t'avoue que pour une débutante en js j'ai un peu du mal à tout comprendre...Par exemple quelle partie du code fait que la page se rafraichie immédiatement si on change la quantité ?

                          Par contre j'ai un problème, j'ai des cellules qui contiennent du texte comme "traces" ou "nc" ou encore "< 70" par exemple. Du coup comme ce n'est pas numérique, ça m'affiche NaN. Ainsi que dans les totaux.

                          dans mon ancien code la condition était :

                          } else {
                                  newValeur = $(this).find("td").eq(1).text();



                          Est-ce que la partie de code à modifier est celle-là ?

                              const updateRow = function (trElement) {
                                  let value = parseFloat(trElement.input.value.replace(',','.'))
                                  if (value === NaN) { return }
                          
                                  [...trElement].splice(2).forEach( e => {
                                      let newValue = Math.round(parseFloat(e.dataset.for100) * value) / 100
                                      e.textContent = newValue
                                      e.dataset.curValue = newValue
                                  })
                              }
                          

                          Merci d'avance si tu as le temps de me répondre

                          • Partager sur Facebook
                          • Partager sur Twitter

                          Calculs à partir des données de 2 tables

                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                          • Editeur
                          • Markdown