Native Implementation of Jquery Validation Plugin

Native Implementation of Jquery Validation Plugin

Wellidate is a fast, easy-to-use JavaScript form validation library that supports both native HTML5 validation attribute and HTML data attribute.

Wellidate is a fast, easy-to-use JavaScript form validation library that supports both native HTML5 validation attribute and HTML data attribute.

More features:

  • Auto moves the focus to the invalid form field.
  • Custom error messages and styles.
  • 20+ built-in validation rules (see below).
  • Allows to include/exclude form fields.
  • Allows to display results in a Summary container.

Validation rules included:

  1. accept
  2. date
  3. digits
  4. email
  5. equalto
  6. filesize
  7. greater
  8. integer
  9. length
  10. lower
  11. max
  12. maxlength
  13. min
  14. minlength
  15. number
  16. range
  17. regex
  18. remote
  19. required
  20. step

How to use it:

Download the insert the JavaScript file into the document and we’re ready to go.

<script src="src/wellidate.js"></script>

Apply rules to form fields using HTML5 form validation attributes or HTML data-val-ruleName attributes as follows:

<form>
  <label for="data-name">Name</label>
  <input name="data-name" data-val-required="" data-val-length="" data-val-length-max="10">

  <button>Submit</button>
</form>
<!-- OR -->
<form>
  <label for="data-name">Name</label>
  <input name="data-name" required minlength="2" maxlength="10">

  <button>Submit</button>
</form>

Initialize the Wellidate on the HTML form and done.

new Wellidate(document.querySelector('form'));

All possible options to customize the form validation. You can pass the following options as an object to the Wellidate method.

new Wellidate(document.querySelector('form'),{

    // moves the focus to the invaild field
    focusInvalid: true,

    // configurable submit handler
    submitHandler: null,

    // moves the focus to the field after clean up
    focusCleanup: false,

    // includes the following form fields
    include: 'input,textarea,select',

    // for displaying results
    summary: {
      container: '[data-valmsg-summary=true]',
      show: function (result) {
        if (this.container) {
          var summary = document.querySelector(this.container);

          if (summary) {
            summary.innerHTML = '';

            if (result.isValid) {
              summary.classList.add('validation-summary-valid');
              summary.classList.remove('validation-summary-errors');
            } else {
              summary.classList.add('validation-summary-errors');
              summary.classList.remove('validation-summary-valid');

              var list = document.createElement('ul');

              result.invalid.forEach(function (invalid) {
                var item = document.createElement('li');

                item.innerHTML = invalid.message;

                list.appendChild(item);
              });

              summary.appendChild(list);
            }
          }
        }
      },
      reset: function () {
        this.show({
          isValid: true,
          invalid: []
        });
      }
    },

    // default classes
    classes: {
      inputPending: 'input-validation-pending',
      inputError: 'input-validation-error',
      inputValid: 'input-validation-valid',
      fieldPending: 'input-validation-pending',
      fieldError: 'field-validation-error',
      fieldValid: 'field-validation-valid',
      wasValidated: 'was-validated'
    },

    // excludes following form fields
    excludes: [
      'input[type=button]',
      'input[type=submit]',
      'input[type=image]',
      'input[type=reset]',
      ':disabled'
    ],

    // basic rules
    rule: {
      trim: true,
      message: 'This field is not valid.',
      isValid: function () {
          return false;
      },
      isEnabled: function () {
          return true;
      },
      formatMessage: function () {
        return this.message;
      },
      normalizeValue: function (element) {
        element = element || this.element;
        var value = element.value;

        if (element.tagName == 'SELECT' && element.multiple) {
          return [].filter.call(element.options, function (option) {
            return option.selected;
          }).length;
        } else if (element.type == 'radio') {
          if (element.name) {
            var name = this.wellidate.escapeAttribute(element.name);
            var checked = document.querySelector('input[name="' + name + '"]:checked');

            value = checked ? checked.value : '';
          } else {
            value = element.checked ? value : '';
          }
        } else if (element.type == 'file') {
          if (value.lastIndexOf('\\') >= 0) {
            value = value.substring(value.lastIndexOf('\\') + 1);
          } else if (value.lastIndexOf('/') >= 0) {
            value = value.substring(value.lastIndexOf('/') + 1);
          }
        }

        return this.trim ? value.trim() : value;
      }
    }

});

Default validation rules. Override the following validation rules as per your needs.

new Wellidate(document.querySelector('form'),{
    rules: {
      required: {
          message: 'This field is required.',
          isValid: function () {
              return Boolean(this.normalizeValue());
          }
      },
      equalto: {
          message: 'Please enter the same value again.',
          isValid: function () {
              var other = document.getElementById(this.other);

              return other && this.normalizeValue() == this.normalizeValue(other);
          }
      },
      length: {
          message: 'Please enter a value between {0} and {1} characters long.',
          isValid: function () {
              var length = this;
              var value = length.normalizeValue();

              return (length.min == null || length.min <= value.length) && (value.length <= length.max || length.max == null);
          },
          formatMessage: function () {
              var length = this;

              if (length.min != null && length.max == null && !length.isDataMessage) {
                  return Wellidate.prototype.rules.minlength.message.replace('{0}', length.min);
              } else if (length.min == null && length.max != null && !length.isDataMessage) {
                  return Wellidate.prototype.rules.maxlength.message.replace('{0}', length.max);
              }

              return length.message.replace('{0}', length.min).replace('{1}', length.max);
          }
      },
      minlength: {
          message: 'Please enter at least {0} characters.',
          isValid: function () {
              return this.min == null || !parseFloat(this.min) <= this.normalizeValue().length;
          },
          formatMessage: function () {
              return this.message.replace('{0}', this.min);
          }
      },
      maxlength: {
          message: 'Please enter no more than {0} characters.',
          isValid: function () {
              return this.normalizeValue().length <= this.max || !parseFloat(this.max);
          },
          formatMessage: function () {
              return this.message.replace('{0}', this.max);
          }
      },
      email: {
          message: 'Please enter a valid email address.',
          isValid: function () {
              return /^$|^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-][email protected][a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(this.normalizeValue());
          }
      },
      integer: {
          message: 'Please enter a valid integer value.',
          isValid: function () {
              return /^$|^[+-]?\d+$/.test(this.normalizeValue());
          }
      },
      number: {
          message: 'Please enter a valid number.',
          scaleMessage: 'Please enter a value with no more than {0} fractional digits',
          precisionMessage: 'Please enter a value using no more than {0} significant digits',
          isValid: function () {
              return /^$|^[+-]?(\d+|\d{1,3}(,\d{3})+)?(\.\d+)?$/.test(this.normalizeValue());
          }
      },
      digits: {
          message: 'Please enter only digits.',
          isValid: function () {
              return /^\d*$/.test(this.normalizeValue());
          }
      },
      date: {
          message: 'Please enter a valid date.',
          isValid: function () {
              return /^$|^\d{4}-(0?[1-9]|1[012])-(0?[1-9]|[12][0-9]|3[01])$/.test(this.normalizeValue());
          }
      },
      range: {
          message: 'Please enter a value between {0} and {1}.',
          isValid: function () {
              var range = this;
              var value = range.normalizeValue2();

              return !value || (range.min == null || range.min <= parseFloat(value)) && (parseFloat(value) <= range.max || range.max == null);
          },
          formatMessage: function () {
              var range = this;

              if (range.min != null && range.max == null && !range.isDataMessage) {
                  return Wellidate.prototype.rules.min.message.replace('{0}', range.min);
              } else if (range.min == null && range.max != null && !range.isDataMessage) {
                  return Wellidate.prototype.rules.max.message.replace('{0}', range.max);
              }

              return range.message.replace('{0}', range.min).replace('{1}', range.max);
          }
      },
      min: {
          message: 'Please enter a value greater than or equal to {0}.',
          isValid: function () {
              var value = this.normalizeValue();

              return !value || !parseFloat(this.value) || this.value <= parseFloat(value);
          },
          formatMessage: function () {
              return this.message.replace('{0}', this.value);
          }
      },
      max: {
          message: 'Please enter a value less than or equal to {0}.',
          isValid: function () {
              var value = this.normalizeValue();

              return !value || !parseFloat(this.value) || parseFloat(value) <= this.value;
          },
          formatMessage: function () {
              return this.message.replace('{0}', this.value);
          }
      },
      greater: {
          message: 'Please enter a value greater than {0}.',
          isValid: function () {
              var value = this.normalizeValue();

              return !value || !parseFloat(this.than) || this.than < parseFloat(value);
          },
          formatMessage: function () {
              return this.message.replace('{0}', this.than);
          }
      },
      lower: {
          message: 'Please enter a value lower than {0}.',
          isValid: function () {
              var value = this.normalizeValue();

              return !value || !parseFloat(this.than) || parseFloat(value) < this.than;
          },
          formatMessage: function () {
              return this.message.replace('{0}', this.than);
          }
      },
      step: {
          message: 'Please enter a multiple of {0}.',
          isValid: function () {
              var value = this.normalizeValue();

              return !value || !parseFloat(this.value) || parseFloat(value) % this.value == 0;
          },
          formatMessage: function () {
              return this.message.replace('{0}', this.value);
          }
      },
      filesize: {
          page: 1024,
          message: 'File size should not exceed {0} MB.',
          isValid: function () {
              var size = [].reduce.call(this.element.files, function (total, file) {
                  return total + file.size;
              }, 0);

              return size <= this.max || this.max == null;
          },
          formatMessage: function () {
              var filesize = this;
              var mb = (filesize.max / filesize.page / filesize.page).toFixed(2);

              return filesize.message.replace('{0}', mb.replace(/[.|0]*$/, ''));
          }
      },
      accept: {
          message: 'Please select files in correct format.',
          isValid: function () {
              var filter = this.types.split(',').map(function (type) {
                  return type.trim();
              });

              var correct = [].filter.call(this.element.files, function (file) {
                  var extension = file.name.split('.').pop();

                  for (var i = 0; i < filter.length; i++) {
                      if (filter[i].indexOf('.') == 0) {
                          if (file.name != extension && '.' + extension == filter[i]) {
                              return true;
                          }
                      } else if (/\/\*$/.test(filter[i])) {
                          if (file.type.indexOf(filter[i].replace(/\*$/, '')) == 0) {
                              return true;
                          }
                      } else if (file.type == filter[i]) {
                          return true;
                      }
                  }

                  return !filter.length;
              });

              return this.element.files.length == correct.length;
          }
      },
      regex: {
          message: 'Please enter value in a valid format. {0}',
          isValid: function () {
              var value = this.normalizeValue();

              return !value || !this.pattern || new RegExp(this.pattern).test(value);
          },
          formatMessage: function () {
              return this.message.replace('{0}', this.title || '');
          }
      },
      remote: {
          type: 'get',
          message: 'Please fix this field.',
          isValid: function (validatable) {
              var remote = this;

              if (remote.request && remote.request.readyState != 4) {
                  remote.request.abort();
              }

              clearTimeout(remote.start);
              remote.start = setTimeout(function () {
                  if (validatable.isValid) {
                      remote.request = new XMLHttpRequest();
                      remote.request.open(remote.type, remote.buildUrl(), true);
                      remote.request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');

                      remote.request.onload = function () {
                          if (validatable.isValid && 200 <= this.status && this.status < 400) {
                              remote.apply(validatable, this.responseText);
                          }
                      };

                      remote.prepare(validatable);

                      remote.request.send();

                      validatable.pending();
                  }
              }, 1);

              return true;
          },
          buildUrl: function () {
              var remote = this;
              var url = remote.url.split('?', 2)[0];
              var fields = (remote.additionalFields || '').split(',').filter(Boolean);
              var query = (remote.url.split('?', 2)[1] || '').split('&').filter(Boolean);

              for (var i = 0; i < fields.length; i++) {
                  var element = document.querySelector(fields[i]);
                  var value = remote.normalizeValue(element) || '';

                  query.push(encodeURIComponent(element.name) + "=" + encodeURIComponent(value));
              }

              query.push(encodeURIComponent(remote.element.name) + "=" + encodeURIComponent(remote.normalizeValue() || ''));

              return url + '?' + query.join('&');
          },
          prepare: function () {
          },
          apply: function (validatable, response) {
              var result = JSON.parse(response);

              if (result.isValid === false) {
                  validatable.error('remote', result.message);
              } else {
                  validatable.success(result.message);
              }
          }
      }
    }
});

API methods.

var instance = new Wellidate(document.querySelector('form'));

// checks if is valid
instance.isValid(fieldName);

// Validates all or selected fields
instance.form();

// Validates the form and returns the validation results for each field
instance.validate();

// rebuilds the instnace
instance.rebuild();

// applies rules to fields
instance.apply({
  '#name': {
    error: 'Enter a unique name'
  },
  // ...
});

// resets the form
instance.reset();

Download Details:

Author: NonFactors

Demo: https://nonfactors.github.io/Wellidate/

Source Code: https://github.com/NonFactors/Wellidate

javascript

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

The essential JavaScript concepts that you should understand

The essential JavaScript concepts that you should understand - For successful developing and to pass a work interview

Data Types In JavaScript

JavaScript data types are kept easy. While JavaScript data types are mostly similar to other programming languages; some of its data types can be unique. Here, we’ll outline the data types of JavaScript.

Introduction With Basic JavaScript

Introduction With Basic JavaScript - Unlike most programming languages, the JavaScript language has no concept of input or output. It is designed to run as a scripting language in a host environment, and it is up to the host environment to provide mechanisms for communicating with the outside world.

JavaScript Memory Management System

The main goal of this article is help to readers to understand that how memory management system performs in JavaScript. I will use a shorthand such as GC which means Garbage Collection. When the browsers use Javascript, they need any memory location to store objects, functions, and all other things. Let’s deep in dive that how things going to work in GC.

Create a Line Through Effect with JavaScript

In this post we are going to create an amazing line through effect, with help of CSS and lots of JavaScript. So, head over to your terminal and create a folder LineThroughEffect. Create three files -index.html, main.js and styles.css inside it.