1
votes

javascript ajouter un nouveau formulaire

J'ai créé un javascript html css, un arbre lorsque vous sélectionnez une option, une autre option sera visible (selon la première option sélectionnée) dans cet exemple il n'y a que 2 options.

le problème est qu'à la fin , il y a un bouton qui devrait ajouter un nouveau formulaire (ligne) avec les mêmes options, pour tout recommencer, quand je clique sur ce bouton, il ajoute une nouvelle ligne mais le script ne fonctionne pas, je ne sais pas comment le réparer!

Voici un JSFiddle

p >

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
  <div class="row-fluid">
    <table style="font-size:10px">
      <tbody>
        <tr>
          <td>
            <select id="Volum">
              <option value="1x ">1x </option>
              <option value="2x ">2x </option>
              <option value="3x ">3x </option>
              <option value="4x ">4x </option>
              <option value="5x ">5x </option>
              <option value="6x ">6x</option>
            </select>
          </td>
          <td>
            <select id="produse">
              <option value="reset">Selecteaza Produs</option>
              <option value="Coltare">Coltare</option>
              <option value="Seturi">Seturi</option>
            </select>
          </td>
          <td>
            <select id="ModeleColtare" class="sub_select_class">
              <option value="Coltar Vera">Coltar Vera</option>
              <option value="Coltar Onix">Coltar Onix</option>
              <option value="Coltar Olyve">Coltar Olyve</option>
              <option value="Coltar Adrian">Coltar Adrian</option>
            </select>
          </td>
          <td>
            <select id="ModeleSeturi" class="sub_select_class">
              <option value="Set Dana">Set Dana</option>
              <option value="Set Ramona">Set Ramona</option>
              <option value="Set Gina">Set Gina</option>
              <option value="Set Olyve">Set Olyve</option>
            </select>
          </td>
          <td>
            Alte Detalii: <textarea rows="1" style="width:120px;"></textarea> Pret: <input type="text" size="3" /> </td>
          <td>
            <button id="filter" name="filter" onclick="resetFunction()">Reset</button>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</div>
<div>
  <button id="addMore" class="btn btn-sm btn-primary"><i class="fa fa-dot-circle-o"></i> Add Row</button></div>
#ModeleColtare,
#ModeleSeturi {
  display: none;
}

.new-rect {
  background: black;
  width: 100%;
  height: 30px;
}
$("#addMore").click(function() {
  $(".row-fluid:last").clone().appendTo(".wrapper");
});

$("#produse").change(function() {
  var $this = $(this),
    value = $this.val(); // save value
  $('.sub_select_class').hide(); // we hide every second select
  switch (value) { // we show only what needs to be visible
    case 'Canapele':
      $("#ModeleCanapele").show();
      break;
    case 'Coltare':
      $("#ModeleColtare").show();
      break;
    case 'Mobila':
      $("#ModeleMobila").show();
      break;
    case 'Fotolii':
      $("#ModeleFotolii").show();
      break;
    case 'Seturi':
      $("#ModeleSeturi").show();
      break;
      // ...etc
  }
});


6 commentaires

Bienvenue dans Stack Overflow. Dans sa forme actuelle, il est peu probable que votre question reçoive beaucoup de réponses utiles. Veuillez lire les articles du centre d'aide pour savoir comment poser une bonne question. En particulier, vous voudrez peut-être expliquer exactement ce qui ne fonctionne pas, "mais le script ne fonctionne pas, je n'ai aucune idée de comment le réparer" n'aide personne à comprendre ce qui se passe.


Chaque ligne a une sélection avec l'ID "produse". L'identifiant est censé être unique par élément sur une page. Utilisez plutôt la classe.


@ChrisPickford C'était clair pour moi.


stackoverflow.com/questions/203198/… < / a>


Je comprends ce que vous avez dit, le problème est que je ne pourrai pas ajouter plus de classes.le script ne fonctionnera pas


Pirjol, chaque élément doit avoir un attribut attaché OU une sorte de "conteneur" pour la ligne qui désigne de quel numéro de ligne il s'agit. Ou vous pouvez utiliser child nth pour sélectionner une ligne spécifique. Vous pouvez le faire de manière dynamique en utilisant des classes, puis quand une sélection (produit) est modifiée, découvrir le nombre de lignes au-dessus, puis sélectionner les autres éléments en utilisant leur nom de classe (PAS ID) et le numéro de ligne (enfant nième)


3 Réponses :


-1
votes

Lorsque vous ajoutez l'élément à la page, il n'hérite pas de la fonction on 'change' que vous Vous avez également id = "produse" et vous aurez des ID en double ... Changez ceci en class = "produse" au lieu de id! Ce que vous devez faire est d'envelopper ceci dans une fonction ...

$("#addMore").click(function(){   
    var rows = $(".produse").length,
    newRowNumber = rows + 1
    $(".row-fluid:last").clone().appendTo(".wrapper")
    // make sure all of the rowNumber attributes = newRowNumber here
    initiateProduse() // add the effect to new row
});

Maintenant, il y aura toujours des problèmes ... Tous les effets de show "#Modele ...." ne seront pas fonctionnent car il y a des ID en double. Vous avez besoin d'un moyen de spécifier QUEL élément vous devez utiliser ...

Je recommande des attributs. Vous pouvez donner à chaque sélection / entrée une valeur comme ModeleCanapele = "1", puis quand une deuxième ligne est ajoutée, elle aura ModeleCanapele = "2"

Ensuite, vous feriez quelque chose comme ... p >

var rowNumber = $(this).attr('rowNumber')
$('[sub_select_class="'+rowNumber+'"]').hide(); // change to attribute instead of class select 
switch(value) { // we show only what needs to be visible
           case 'Canapele':
             $("[ModeleCanapele='"+rowNumber+"']").show();
             break;

Vous pouvez suivre le rowNumber en faisant quelque chose comme ...

<select class="produse" rowNumber="1"> 

pour le premier ...

et à l'intérieur de la nouvelle fonction que vous utilisez, vous pouvez faire ...

$("[ModeleCanapele='"+newRowNumber+"']").show(); 

Pour définir le NOUVEAU numéro de ligne, nous ferions quelque chose comme ça ...

$("#addMore").click(function(){   
    $(".row-fluid:last").clone().appendTo(".wrapper"); 
    initiateProduse() // add the effect to new row
});
    function initiateProduse(){
     $(".produse").off("change"); // remove on change effects so it doesn't have double on change effects on existing rows...
     $(".produse").change(function(){
        var $this = $(this), value = $this.val(); // save value
        $('.sub_select_class').hide(); // we hide every second select
        switch(value) { // we show only what needs to be visible
           case 'Canapele':
             $("#ModeleCanapele").show();
             break;
           case 'Coltare':
             $("#ModeleColtare").show();
             break;
             case 'Mobila':
             $("#ModeleMobila").show();
             break;
             case 'Fotolii':
             $("#ModeleFotolii").show();
             break;
             case 'Seturi':
             $("#ModeleSeturi").show();
             break;
           // ...etc
        }
     });
    }

    initiateProduse() // initiate the change effect on page load

Je n'ai pas assez de temps pour faire tout le code pour vous, mais voici comment vous pouvez le faire. Vous devez vous assurer que chaque sélection / entrée a un attribut et un identifiant de classe au lieu d'un ID et vous assurer que le numéro de ligne est ajouté (+1) chaque fois que vous ajoutez une ligne

Un moyen beaucoup plus simple serait pour inclure réellement le modèle HTML dans le JS afin que vous puissiez utiliser une variable pour définir le nouveau numéro de ligne à chaque fois (au lieu d'utiliser le clonage)


6 commentaires

Utilisez simplement la délégation au lieu d'appeler initate, ce qui ajoutera et ajoutera des gestionnaires d'événements encore et encore sur toutes les sélections. Voir ma réponse pour une meilleure méthode


Vous avez raison à propos de la délégation d'événements ~ de toute façon, cela fonctionnera toujours. Le principal problème du PO est sans aucun doute l'utilisation d'identifiants au lieu de classes et / ou d'attributs.


Si vous continuez d'appeler initateProduse (), les événements se multiplieront sur toutes les sélections existantes


Il désactive les effets de changement des anciennes lignes .produse avant d'en appliquer de nouvelles


Ah vrai. TRÈS inefficace


Absolument, oui.



0
votes
  1. Les identifiants doivent être uniques. Utilisez une classe
  2. Vous devez déléguer les gestionnaires d'événements lorsque vous insérez du contenu dynamique
  3. SEC, ne vous répétez pas
  4. <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="wrapper">
      <div class="row-fluid">
        <table style="font-size:10px">
          <tbody>
            <tr>
              <td>
                <select class="Volum">
                  <option value="1x ">1x </option>
                  <option value="2x ">2x </option>
                  <option value="3x ">3x </option>
                  <option value="4x ">4x </option>
                  <option value="5x ">5x </option>
                  <option value="6x ">6x</option>
                </select>
              </td>
              <td>
                <select class="produse">
                  <option value="reset">Selecteaza Produs</option>
                  <option value="Coltare">Coltare</option>
                  <option value="Seturi">Seturi</option>
                </select>
              </td>
              <td>
                <select class="ModeleColtare sub_select_class">
                  <option value="Coltar Vera">Coltar Vera</option>
                  <option value="Coltar Onix">Coltar Onix</option>
                  <option value="Coltar Olyve">Coltar Olyve</option>
                  <option value="Coltar Adrian">Coltar Adrian</option>
                </select>
              </td>
              <td>
                <select class="ModeleSeturi sub_select_class">
                  <option value="Set Dana">Set Dana</option>
                  <option value="Set Ramona">Set Ramona</option>
                  <option value="Set Gina">Set Gina</option>
                  <option value="Set Olyve">Set Olyve</option>
                </select>
              </td>
              <td>
                Alte Detalii: <textarea rows="1" style="width:120px;"></textarea> Pret: <input type="text" size="3" /> </td>
              <td>
                <button class="filter" name="filter">Reset</button>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
    <div>
      <button id="addMore" class="btn btn-sm btn-primary"><i class="fa fa-dot-circle-o"></i> Add Row</button></div>
    .sub_select_class {
      display: none;
    }
    
    .new-rect {
      background: black;
      width: 100%;
      height: 30px;
    }
    function resetFunction() { // not sure what you want here? 
      $(this).closest(".row-fluid").remove(); 
    }
    
    $(function() {
      $("#addMore").click(function() {
        var $clone = $(".row-fluid:last").clone(true)
        $('.sub_select_class',$clone).hide(); // we hide every second select    
        $clone.appendTo(".wrapper");
      });
    
      $(".row-fluid").on("click",".filter", resetFunction);
    
      $(".row-fluid").on("change", ".produse", function() {
        var value = $(this).val(), // save value
            $parent = $(this).closest(".row-fluid");
        $('.sub_select_class',$parent).hide(); // we hide every second select
        $(".Modele" + value,$parent).show();
      });
    });

0 commentaires

0
votes

Le problème est que vous génériez une nouvelle ligne, mais vous référeniez toujours la première ligne (et vous le faisiez via votre utilisation naïve des identifiants). Au lieu de cela, votre code doit fonctionner uniquement sur une ligne spécifique à la fois - donc, j'ai modifié votre code pour passer une référence à la ligne, nous pouvons alors utiliser vos mêmes sélecteurs JQuery, mais à partir de la ligne référencée.

REMARQUE: plusieurs autres ont blâmé l'utilisation d'identifiants en double, mais ce n'est clairement pas le problème. Le fait est que vous POUVEZ utiliser des identifiants en double , et il est courant de le faire dans de telles situations.

Pour être clair, la spécification HTML actuelle indique que:

Si la valeur de l'id n'est pas la chaîne vide, elle doit être unique dans un document. ref

Mais, en tant que notes de discussion d'échange de piles séparées , ce n'est pas le cas en pratique (et ne le sera probablement jamais). En pratique, l'ID ne devrait être unique que dans une portée, comme dans un composant réutilisable (c'est-à-dire, votre ) clonable .

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
  <div class="row-fluid">
    <table style="font-size:10px">
      <tbody>
        <tr>
          <td>
            <select id="Volum">
              <option value="1x ">1x </option>
              <option value="2x ">2x </option>
              <option value="3x ">3x </option>
              <option value="4x ">4x </option>
              <option value="5x ">5x </option>
              <option value="6x ">6x</option>
            </select>
          </td>
          <td>
            <select id="produse">
              <option value="reset">Selecteaza Produs</option>
              <option value="Coltare">Coltare</option>
              <option value="Seturi">Seturi</option>
            </select>
          </td>
          <td>
            <select id="ModeleColtare" class="sub_select_class">
              <option value="Coltar Vera">Coltar Vera</option>
              <option value="Coltar Onix">Coltar Onix</option>
              <option value="Coltar Olyve">Coltar Olyve</option>
              <option value="Coltar Adrian">Coltar Adrian</option>
            </select>
          </td>
          <td>
            <select id="ModeleSeturi" class="sub_select_class">
              <option value="Set Dana">Set Dana</option>
              <option value="Set Ramona">Set Ramona</option>
              <option value="Set Gina">Set Gina</option>
              <option value="Set Olyve">Set Olyve</option>
            </select>
          </td>
          <td>
            Alte Detalii: <textarea rows="1" style="width:120px;"></textarea> Pret: <input type="text" size="3" /> </td>
          <td>
            <button id="filter" name="filter" onclick="resetFunction()">Reset</button>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</div>
<div>
  <button id="addMore" class="btn btn-sm btn-primary"><i class="fa fa-dot-circle-o"></i> Add Row</button></div>
#ModeleColtare,
#ModeleSeturi {
  display: none;
}

.new-rect {
  background: black;
  width: 100%;
  height: 30px;
}
$("#addMore").click(function() {
  var newRow = $(".row-fluid:last").clone();
  
  newRow.appendTo(".wrapper");
  
  newRow.find('.sub_select_class').hide();
  
  newRow.find( "#produse" ).change(function(){
    produseChange(this, newRow);
  });
});


$("#produse").change(function() {
  produseChange(this, $('tr')); 
});


function produseChange(self, row)  {
  var $this = $(self),
  value = $this.val(); // save value
  row.find('.sub_select_class').hide(); // we hide every second select
  switch (value) { // we show only what needs to be visible
    case 'Canapele':
      row.find("#ModeleCanapele").show();
      break;
    case 'Coltare':
      row.find("#ModeleColtare").show();
      break;
    case 'Mobila':
      row.find("#ModeleMobila").show();
      break;
    case 'Fotolii':
      row.find("#ModeleFotolii").show();
      break;
    case 'Seturi':
      row.find("#ModeleSeturi").show();
      break;
      // ...etc
  }
}


4 commentaires

J'ai édité le script BIG et il semble que la première ligne fonctionne comme un charme, mais lorsque j'ajoute une nouvelle ligne ne fonctionne toujours pas - jsfiddle.net/te7hxzbd/1


J'ai juste essayé votre jsfiddle, et j'ai pu ajouter plus de lignes sans problème. Comment ça ne marche pas?


si vous sélectionnez sur la première ligne par exemple canapele alors vous sélectionnez canapea dana, d'autres options apparaissent mais si vous ajoutez une nouvelle ligne et faites de même, cela ne fonctionnera pas


D'accord, je vois. Vous continuez à faire votre erreur d'origine avec les événements .change restants. Vous devrez adapter ma solution au reste de votre code, c'est-à-dire $ ("# ModeleMobila"). Change (...) doit devenir newRow.find ("# ModeleMobila"). Change (...). Donc, assurez-vous simplement de bien comprendre ce que fait mon code, puis vous pourrez terminer vous-même le code restant