vendor: 11,730 bytes, lines 1-385
1/*! 2 * Validator v0.11.5 for Bootstrap 3, by @1000hz 3 * Copyright 2016 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 function getValue($el) { 16 return $el.is('[type="checkbox"]') ? $el.prop('checked') : 17 $el.is('[type="radio"]') ? !!$('[name="' + $el.attr('name') + '"]:checked').length : 18 $el.val() 19 } 20 21 var Validator = function (element, options) { 22 this.options = options 23 this.validators = $.extend({}, Validator.VALIDATORS, options.custom) 24 this.$element = $(element) 25 this.$btn = $('button[type="submit"], input[type="submit"]') 26 .filter('[form="' + this.$element.attr('id') + '"]') 27 .add(this.$element.find('input[type="submit"], button[type="submit"]')) 28 29 this.update() 30 31 this.$element.on('input.bs.validator change.bs.validator focusout.bs.validator', $.proxy(this.onInput, this)) 32 this.$element.on('submit.bs.validator', $.proxy(this.onSubmit, this)) 33 this.$element.on('reset.bs.validator', $.proxy(this.reset, this)) 34 35 this.$element.find('[data-match]').each(function () { 36 var $this = $(this) 37 var target = $this.data('match') 38 39 $(target).on('input.bs.validator', function (e) { 40 getValue($this) && $this.trigger('input.bs.validator') 41 }) 42 }) 43 44 this.$inputs.filter(function () { return getValue($(this)) }).trigger('focusout') 45 46 this.$element.attr('novalidate', true) // disable automatic native validation 47 this.toggleSubmit() 48 } 49 50 Validator.VERSION = '0.11.5' 51 52 Validator.INPUT_SELECTOR = ':input:not([type="hidden"], [type="submit"], [type="reset"], button)' 53 54 Validator.FOCUS_OFFSET = 20 55 56 Validator.DEFAULTS = { 57 delay: 500, 58 html: false, 59 disable: true, 60 focus: true, 61 custom: {}, 62 errors: { 63 match: 'Does not match', 64 minlength: 'Not long enough' 65 }, 66 feedback: { 67 success: 'glyphicon-ok', 68 error: 'glyphicon-remove' 69 } 70 } 71 72 Validator.VALIDATORS = { 73 'native': function ($el) { 74 var el = $el[0] 75 if (el.checkValidity) { 76 return !el.checkValidity() && !el.validity.valid && (el.validationMessage || "error!") 77 } 78 }, 79 'match': function ($el) { 80 var target = $el.data('match') 81 return $el.val() !== $(target).val() && Validator.DEFAULTS.errors.match 82 }, 83 'minlength': function ($el) { 84 var minlength = $el.data('minlength') 85 return $el.val().length < minlength && Validator.DEFAULTS.errors.minlength 86 } 87 } 88 89 Validator.prototype.update = function () { 90 this.$inputs = this.$element.find(Validator.INPUT_SELECTOR) 91 .add(this.$element.find('[data-validate="true"]')) 92 .not(this.$element.find('[data-validate="false"]')) 93 94 return this 95 } 96 97 Validator.prototype.onInput = function (e) { 98 var self = this 99 var $el = $(e.target) 100 var deferErrors = e.type !== 'focusout' 101 102 if (!this.$inputs.is($el)) return 103 104 this.validateInput($el, deferErrors).done(function () { 105 self.toggleSubmit() 106 }) 107 } 108 109 Validator.prototype.validateInput = function ($el, deferErrors) { 110 var value = getValue($el) 111 var prevErrors = $el.data('bs.validator.errors') 112 var errors 113 114 if ($el.is('[type="radio"]')) $el = this.$element.find('input[name="' + $el.attr('name') + '"]') 115 116 var e = $.Event('validate.bs.validator', {relatedTarget: $el[0]}) 117 this.$element.trigger(e) 118 if (e.isDefaultPrevented()) return 119 120 var self = this 121 122 return this.runValidators($el).done(function (errors) { 123 $el.data('bs.validator.errors', errors) 124 125 errors.length 126 ? deferErrors ? self.defer($el, self.showErrors) : self.showErrors($el) 127 : self.clearErrors($el) 128 129 if (!prevErrors || errors.toString() !== prevErrors.toString()) { 130 e = errors.length 131 ? $.Event('invalid.bs.validator', {relatedTarget: $el[0], detail: errors}) 132 : $.Event('valid.bs.validator', {relatedTarget: $el[0], detail: prevErrors}) 133 134 self.$element.trigger(e) 135 } 136 137 self.toggleSubmit() 138 139 self.$element.trigger($.Event('validated.bs.validator', {relatedTarget: $el[0]})) 140 }) 141 } 142 143 144 Validator.prototype.runValidators = function ($el) { 145 var errors = [] 146 var deferred = $.Deferred() 147 148 $el.data('bs.validator.deferred') && $el.data('bs.validator.deferred').reject() 149 $el.data('bs.validator.deferred', deferred) 150 151 function getValidatorSpecificError(key) { 152 return $el.data(key + '-error') 153 } 154 155 function getValidityStateError() { 156 var validity = $el[0].validity 157 return validity.typeMismatch ? $el.data('type-error') 158 : validity.patternMismatch ? $el.data('pattern-error') 159 : validity.stepMismatch ? $el.data('step-error') 160 : validity.rangeOverflow ? $el.data('max-error') 161 : validity.rangeUnderflow ? $el.data('min-error') 162 : validity.valueMissing ? $el.data('required-error') 163 : null 164 } 165 166 function getGenericError() { 167 return $el.data('error') 168 } 169 170 function getErrorMessage(key) { 171 return getValidatorSpecificError(key) 172 || getValidityStateError() 173 || getGenericError() 174 } 175 176 $.each(this.validators, $.proxy(function (key, validator) { 177 var error = null 178 if ((getValue($el) || $el.attr('required')) && 179 ($el.data(key) || key == 'native') && 180 (error = validator.call(this, $el))) { 181 error = getErrorMessage(key) || error 182 !~errors.indexOf(error) && errors.push(error) 183 } 184 }, this)) 185 186 if (!errors.length && getValue($el) && $el.data('remote')) { 187 this.defer($el, function () { 188 var data = {} 189 data[$el.attr('name')] = getValue($el) 190 $.get($el.data('remote'), data) 191 .fail(function (jqXHR, textStatus, error) { errors.push(getErrorMessage('remote') || error) }) 192 .always(function () { deferred.resolve(errors)}) 193 }) 194 } else deferred.resolve(errors) 195 196 return deferred.promise() 197 } 198 199 Validator.prototype.validate = function () { 200 var self = this 201 202 $.when(this.$inputs.map(function (el) { 203 return self.validateInput($(this), false) 204 })).then(function () { 205 self.toggleSubmit() 206 self.focusError() 207 }) 208 209 return this 210 } 211 212 Validator.prototype.focusError = function () { 213 if (!this.options.focus) return 214 215 var $input = this.$element.find(".has-error:first :input") 216 if ($input.length === 0) return 217 218 $('html, body').animate({scrollTop: $input.offset().top - Validator.FOCUS_OFFSET}, 250) 219 $input.focus() 220 } 221 222 Validator.prototype.showErrors = function ($el) { 223 var method = this.options.html ? 'html' : 'text' 224 var errors = $el.data('bs.validator.errors') 225 var $group = $el.closest('.form-group') 226 var $block = $group.find('.help-block.with-errors') 227 var $feedback = $group.find('.form-control-feedback') 228 229 if (!errors.length) return 230 231 errors = $('<ul/>') 232 .addClass('list-unstyled') 233 .append($.map(errors, function (error) { return $('<li/>')[method](error) })) 234 235 $block.data('bs.validator.originalContent') === undefined && $block.data('bs.validator.originalContent', $block.html()) 236 $block.empty().append(errors) 237 $group.addClass('has-error has-danger') 238 239 $group.hasClass('has-feedback') 240 && $feedback.removeClass(this.options.feedback.success) 241 && $feedback.addClass(this.options.feedback.error) 242 && $group.removeClass('has-success') 243 } 244 245 Validator.prototype.clearErrors = function ($el) { 246 var $group = $el.closest('.form-group') 247 var $block = $group.find('.help-block.with-errors') 248 var $feedback = $group.find('.form-control-feedback') 249 250 $block.html($block.data('bs.validator.originalContent')) 251 $group.removeClass('has-error has-danger has-success') 252 253 $group.hasClass('has-feedback') 254 && $feedback.removeClass(this.options.feedback.error) 255 && $feedback.removeClass(this.options.feedback.success) 256 && getValue($el) 257 && $feedback.addClass(this.options.feedback.success) 258 && $group.addClass('has-success') 259 } 260 261 Validator.prototype.hasErrors = function () { 262 function fieldErrors() { 263 return !!($(this).data('bs.validator.errors') || []).length 264 } 265 266 return !!this.$inputs.filter(fieldErrors).length 267 } 268 269 Validator.prototype.isIncomplete = function () { 270 function fieldIncomplete() { 271 var value = getValue($(this)) 272 return !(typeof value == "string" ? $.trim(value) : value) 273 } 274 275 return !!this.$inputs.filter('[required]').filter(fieldIncomplete).length 276 } 277 278 Validator.prototype.onSubmit = function (e) { 279 this.validate() 280 if (this.isIncomplete() || this.hasErrors()) e.preventDefault() 281 } 282 283 Validator.prototype.toggleSubmit = function () { 284 if (!this.options.disable) return 285 this.$btn.toggleClass('disabled', this.isIncomplete() || this.hasErrors()) 286 } 287 288 Validator.prototype.defer = function ($el, callback) { 289 callback = $.proxy(callback, this, $el) 290 if (!this.options.delay) return callback() 291 window.clearTimeout($el.data('bs.validator.timeout')) 292 $el.data('bs.validator.timeout', window.setTimeout(callback, this.options.delay)) 293 } 294 295 Validator.prototype.reset = function () { 296 this.$element.find('.form-control-feedback') 297 .removeClass(this.options.feedback.error) 298 .removeClass(this.options.feedback.success) 299 300 this.$inputs 301 .removeData(['bs.validator.errors', 'bs.validator.deferred']) 302 .each(function () { 303 var $this = $(this) 304 var timeout = $this.data('bs.validator.timeout') 305 window.clearTimeout(timeout) && $this.removeData('bs.validator.timeout') 306 }) 307 308 this.$element.find('.help-block.with-errors') 309 .each(function () { 310 var $this = $(this) 311 var originalContent = $this.data('bs.validator.originalContent') 312 313 $this 314 .removeData('bs.validator.originalContent') 315 .html(originalContent) 316 }) 317 318 this.$btn.removeClass('disabled') 319 320 this.$element.find('.has-error, .has-danger, .has-success').removeClass('has-error has-danger has-success') 321 322 return this 323 } 324 325 Validator.prototype.destroy = function () { 326 this.reset() 327 328 this.$element 329 .removeAttr('novalidate') 330 .removeData('bs.validator') 331 .off('.bs.validator') 332 333 this.$inputs 334 .off('.bs.validator') 335 336 this.options = null 337 this.validators = null 338 this.$element = null 339 this.$btn = null 340 341 return this 342 } 343 344 // VALIDATOR PLUGIN DEFINITION 345 // =========================== 346 347 348 function Plugin(option) { 349 return this.each(function () { 350 var $this = $(this) 351 var options = $.extend({}, Validator.DEFAULTS, $this.data(), typeof option == 'object' && option) 352 var data = $this.data('bs.validator') 353 354 if (!data && option == 'destroy') return 355 if (!data) $this.data('bs.validator', (data = new Validator(this, options))) 356 if (typeof option == 'string') data[option]() 357 }) 358 } 359 360 var old = $.fn.validator 361 362 $.fn.validator = Plugin 363 $.fn.validator.Constructor = Validator 364 365 366 // VALIDATOR NO CONFLICT 367 // ===================== 368 369 $.fn.validator.noConflict = function () { 370 $.fn.validator = old 371 return this 372 } 373 374 375 // VALIDATOR DATA-API 376 // ================== 377 378 $(window).on('load', function () { 379 $('form[data-toggle="validator"]').each(function () { 380 var $form = $(this) 381 Plugin.call($form, $form.data()) 382 }) 383 }) 384 385}(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.