JAVASCRIPT 26
Validator.js Guest on 25th April 2021 07:43:07 AM
  1. /*!
  2.  * Validator v0.9.0 for Bootstrap 3, by @1000hz
  3.  * Copyright 2015 Cina Saffary
  4.  * Licensed under http://opensource.org/licenses/MIT
  5.  *
  6.  * https://github.com/1000hz/bootstrap-validator
  7.  */
  8.  
  9. +function ($) {
  10.   'use strict';
  11.  
  12.   // VALIDATOR CLASS DEFINITION
  13.   // ==========================
  14.  
  15.   var Validator = function (element, options) {
  16.     this.$element = $(element)
  17.     this.options  = options
  18.  
  19.     options.errors = $.extend({}, Validator.DEFAULTS.errors, options.errors)
  20.  
  21.     for (var custom in options.custom) {
  22.       if (!options.errors[custom]) throw new Error('Missing default error message for custom validator: ' + custom)
  23.     }
  24.  
  25.     $.extend(Validator.VALIDATORS, options.custom)
  26.  
  27.     this.$element.attr('novalidate', true) // disable automatic native validation
  28.     this.toggleSubmit()
  29.  
  30.     this.$element.on('input.bs.validator change.bs.validator focusout.bs.validator', $.proxy(this.validateInput, this))
  31.     this.$element.on('submit.bs.validator', $.proxy(this.onSubmit, this))
  32.  
  33.     this.$element.find('[data-match]').each(function () {
  34.       var $this  = $(this)
  35.       var target = $this.data('match')
  36.  
  37.       $(target).on('input.bs.validator', function (e) {
  38.         $this.val() && $this.trigger('input.bs.validator')
  39.       })
  40.     })
  41.   }
  42.  
  43.   Validator.INPUT_SELECTOR = ':input:not([type="submit"], button):enabled:visible'
  44.  
  45.   Validator.DEFAULTS = {
  46.     delay: 500,
  47.     html: false,
  48.     disable: true,
  49.     custom: {},
  50.     errors: {
  51.       match: 'Does not match',
  52.       minlength: 'Not long enough'
  53.     },
  54.     feedback: {
  55.       success: 'glyphicon-ok',
  56.       error: 'glyphicon-remove'
  57.     }
  58.   }
  59.  
  60.   Validator.VALIDATORS = {
  61.     'native': function ($el) {
  62.       var el = $el[0]
  63.       return el.checkValidity ? el.checkValidity() : true
  64.     },
  65.     'match': function ($el) {
  66.       var target = $el.data('match')
  67.       return !$el.val() || $el.val() === $(target).val()
  68.     },
  69.     'minlength': function ($el) {
  70.       var minlength = $el.data('minlength')
  71.       return !$el.val() || $el.val().length >= minlength
  72.     }
  73.   }
  74.  
  75.   Validator.prototype.validateInput = function (e) {
  76.     var $el        = $(e.target)
  77.     var prevErrors = $el.data('bs.validator.errors')
  78.     var errors
  79.  
  80.     if ($el.is('[type="radio"]')) $el = this.$element.find('input[name="' + $el.attr('name') + '"]')
  81.  
  82.     this.$element.trigger(e = $.Event('validate.bs.validator', {relatedTarget: $el[0]}))
  83.  
  84.     if (e.isDefaultPrevented()) return
  85.  
  86.     var self = this
  87.  
  88.     this.runValidators($el).done(function (errors) {
  89.       $el.data('bs.validator.errors', errors)
  90.  
  91.       errors.length ? self.showErrors($el) : self.clearErrors($el)
  92.  
  93.       if (!prevErrors || errors.toString() !== prevErrors.toString()) {
  94.         e = errors.length
  95.           ? $.Event('invalid.bs.validator', {relatedTarget: $el[0], detail: errors})
  96.           : $.Event('valid.bs.validator', {relatedTarget: $el[0], detail: prevErrors})
  97.  
  98.         self.$element.trigger(e)
  99.       }
  100.  
  101.       self.toggleSubmit()
  102.  
  103.       self.$element.trigger($.Event('validated.bs.validator', {relatedTarget: $el[0]}))
  104.     })
  105.   }
  106.  
  107.  
  108.   Validator.prototype.runValidators = function ($el) {
  109.     var errors   = []
  110.     var deferred = $.Deferred()
  111.     var options  = this.options
  112.  
  113.     $el.data('bs.validator.deferred') && $el.data('bs.validator.deferred').reject()
  114.     $el.data('bs.validator.deferred', deferred)
  115.  
  116.     function getErrorMessage(key) {
  117.       return $el.data(key + '-error')
  118.         || $el.data('error')
  119.         || key == 'native' && $el[0].validationMessage
  120.         || options.errors[key]
  121.     }
  122.  
  123.     $.each(Validator.VALIDATORS, $.proxy(function (key, validator) {
  124.       if (($el.data(key) || key == 'native') && !validator.call(this, $el)) {
  125.         var error = getErrorMessage(key)
  126.         !~errors.indexOf(error) && errors.push(error)
  127.       }
  128.     }, this))
  129.  
  130.     if (!errors.length && $el.val() && $el.data('remote')) {
  131.       this.defer($el, function () {
  132.         var data = {}
  133.         data[$el.attr('name')] = $el.val()
  134.         $.get($el.data('remote'), data)
  135.           .fail(function (jqXHR, textStatus, error) { errors.push(getErrorMessage('remote') || error) })
  136.           .always(function () { deferred.resolve(errors)})
  137.       })
  138.     } else deferred.resolve(errors)
  139.  
  140.     return deferred.promise()
  141.   }
  142.  
  143.   Validator.prototype.validate = function () {
  144.     var delay = this.options.delay
  145.  
  146.     this.options.delay = 0
  147.     this.$element.find(Validator.INPUT_SELECTOR).trigger('input.bs.validator')
  148.     this.options.delay = delay
  149.  
  150.     return this
  151.   }
  152.  
  153.   Validator.prototype.showErrors = function ($el) {
  154.     var method = this.options.html ? 'html' : 'text'
  155.  
  156.     this.defer($el, function () {
  157.       var $group = $el.closest('.form-group')
  158.       var $block = $group.find('.help-block.with-errors')
  159.       var $feedback = $group.find('.form-control-feedback')
  160.       var errors = $el.data('bs.validator.errors')
  161.  
  162.       if (!errors.length) return
  163.  
  164.       errors = $('<ul/>')
  165.         .addClass('list-unstyled')
  166.         .append($.map(errors, function (error) { return $('<li/>')[method](error) }))
  167.  
  168.       $block.data('bs.validator.originalContent') === undefined && $block.data('bs.validator.originalContent', $block.html())
  169.       $block.empty().append(errors)
  170.       $group.addClass('has-error')
  171.  
  172.       $feedback.length
  173.         && $feedback.removeClass(this.options.feedback.success)
  174.         && $feedback.addClass(this.options.feedback.error)
  175.         && $group.removeClass('has-success')
  176.     })
  177.   }
  178.  
  179.   Validator.prototype.clearErrors = function ($el) {
  180.     var $group = $el.closest('.form-group')
  181.     var $block = $group.find('.help-block.with-errors')
  182.     var $feedback = $group.find('.form-control-feedback')
  183.  
  184.     $block.html($block.data('bs.validator.originalContent'))
  185.     $group.removeClass('has-error')
  186.  
  187.     $feedback.length
  188.       && $feedback.removeClass(this.options.feedback.error)
  189.       && $feedback.addClass(this.options.feedback.success)
  190.       && $group.addClass('has-success')
  191.   }
  192.  
  193.   Validator.prototype.hasErrors = function () {
  194.     function fieldErrors() {
  195.       return !!($(this).data('bs.validator.errors') || []).length
  196.     }
  197.  
  198.     return !!this.$element.find(Validator.INPUT_SELECTOR).filter(fieldErrors).length
  199.   }
  200.  
  201.   Validator.prototype.isIncomplete = function () {
  202.     function fieldIncomplete() {
  203.       return this.type === 'checkbox' ? !this.checked                                   :
  204.              this.type === 'radio'    ? !$('[name="' + this.name + '"]:checked').length :
  205.                                         $.trim(this.value) === ''
  206.     }
  207.  
  208.     return !!this.$element.find(Validator.INPUT_SELECTOR).filter('[required]').filter(fieldIncomplete).length
  209.   }
  210.  
  211.   Validator.prototype.onSubmit = function (e) {
  212.     this.validate()
  213.     if (this.isIncomplete() || this.hasErrors()) e.preventDefault()
  214.   }
  215.  
  216.   Validator.prototype.toggleSubmit = function () {
  217.     if(!this.options.disable) return
  218.  
  219.     var $btn = $('button[type="submit"], input[type="submit"]')
  220.       .filter('[form="' + this.$element.attr('id') + '"]')
  221.       .add(this.$element.find('input[type="submit"], button[type="submit"]'))
  222.  
  223.     $btn.toggleClass('disabled', this.isIncomplete() || this.hasErrors())
  224.   }
  225.  
  226.   Validator.prototype.defer = function ($el, callback) {
  227.     callback = $.proxy(callback, this)
  228.     if (!this.options.delay) return callback()
  229.     window.clearTimeout($el.data('bs.validator.timeout'))
  230.     $el.data('bs.validator.timeout', window.setTimeout(callback, this.options.delay))
  231.   }
  232.  
  233.   Validator.prototype.destroy = function () {
  234.     this.$element
  235.       .removeAttr('novalidate')
  236.       .removeData('bs.validator')
  237.       .off('.bs.validator')
  238.  
  239.     this.$element.find(Validator.INPUT_SELECTOR)
  240.       .off('.bs.validator')
  241.       .removeData(['bs.validator.errors', 'bs.validator.deferred'])
  242.       .each(function () {
  243.         var $this = $(this)
  244.         var timeout = $this.data('bs.validator.timeout')
  245.         window.clearTimeout(timeout) && $this.removeData('bs.validator.timeout')
  246.       })
  247.  
  248.     this.$element.find('.help-block.with-errors').each(function () {
  249.       var $this = $(this)
  250.       var originalContent = $this.data('bs.validator.originalContent')
  251.  
  252.       $this
  253.         .removeData('bs.validator.originalContent')
  254.         .html(originalContent)
  255.     })
  256.  
  257.     this.$element.find('input[type="submit"], button[type="submit"]').removeClass('disabled')
  258.  
  259.     this.$element.find('.has-error').removeClass('has-error')
  260.  
  261.     return this
  262.   }
  263.  
  264.   // VALIDATOR PLUGIN DEFINITION
  265.   // ===========================
  266.  
  267.  
  268.   function Plugin(option) {
  269.     return this.each(function () {
  270.       var $this   = $(this)
  271.       var options = $.extend({}, Validator.DEFAULTS, $this.data(), typeof option == 'object' && option)
  272.       var data    = $this.data('bs.validator')
  273.  
  274.       if (!data && option == 'destroy') return
  275.       if (!data) $this.data('bs.validator', (data = new Validator(this, options)))
  276.       if (typeof option == 'string') data[option]()
  277.     })
  278.   }
  279.  
  280.   var old = $.fn.validator
  281.  
  282.   $.fn.validator             = Plugin
  283.   $.fn.validator.Constructor = Validator
  284.  
  285.  
  286.   // VALIDATOR NO CONFLICT
  287.   // =====================
  288.  
  289.   $.fn.validator.noConflict = function () {
  290.     $.fn.validator = old
  291.     return this
  292.   }
  293.  
  294.  
  295.   // VALIDATOR DATA-API
  296.   // ==================
  297.  
  298.   $(window).on('load', function () {
  299.     $('form[data-toggle="validator"]').each(function () {
  300.       var $form = $(this)
  301.       Plugin.call($form, $form.data())
  302.     })
  303.   })
  304.  
  305. }(jQuery);

Paste-bin is for source code and general debugging text.

Login or Register to edit, delete and keep track of your pastes and more.

Raw Paste

Login or Register to edit or fork this paste. It's free.