Search code examples
javascriptjquerymethod-chaining

Method Chaining Won't Work for the dynamically created element in JQuery


I have 3 input fields inside a table row that are needed to validate on the client-side without pressing the submit button:

<td>
  <input name="clr" type="number" class="form-control" min="27" step="any">
</td>
<td>
  <input name="litre" type="number" class="form-control" min="0.5" step="any">
</td>
<td>
  <input name="fat" type="number" class="form-control" min="3.0" max="7.0" step="any">
</td>

So I attach blur and invalid events. I also need to attach those two events on the dynamically created input fields.

Below code is work for static input fields:

$('input[name="clr"], input[name="litre"], input[name="fat"]').on('blur', function(event) {
  event.target.checkValidity();
  $(event.target).removeClass("errorClass");
}).on('invalid', function(event) {
  setTimeout(function() {
    $(event.target).focus().addClass("errorClass");
  }, 50);
});

For dynamically created elements I tried this code:

$(document).on({
    'blur': function(event) {
      event.target.checkValidity();
      $(event.target).removeClass("errorClass");
    },
    'invalid': function(event) {
      setTimeout(function() {
        $(event.target).focus().addClass("errorClass");
      }, 50);
    }
  },
  'input[name="clr"], input[name="litre"], input[name="fat"]'
);

BUT this won't work!

Can anyone give me suggestion how can I overcome this problem?

EDIT: Heres, how I created the dynamically elements:

let clrTd = '<td><input name="clr" type="number" class="form-control" min="27" step="any"></td>';
let litreTd = '<td><input name="litre" type="number" class="form-control" min="0.5" step="any"></td>';
let fatTd = '<td><input name="fat" type="number" class="form-control" min="3.0" max="7.0" step="any"></td>';

$(document).on('blur', 'input[name="code"]', function () {
    if ($(this).closest("tr").is(":last-child") && $(this).val() != '') {
        var markup = "<tr>" + clrTd + litreTd + fatTd + "</tr> ";
        $("#editableTable tbody").append(markup);
    }
});

Solution

  • The reason why it is not working is because you are attaching an event handler to specific elements during the initial phase of the webpage creation. Identification of specific elements and attaching the Event handler needs to happen after the elements have been added.

    You can create new function and reuse them in such a case like this:

    function handleBlur(event){
      event.target.checkValidity();
      $(event.target).removeClass("errorClass");
    }
    function handleInvalid(event){
      setTimeout(function() {
        $(event.target).focus().addClass("errorClass");
      }, 50);
    }
    

    Changes for attaching these event handlers to specific elements:

    $('input[name="clr"], input[name="litre"], input[name="fat"]')
    .on('blur',function(event) {
      handleBlur(event);
    })
    .on('invalid', function(event) {
      handleInvalid(event);
    });
    

    In the end of dynamically added content

      $(document).on('blur', 'input[name="code"]', function () {
        if ($(this).closest("tr").is(":last-child") && $(this).val() != '') {
          var markup = "<tr>" + clrTd + litreTd + fatTd + "</tr> ";
          $("#editableTable tbody").append(markup);
          $('#editableTable tbody').find('input[name="clr"], input[name="litre"], input[name="fat"]')
          .on('blur',function(event) {
            handleBlur(event);
          })
          .on('invalid', function(event) {
            handleInvalid(event);
          });
        }
      });