2

The error validation works if there is only one instance of .item however when I duplicate the item and try to validate the input, the inputError function seems to run on every instance instead of just the one being validated.

How do I run the validate function on the only the inputs inside of each .item?

$(document).ready(function() {
  var $items = $(".item");
  $items.each(function() {
    var $input = $(this).find(".input");
    var inputCheck = function() {
      var errorList = $("ul.errorMessages", $items);
      var inputError = function() {
        errorList.empty();
        $items.find(":invalid").each(function(index, node) {
          var label = $(node).attr("name");
          var message = node.validationMessage || "Invalid value.";
          errorList
            .show()
            .append(
              "<li><span>" + label + ": " + "</span>" + message + "</li>"
            );
        });
      };
      $("input[type=submit], button", $items).on("click", inputError);
    };
    inputCheck();
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="form">
  <div class="item">
    <div class="success"></div>
    <ul class="errorMessages"></ul>
    <label>
      <input required class="input" name="first" type="text" placeholder="first">
    </label>
    <label>
      <input required class="input" name="second" type="text" placeholder="second">
    </label>
    <button type="submit">Create</button>
  </div>
  <div class="item">
    <div class="success"></div>
    <ul class="errorMessages"></ul>
    <label>
      <input required class="input" name="first_2" type="text" placeholder="first">
    </label>
    <label>
      <input required class="input" name="second_2" type="text" placeholder="second">
    </label>
    <button type="submit">Create</button>
  </div>
</div>

2
  • why not label it something different? Commented Aug 22, 2020 at 21:19
  • every time you validate, you add a new event handler - probably not a great practice, you also name a function and can probably just self instantiate it. Commented Aug 24, 2020 at 18:48

2 Answers 2

3
+50

this is tricky but you can store current item being iterated in a variable such as $this and then manipulate it

$(document).ready(function() {
  var $items = $(".item");
  $items.each(function() {
    var $this = $(this);
    var $input = $this.find(".input");
    var inputCheck = function() {
      var errorList = $("ul.errorMessages", $this);
      var inputError = function() {
        errorList.empty();
        $this.find(":invalid").each(function(index, node) {
          var label = $(node).attr("name");
          var message = node.validationMessage || "Invalid value.";
          errorList
            .show()
            .append(
              "<li><span>" + label + ": " + "</span>" + message + "</li>"
            );
        });
      };
      $("input[type=submit], button", $this).on("click", inputError);
    };
    inputCheck();
  });
});

here is fiddle: https://jsfiddle.net/rjpyqms9/

Sign up to request clarification or add additional context in comments.

Comments

0

I would put simplify the code and create a function with a simpler set of code in it and call that. You will also want the submit event in case someone triggers it - like from a keyboard. Note I attached the event handler to the .item to simplify the code;

NOTE: I assume some sort of a validate plugin etc. exists to put the :invalid in there. EDIT: thought about it and made it simpler.

$(function() {
  function inputError(event) {
    // the item
    let item = $(event.delegateTarget);
    let invalids = item.find(':invalid');
    if (invalids) {
      let errorList = item.find(".errorMessages")
      errorList.empty();
      invalids 
        .each(function(index, node) {
          let label = $(node).attr("name");
          let message = node.validationMessage || "Invalid value.";
          errorList
            .append("<li><span>" + label + ": " + "</span>" + message + "</li>")
            .show();
        });
    }
  }
  $('.form').find('.item').on('click submit', "button[type=submit]", inputError);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="form">
  <div class="item">
    <div class="success"></div>
    <ul class="errorMessages"></ul>
    <label>
      <input required class="input" name="first" type="text" placeholder="first">
    </label>
    <label>
      <input required class="input" name="second" type="text" placeholder="second">
    </label>
    <button type="submit">Create</button>
  </div>
  <div class="item">
    <div class="success"></div>
    <ul class="errorMessages"></ul>
    <label>
      <input required class="input" name="first_2" type="text" placeholder="first">
    </label>
    <label>
      <input required class="input" name="second_2" type="text" placeholder="second">
    </label>
    <button type="submit">Create</button>
  </div>
</div>

2 Comments

Thanks for the alternate solution however the snippet doesn't seem to be working
yea, I had a couple typo's and simplified it a bit with an edit

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.