Пользовательское сообщение jQuery Validate plugin отображается только на первом входе входного массива - PullRequest
0 голосов
/ 12 октября 2018

Контекст

У меня многоэтапная форма, и я пытаюсь проверить каждый шаг формы ( необходимо заполнить все поля ввода )

После поиска инайти рабочее решение для проверки нескольких входных данных массива:

$("[name^=serialNbs]").each(function() {
  $(this).rules("add", {
    required: true,
    messages: {
     required: "Il faut remplir le numéro de série"
    }
  });
});

У меня все еще есть проблема, связанная с сообщением.

Проблема

Мое личное сообщение показывает толькона первом входе (3-й шаг)

Validate step 3

Фрагмент

Вот фрагмент, просто выберите параметры радио по умолчанию ( Computer & Sonceboz ) на первом шаге , укажите количество от 1 до 10 на втором шаге и попробуйте перейти на третий шаг без заполнения ввода

$(document).ready(function() {
  var id, current_div;
  var valid = $("#add_to_stock").validate({
    rules: {
      pc_quantity: {
        required: true,
        range: [1, 10],
        digits: true
      },
      /*pc_model:{
          required: true
      },
      hard_type:{
          required: true
      },
      hard_model:{
          required: true
      },*/
      hard_quantity: {
        required: true,
        range: [1, 10],
        digits: true
      }
    },
    messages: {
      pc_quantity: "La quantité doit être entre 1 et 10",
      pc_model: "Il faut choisir un modèle",
      hard_type: "Il faut choisir un type",
      hard_model: "Il faut choisir un modèle",
      hard_quantity: "La quantité doit être entre 1 et 10"

    },
    highlight: function(element) {
      $(element).closest('.form-group').addClass('has-error');
    },
    unhighlight: function(element) {
      $(element).closest('.form-group').removeClass('has-error');
    },
    errorElement: 'span',
    errorClass: 'help-block',
    errorPlacement: function(error, element) {
      if (element.hasClass('select2')) {
        error.insertAfter(element.next('span'));
      } else {
        error.insertAfter(element);
      }
    }
  });


  $("[name^=serialNbs]").each(function() {
    $(this).rules("add", {
      required: true,
      messages: {
        required: "Il faut remplir le numéro de série"
      }
    });
  });




  $.fn.select2.defaults.set("theme", "bootstrap");
  $(".select2").select2({
    selectOnClose: true
  });

  $('.select2').on('change', function() {
    $(this).valid();
  });

  //empeche l'envoi du formulaire on tappant la touche enter
  $(document).on("keypress", "form", function(event) {
    return event.keyCode != 13;
  });

  //évenements click des buttons "suivant"
  $(".go_to_step_2").click(function() {
    var option_val = $('input[name=mat_type]:checked').val();
    //console.log(option_val);

    switch (option_val) {
      case 'computer':
        $('#step1').hide();
        $('#step2a').show();
        break;
      case 'hardware':
        $('#step1').hide();
        $('#step2b').show();
        break;
      case 'contract':
        $('#step1').hide();
        $('#step2c').show();
        break;
      default:
    }
  });

  $.ajax('./sources/computer_models.txt', {
    dataType: 'text',
    success: function(text) {

      var data = text.split("\n").map(function(item) {
        var typeIdName = item.split(':');
        return {
          'id': typeIdName[0],
          'text': typeIdName[1]
        };
      });
      //console.log(data);
      $('#pc_model').select2({
        'data': data,
        placeholder: "Selectionnez un modèle",
        allowClear: true
      });
    }
  });

  $.ajax('./sources/hardware_types.txt', {
    dataType: 'text',
    success: function(text) {

      var data = text.split("\n").map(function(item) {
        var typeIdName = item.split(':');
        return {
          'id': typeIdName[0],
          'text': typeIdName[1]
        };
      });
      //console.log(data);
      $('#hard_type').select2({
        'data': data,
        placeholder: "Selectionnez un type",
        allowClear: true
      });
    }
  });

  $("#hard_type").on("change", function() {
    var selectedType = $("#hard_type").val();
    //console.log(selectedType);
    $('#hard_model').html('').select2({
      data: [{
        id: '',
        text: ''
      }]
    });
    $.ajax('./sources/hardware_models_' + selectedType + '.txt', {
      dataType: 'text',
      success: function(text) {

        var data = text.split("\n").map(function(item) {
          var typeIdName = item.split(':');
          return {
            'id': typeIdName[0],
            'text': typeIdName[1]
          };
        });
        //console.log(data);
        $('#hard_model').select2({
          'data': data,
          placeholder: "Selectionnez un modèle",
          allowClear: true
        });
      }
    });
  });

  $(".go_to_step_3").click(function() {
    if ($('div').css('display') == 'block' && $('div').hasClass('add_mat')) {
      id = $(".add_mat:visible").attr('id');
    }
    //console.log(id);
    current_div = "#" + id;
    //console.log(current_div);
    if (valid.form()) {
      $(current_div).hide();
      $("#step3").show();
    }

    var option_val = $('input[name=mat_type]:checked').val();
    var quantity;
    switch (option_val) {
      case 'computer':
        quantity = $('input[name=pc_quantity]').val();
        //console.log(quantity);
        break;
      case 'hardware':
        quantity = $('input[name=hard_quantity]').val();
        //console.log(quantity);
        break;
      case 'contract':
        quantity = $('input[name=contr_quantity]').val();
        //console.log(quantity);
        break;
      default:
    }

    //console.log(quantity);
    var wrapper = $('.SN_wrapper');
    var labelField = '';
    var inputField = '';
    var initialInputID = $("input[name*='serialNbs']").attr('id');
    var x = parseInt(initialInputID.split("_")[1]);
    var y = x + 1;

    if (quantity != 1) {
      for (i = 0; i < quantity - 1; i++) {
        if ($("#serialNb_" + y).length == 0) {
          console.log("1: i:" + i + " ; q:" + quantity + " ; y:" + y + " ; x:" + x);
          labelField = '<label for="serialNb_' + y + ' " class="col-sm-2 control-label padding-right">' + 'Numéro de série ' + y + ' :</label>';
          inputField = '<div class="col-sm-10"><input id="serialNb_' + y + '" name="serialNbs[' + y + ']" class="form-control " type="text" value="" required/></div>';
          y++;
          $(wrapper).append(labelField, inputField);
        } else {

          y++;
          $(wrapper).append(labelField, inputField);
        }
      }
    }

  });

  $(".go_to_step_4").click(function() {
    if (valid.form()) {
      $("#step3").hide();
      $("#step4").show();
    }


    var option_val = $('input[name=mat_type]:checked').val();
    var quantity;
    var opt_site = $('input[name=stock_site]:checked').val();
    var site;
    var model;
    var type;
    var serialNbs = $("input[name*='serialNbs']");
    switch (option_val) {
      case 'computer':
        $("#type_h4").hide();
        if ($("#site").text().length == 0) {
          site = opt_site;
          $("#site").append(site);
        } else {
          if (site != opt_site) {
            $("#site").text('');
            site = opt_site;
            $("#site").append(site);
          } else {
            $("#site").append(site);
          }
        }

        if ($("#model").text().length == 0) {
          model = $('#pc_model option:selected').text();
          $("#model").append(model);
        } else {
          if (model != $('#pc_model option:selected').text()) {
            $("#model").text('');
            model = $('#pc_model option:selected').text();
            $("#model").append(model);
          } else {
            $("#model").append(model);
          }
        }

        if ($("#quant").text().length == 0) {
          quantity = $('input[name=pc_quantity]').val();
          $("#quant").append(quantity);
        } else {
          if (quantity != $('input[name=pc_quantity]').val()) {
            $("#quant").text('');
            quantity = $('input[name=pc_quantity]').val();
            $("#quant").append(quantity);
          } else {
            $("#quant").append(quantity);
          }
        }

        serialNbs.each(function() {
          var eachVal = $(this).val();
          var exists = $('#list_SN li:contains(' + eachVal + ')').length;

          if (!exists) {
            $("#list_SN").append("<li>" + eachVal + "</li>");
          }
        });
        //console.log(model + ";" + quantity);                
        break;
      case 'hardware':

        if ($("#type").text().length == 0) {
          type = $('#hard_type option:selected').text();
          $("#type").append(type);
        } else {
          if (type != $('#hard_type option:selected').text()) {
            $("#type").text('');
            type = $('#hard_type option:selected').text();
            $("#type").append(type);
          } else {
            $("#type").append(type);
          }
        }

        if ($("#model").text().length == 0) {
          model = $('#hard_model option:selected').text();
          $("#model").append(model);
        } else {
          if (model != $('#hard_model option:selected').text()) {
            $("#model").text('');
            model = $('#hard_model option:selected').text();
            $("#model").append(model);
          } else {
            $("#model").append(model);
          }
        }

        if ($("#quant").text().length == 0) {
          quantity = $('input[name=hard_quantity]').val();
          $("#quant").append(quantity);
        } else {
          if (quantity != $('input[name=hard_quantity]').val()) {
            $("#quant").text('');
            quantity = $('input[name=hard_quantity]').val();
            $("#quant").append(quantity);
          } else {
            $("#quant").append(quantity);
          }
        }

        serialNbs.each(function() {
          var eachVal = $(this).val();
          var exists = $('#list_SN li:contains(' + eachVal + ')').length;

          if (!exists) {
            $("#list_SN").append("<li>" + eachVal + "</li>");
          }
        });
        //console.log(type + ";" + model + ";" + quantity);
        break;
      case 'contract':
        quantity = $('input[name=contr_quantity]').val();
        //console.log(quantity);
        break;
      default:
    }
    //console.log(type + ";" + model + ";" + quantity);
  });

  //évenements click des buttons "précédent"

  $(".back_to_step_1").click(function() {
    if ($('div').css('display') == 'block' && $('div').hasClass('add_mat')) {
      id = $(".add_mat:visible").attr('id');
    }

    //console.log(id);
    current_div = "#" + id;
    //console.log(current_div);

    $(current_div).hide();
    $("#step1").show();
  });

  $(".back_to_step_2").click(function() {
    var option_val = $('input[name=mat_type]:checked').val();
    //console.log(option_val);
    var wrapper = $('.SN_wrapper');
    var labelField = '';
    var inputField = '';

    switch (option_val) {
      case 'computer':
        $('#step3').hide();
        $('#step2a').show();
        wrapper.text('');
        labelField = '<label for="serialNb_1 " class="col-sm-2 control-label padding-right">' + 'Numéro de série 1 :</label>';
        inputField = '<div class="col-sm-10"><input id="serialNb_1" name="serialNbs[]" class="form-control" type="text" value="" /></div>';
        $(wrapper).append(labelField, inputField);
        break;
      case 'hardware':
        $('#step3').hide();
        $('#step2b').show();
        wrapper.text('');
        labelField = '<label for="serialNb_1 " class="col-sm-2 control-label padding-right">' + 'Numéro de série 1 :</label>';
        inputField = '<div class="col-sm-10"><input id="serialNb_1" name="serialNbs[]" class="form-control" type="text" value="" /></div>';
        $(wrapper).append(labelField, inputField);
        break;
      case 'contract':
        $('#step3').hide();
        $('#step2c').show();
        wrapper.text('');
        labelField = '<label for="serialNb_1 " class="col-sm-2 control-label padding-right">' + 'Numéro de série 1 :</label>';
        inputField = '<div class="col-sm-10"><input id="serialNb_1" name="serialNbs[]" class="form-control" type="text" value="" /></div>';
        $(wrapper).append(labelField, inputField);
        break;
      default:
    }
  });

  $(".back_to_step_3").click(function() {
    $("#step4").hide();
    $("#step3").show();



  });
});
#add_to_stock fieldset:not(:first-of-type) {
  display: none;
}

.add_mat {
  position: relative;
  min-height: 200px;
}

.container-decisions {
  position: relative;
}

.container-decisions #step1,
#step2,
#step2a,
#step2b,
#step2c,
#step3,
#step4 {
  display: none;
}

.container-decisions #step1 {
  display: block;
}

.no_margin {
  margin: 0;
  padding: 0;
}

.btn {
  min-width: 120px;
}

.label-info {
  font-size: 90%;
}

.has-error input[type="text"],
.has-error input[type="number"],
.has-error select {
  border: 1px solid #a94442;
}

.has-error .select2-selection {
  border-color: rgb(185, 74, 72) !important;
}
<!DOCTYPE html>

<html>

<head>
  <meta charset="UTF-8">
  <title>Gestion du stock</title>
  <!-- Latest compiled and minified CSS -->
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <!-- jQuery library -->
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <!-- Latest compiled JavaScript -->
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
  <!-- Select2 plugin-->
  <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.css" rel="stylesheet" />
  <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.js"></script>
  <link href="https://cdnjs.cloudflare.com/ajax/libs/select2-bootstrap-theme/0.1.0-beta.10/select2-bootstrap.min.css" rel="stylesheet" />

  <!--JQuery Validator-->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.16.0/jquery.validate.min.js"></script>

  <!-- js et css perso-->
  <script type="text/javascript" src="js/stock.js"></script>
  <link rel="stylesheet" type="text/css" href="css/stock.css">

</head>

<body>
  <div class="container">
    <div class="panel-group">
      <div class="panel panel-default">
        <div class="panel-heading">
          <h3>Ajout de nouveau matériel</h3>
        </div>
        <div class="panel-body">
          <div class="container-decisions">
            <form id="add_to_stock" class="form-horizontal" name="add_to_stock" method="post" action="./result.php">

              <div id="step1" class="add_mat">

                <legend>Step 1 of 4</legend>
                <div class="form-group col-sm-12">
                  <label class="control-label">Type de Matériel</label>
                  <div class="radio">
                    <label><input type="radio" name="mat_type" value="computer" checked>Ordinateur</label>
                  </div>
                  <div class="radio">
                    <label><input type="radio" name="mat_type" value="hardware">Hardware</label>
                  </div>
                  <div class="radio disabled">
                    <label><input type="radio" name="mat_type" value="contract" disabled>Contrat</label>
                  </div>
                  <div class="form-group col-sm-12">
                    <label class="control-label">Site du Stock</label>
                    <div class="radio">
                      <label><input type="radio" name="stock_site" value="Sonceboz" checked>Sonceboz</label>
                    </div>
                    <div class="radio">
                      <label><input type="radio" name="stock_site" value="Boncourt">Boncourt</label>
                    </div>
                  </div>
                  <div class="form-group col-sm-12">
                    <div class="col-sm-5 pull-right">
                      <button class="btn btn-success pull-right go_to_step_2" type="button">
                                                    Suivant <span class="glyphicon glyphicon-chevron-right"></span>
                                                </button>
                    </div>
                  </div>
                </div>
              </div>


              <div id="step2a" class="add_mat">
                <legend>Step 2 of 4</legend>
                <div class="form-group col-sm-12 ">
                  <h4 class="text-muted text-uppercase "><strong>Ajouter un ordinateur</strong></h4>

                  <div class="alert alert-warning"><span class="glyphicon glyphicon-warning-sign"></span><strong> Attention :</strong> Il faut remplir tous les champs ! La quantité doit être entre 1 et 10.</div>

                  <div class="form-group">
                    <label class="col-sm-2 control-label" for="pc_model">Modèle :</label>
                    <div class="col-sm-10">
                      <select id="pc_model" name="pc_model" class="select2 form-control" style="width: 100%">
                        <option></option>
                      </select>
                    </div>
                  </div>

                  <div class="form-group no_margin">
                    <div class="col-sm-10">
                      <input id="pc_deploymentState" name="pc_deploymentState" class="form-control" type="hidden" value="Stock new">
                    </div>
                  </div>

                  <div class="form-group no_margin">
                    <div class="col-sm-10">
                      <input id="pc_incidentState" name="pc_incidentState" class="form-control" type="hidden" value="Operational">
                    </div>
                  </div>

                  <div class="form-group cont-quant">
                    <label class="col-sm-2 control-label" for="pc_quantity">Quantité :</label>
                    <div class="col-sm-10">
                      <input id="pc_quantity" name="pc_quantity" class="form-control quantity" type="number" min="1" max="10" value="" required>
                    </div>
                  </div>

                  <div class="form-group col-sm-12">
                    <div class="col-sm-1"></div>
                    <div class="col-sm-5">
                      <button class="btn btn-warning pull-left back_to_step_1" type="button">
                                                    <span class="glyphicon glyphicon-chevron-left"></span> Précédent 
                                                </button>
                    </div>
                    <div class="col-sm-6">
                      <button class="btn btn-success pull-right go_to_step_3" type="button">
                                                    Suivant <span class="glyphicon glyphicon-chevron-right"></span>
                                                </button>
                    </div>
                  </div>
                </div>
              </div>
              <div id="step2b" class="add_mat">

                <legend>Step 2 of 4</legend>
                <div class="form-group col-sm-12">
                  <label class="control-label">Ajouter du hardware</label>

                  <div class="form-group">
                    <label class="col-sm-2 control-label" for="hard_type">Type :</label>
                    <div class="col-sm-10">
                      <select id="hard_type" name="hard_type" class="select2 form-control" style="width: 100%" required>
                        <option></option>
                      </select>
                    </div>
                  </div>

                  <div class="form-group">
                    <label class="col-sm-2 control-label" for="hard_model">Model :</label>

                    <div class="col-sm-10">
                      <select id="hard_model" name="hard_model" class="select2 form-control" style="width: 100%" required>
                        <option></option>
                      </select>
                    </div>
                  </div>

                  <div class="form-group no_margin">
                    <div class="col-sm-10">
                      <input id="hard_deploymentState" name="hard_deploymentState" class="form-control" type="hidden" value="Stock new">
                    </div>
                  </div>

                  <div class="form-group no_margin">
                    <div class="col-sm-10">
                      <input id="hard_incidentState" name="hard_incidentState" class="form-control" type="hidden" value="Operational">
                    </div>
                  </div>

                  <div class="form-group cont-quant">
                    <label class="col-sm-2 control-label" for="hard_quantity">Quantité :</label>
                    <div class="col-sm-10">
                      <input id="hard_quantity" name="hard_quantity" class="form-control quantity" type="number" min="1" max="10" value="" required>
                    </div>
                  </div>

                  <div class="form-group col-sm-12">
                    <div class="col-sm-1"></div>
                    <div class="col-sm-5">
                      <button class="btn btn-warning pull-left back_to_step_1" type="button">
                                                    <span class="glyphicon glyphicon-chevron-left"></span> Précédent 
                                                </button>
                    </div>
                    <div class="col-sm-6">
                      <button class="btn btn-success pull-right go_to_step_3" type="button">
                                                    Suivant <span class="glyphicon glyphicon-chevron-right"></span>
                                                </button>
                    </div>
                  </div>
                </div>

              </div>
              <div id="step2c" class="add_mat">
                <legend>Step 2 of 4</legend>
                <div class="form-group col-sm-12">
                  <label class="control-label">Contract</label>

                  <div class="form-group col-sm-12">
                    <div class="col-sm-1"></div>
                    <div class="col-sm-5">
                      <button class="btn btn-warning pull-left back_to_step_1" type="button">
                                                    <span class="glyphicon glyphicon-chevron-left"></span> Précédent 
                                                </button>
                    </div>
                    <div class="col-sm-6">
                      <button class="btn btn-success pull-right go_to_step_3" type="button">
                                                    Suivant <span class="glyphicon glyphicon-chevron-right"></span>
                                                </button>
                    </div>
                  </div>
                </div>
              </div>

              <div id="step3" class="add_mat">

                <legend>Step 3 of 4</legend>
                <div class="form-group col-sm-12">
                  <label class="control-label">Ajout des numéros de série</label>

                  <div class="SN_wrapper form-group">
                    <label class="col-sm-2 control-label padding-right" for="serialNb_1">Numéro de série 1 :</label>
                    <div class="col-sm-10">
                      <input id="serialNb_1" name="serialNbs[1]" class="form-control" type="text" value="" required>
                    </div>
                  </div>

                  <div class="form-group col-sm-12">
                    <div class="col-sm-1"></div>
                    <div class="col-sm-5">
                      <button class="btn btn-warning pull-left back_to_step_2" type="button">
                                                        <span class="glyphicon glyphicon-chevron-left"></span> Précédent 
                                                    </button>
                    </div>
                    <div class="col-sm-6">
                      <button class="btn btn-success pull-right go_to_step_4" type="button">
                                                        Suivant <span class="glyphicon glyphicon-chevron-right"></span>
                                                    </button>
                    </div>
                  </div>
                </div>
              </div>
              <div id="step4" class="add_mat">


                <legend>Step 4 of 4</legend>
                <div id="recap" class="container">
                  <h3>Récapitulation</h3>
                  <h4 id="site_h4"><span class="label label-info">Site :</span> <span id="site"></span></h4>
                  <h4 id="type_h4"><span class="label label-info">Type :</span> <span id="type"></span></h4>
                  <h4 id="model_h4"><span class="label label-info">Modèle :</span> <span id="model"></span></h4>
                  <h4 id="quant_h4"><span class="label label-info">Quantité :</span> <span id="quant"></span></h4>
                  <div class="">
                    <h4><span class="label label-info">Numéros de série : </span></h4>
                    <ol id="list_SN">

                    </ol>
                  </div>
                </div>
                <div class="form-group col-sm-12">
                  <div class="form-group col-sm-12">
                    <div class="col-sm-1"></div>
                    <div class="col-lg-5">
                      <button class="btn btn-warning pull-left back_to_step_3" type="button">
                                                    <span class="glyphicon glyphicon-chevron-left"></span> Précédent 
                                                </button>
                    </div>
                    <div class="col-lg-6">
                      <button id="add_new_mat" class="btn btn-primary pull-right" type="submit">
                                                    Ajouter
                                                </button>
                    </div>
                  </div>
                </div>
              </div>
            </form>
          </div>
        </div>
      </div>
    </div>
  </div>
</body>

</html>

1 Ответ

0 голосов
/ 12 октября 2018

Вы динамически генерируете эти дополнительные поля?Он не работает так, как вы ожидаете, потому что эти дополнительные поля еще не существуют, когда вы вызываете .each(), который содержит метод .rules().Вы должны вызвать .rules() в этих новых полях просто после , когда вы их создадите.

Причина, по которой они по-прежнему отображаются как required, заключается в том, что у вас также есть атрибут required вHTML-элемент, который является избыточным.Если вы правильно назначаете правило required с помощью метода jQuery Validate, то вам не нужен встроенный атрибут required.

Похоже, вы также можете извлечь некоторые избыточные строки из if / elseутверждение, но это зависит от вас.

Что-то вроде:

if (quantity != 1) {

  for (i = 0; i < quantity - 1; i++) {

    if ($("#serialNb_" + y).length == 0) {
      console.log("1: i:" + i + " ; q:" + quantity + " ; y:" + y + " ; x:" + x);
      labelField = '<label for="serialNb_' + y + ' " class="col-sm-2 control-label padding-right">' + 'Numéro de série ' + y + ' :</label>';
      inputField = '<div class="col-sm-10"><input id="serialNb_' + y + '" name="serialNbs[' + y + ']" class="form-control " type="text" value="" /></div>'; 
    }

    // redundant lines on both sides of if/else??
    y++;
    $(wrapper).append(labelField, inputField);

    // assign the rules/messages right here, just after a new field is inserted
    $('#serialNb_' + y).rules("add", {
        required: true,
        messages: {
            required: "Il faut remplir le numéro de série"
        }
    });

  }  // end for loop

}  // end if

Альтернативно, если вы создаете все дополнительные поля одновременно, то вы можете просто переместить свой исходный цикл .each() вукажите сразу после создания всех этих дополнительных полей.

if (quantity != 1) {
    // create all fields
    ....
}

// all additional fields exist now
$("[name^=serialNbs]").each(function() {
    $(this).rules("add", {
        required: true,
        messages: {
            required: "Il faut remplir le numéro de série"
        }
    });
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...