/* =======================================================================================
Template : Denteur - Responsive Dentist & Medical HTML Template
Author : QuickDev
Create : 18 September 2019
========================================================================================== */
/* ===============================================
1. Preloader
2. Scrolling Top
3. FAQ Accordion
4. Team Carousel
5. Clients Carousel
6. Testimonials Carousel
7. Gallery Carousel
8. Magnific Popup
9. Youtube Popup
10. Counter
11. Counter Up
12. Imager hover Movement
13. Filter Gallery
14. Masonry Gallery Loader
15. Contact Form
15. Grid Carousel
16. Team Carousel
17. Grid Carousel Alt
18. News Carousel
19. Projects Carousel
20. Welding Carousel
21. Testimonials Carousel
21. Contact Form
================================================== */
/* ===============================================
Function Call - Call Function Ones
=============================================== */
jQuery(document).ready(function(){
"use strict";
// here all ready functions
loader();
scroll_top();
counter_up();
magnific_popup();
video_popup();
accordion();
team_carousel();
clients_carousel();
testimonial_slider();
gallery_carousel();
services_carousel();
team_carousel_alt();
grid_carousel_alt();
news_carousel_alt();
projects_carousel();
welding_carousel();
testimonial_carousel();
});
/* ===============================================
1. Preloader - Themplate Preloader
=============================================== */
function loader() {
"use strict";
setTimeout(function () {
$('#loader-wrapper').fadeOut();
}, 1500);
};
/* ===============================================
2. Scrolling Top - Button to scroll up
=============================================== */
function scroll_top(){
"use strict";
var offset = 300,
offset_opacity = 1200,
scroll_top_duration = 700,
$back_to_top = $('.cd-top');
$(window).scroll(function(){
( $(this).scrollTop() > offset ) ? $back_to_top.addClass('cd-is-visible') : $back_to_top.removeClass('cd-is-visible cd-fade-out');
if( $(this).scrollTop() > offset_opacity ) {
$back_to_top.addClass('cd-fade-out');
}
});
$back_to_top.on('click', function(event){
event.preventDefault();
$('body,html').animate({
scrollTop: 0 ,
}, scroll_top_duration
);
});
};
/* ===============================================
3. FAQ Accordion - This is the accordion used on the FAQ page
=============================================== */
function accordion(){
};
$('.accordion > li:eq(0) a').addClass('active').next().slideDown();
$('.accordion a').click(function(j) {
var dropDown = $(this).closest('li').find('p');
$(this).closest('.accordion').find('p').not(dropDown).slideUp();
if ($(this).hasClass('active')) {
$(this).removeClass('active');
} else {
$(this).closest('.accordion').find('a.active').removeClass('active');
$(this).addClass('active');
}
dropDown.stop(false, true).slideToggle();
j.preventDefault();
});
(jQuery)
/* ===============================================
4. Team Carousel - This is used for the team carousel
=============================================== */
function team_carousel(){
$('.team-carousel').slick({
slidesToShow: 3,
slidesToScroll: 1,
autoplay: false,
autoplaySpeed: 1500,
arrows: false,
dots: false,
pauseOnHover: false,
responsive: [{
breakpoint: 992,
settings: {
slidesToShow: 2
}
}, {
breakpoint: 650,
settings: {
slidesToShow:1
}
}]
});
};
/* ===============================================
5. Clients Carousel - This is used for the clients carousel
=============================================== */
function clients_carousel(){
$('.clients-carousel').slick({
slidesToShow: 5,
slidesToScroll: 1,
autoplay: true,
autoplaySpeed: 1500,
arrows: false,
dots: false,
pauseOnHover: false,
responsive: [{
breakpoint: 1200,
settings: {
slidesToShow: 4
}
}, {
breakpoint: 800,
settings: {
slidesToShow:3
}
}, {
breakpoint: 600,
settings: {
slidesToShow:2
}
}]
});
};
/* ===============================================
6. Testimonials Carousel - This is used for the testimonial slider
=============================================== */
function testimonial_slider(){
$("#testimonial-slider").owlCarousel({
items:1,
itemsDesktop:[1000,1],
itemsDesktopSmall:[979,1],
itemsTablet:[768,1],
pagination:true,
navigation:false,
slideSpeed:1000,
singleItem:false,
navigationText:["",""],
autoPlay:true
});
};
/* ===============================================
7. Gallery Carousel - This is used for the gallery carousel
=============================================== */
function gallery_carousel(){
$('.gallery-carousel').slick({
slidesToShow: 4,
slidesToScroll: 1,
autoplay: true,
autoplaySpeed: 1500,
arrows: false,
dots: false,
pauseOnHover: false,
responsive: [{
breakpoint: 992,
settings: {
slidesToShow: 2
}
}, {
breakpoint: 650,
settings: {
slidesToShow:1
}
}]
});
};
/* ===============================================
8. Magnific Popup - This is used for the popup gallery
=============================================== */
function magnific_popup(){
$('.image-popup-vertical-fit').magnificPopup({
type: 'image',
mainClass: 'mfp-with-zoom',
gallery:{
enabled:true
},
zoom: {
enabled: true,
duration: 300, // duration of the effect, in milliseconds
easing: 'ease-in-out', // CSS transition easing function
opener: function(openerElement) {
return openerElement.is('img') ? openerElement : openerElement.find('img');
}
}
});
};
/* ===============================================
9. Youtube Popup - This is used for the youtube video popup
=============================================== */
function video_popup(){
var $btnLoadMore = $(
'
'
);
var items = $(".youtube-popup[data-listnum]");
var count = items.length;
var slice = 2;
var current = 0;
if (items.length > slice) {
//bind load more event
$btnLoadMore.on("click", function(e) {
e.preventDefault();
loadMoreNews();
});
//append load more button
items.closest(".salvattore-grid").after($btnLoadMore);
}
function getItem(listnum) {
return items
.filter(function(index) {
if ($(this).attr("data-listnum") == listnum) {
return true;
}
});
}
function loadMoreNews() {
var end = current + slice;
if (end >= count) {
end = count;
$btnLoadMore.hide();
}
while (current < end) {
var listnum = current + 1; //data-listnum : 1-based
var item = getItem(listnum);
if (item) {
item.fadeIn();
}
current++;
}
}
//youtube popup
$(".popup-youtube").magnificPopup({
type: "iframe",
removalDelay: 160,
preloader: false,
fixedContentPos: false,
iframe: {
markup:
'",
patterns: {
youtube: {
index: "youtube.com/",
id: "v=",
src: "//www.youtube.com/embed/%id%?autoplay=1&rel=0&showinfo=0"
}
},
srcAction: "iframe_src"
}
});
//init load
loadMoreNews();
};
/* ===============================================
10. Counter - This is used for the counter section
=============================================== */
"use strict";
jQuery(document).ready(function ($) {
$('.counter').counterUp({
delay: 10,
time: 1000
});
});
/* ===============================================
11. Counter Up This is used for the counter section
=============================================== */
function counter_up(){
"use strict";
$.fn.counterUp = function (options) {
// Defaults
var settings = $.extend({
'time': 400,
'delay': 10,
'offset': 100,
'beginAt': 0,
'formatter': false,
'context': 'window',
callback: function () {
}
}, options),
s;
return this.each(function () {
// Store the object
var $this = $(this),
counter = {
time: $(this).data('counterup-time') || settings.time,
delay: $(this).data('counterup-delay') || settings.delay,
offset: $(this).data('counterup-offset') || settings.offset,
beginAt: $(this).data('counterup-beginat') || settings.beginAt,
context: $(this).data('counterup-context') || settings.context
};
var counterUpper = function () {
var nums = [];
var divisions = counter.time / counter.delay;
var num = $this.attr('data-num') ? $this.attr('data-num') : $this.text();
var isComma = /[0-9]+,[0-9]+/.test(num);
num = num.replace(/,/g, '');
var decimalPlaces = (num.split('.')[1] || []).length;
if (counter.beginAt > num)
counter.beginAt = num;
var isTime = /[0-9]+:[0-9]+:[0-9]+/.test(num);
// Convert time to total seconds
if (isTime) {
var times = num.split(':'),
m = 1;
s = 0;
while (times.length > 0) {
s += m * parseInt(times.pop(), 10);
m *= 60;
}
}
// Generate list of incremental numbers to display
for (var i = divisions; i >= counter.beginAt / num * divisions; i--) {
var newNum = parseFloat(num / divisions * i).toFixed(decimalPlaces);
// Add incremental seconds and convert back to time
if (isTime) {
newNum = parseInt(s / divisions * i);
var hours = parseInt(newNum / 3600) % 24;
var minutes = parseInt(newNum / 60) % 60;
var seconds = parseInt(newNum % 60, 10);
newNum = (hours < 10 ? "0" + hours : hours) + ":" + (minutes < 10 ? "0" + minutes : minutes) + ":" + (seconds < 10 ? "0" + seconds : seconds);
}
// Preserve commas if input had commas
if (isComma) {
while (/(\d+)(\d{3})/.test(newNum.toString())) {
newNum = newNum.toString().replace(/(\d+)(\d{3})/, '$1' + ',' + '$2');
}
}
if (settings.formatter) {
newNum = settings.formatter.call(this, newNum);
}
nums.unshift(newNum);
}
$this.data('counterup-nums', nums);
$this.text(counter.beginAt);
// Updates the number until we're done
var f = function () {
if (!$this.data('counterup-nums')) {
settings.callback.call(this);
return;
}
$this.html($this.data('counterup-nums').shift());
if ($this.data('counterup-nums').length) {
setTimeout($this.data('counterup-func'), counter.delay);
} else {
$this.data('counterup-nums', null);
$this.data('counterup-func', null);
settings.callback.call(this);
}
};
$this.data('counterup-func', f);
// Start the count up
setTimeout($this.data('counterup-func'), counter.delay);
};
// Perform counts when the element gets into view
$this.waypoint(function (direction) {
counterUpper();
this.destroy(); //-- Waypoint 3.0 version of triggerOnce
}, {offset: counter.offset + "%", context: counter.context});
});
};
(jQuery);
};
/* ===============================================
12. Imager hover Movement - This is used for the image hover on the about-us-2.html page
=============================================== */
$(document).on('mousemove', function (e) {
$('.light').css({
left: e.pageX - 300,
top: e.pageY - 300 });
});
var el = $('.js-tilt-container');
el.on('mousemove', function (e) {var _$$offset =
$(this).offset(),left = _$$offset.left,top = _$$offset.top;
var cursPosX = e.pageX - left;
var cursPosY = e.pageY - top;
var cursFromCenterX = $(this).width() / 2 - cursPosX;
var cursFromCenterY = $(this).height() / 2 - cursPosY;
$(this).css('transform', 'perspective(500px) rotateX(' + cursFromCenterY / 40 + 'deg) rotateY(' + -(cursFromCenterX / 40) + 'deg) translateZ(10px)');
var invertedX = Math.sign(cursFromCenterX) > 0 ? -Math.abs(cursFromCenterX) : Math.abs(cursFromCenterX);
//Parallax transform on image
$(this).find('.js-perspective-neg').css('transform', 'translateY(' + cursFromCenterY / 10 + 'px) translateX(' + -(invertedX / 10) + 'px) scale(1.15)');
$(this).removeClass('leave');
});
el.on('mouseleave', function () {
$(this).addClass('leave');
});
/* ===============================================
13. Filter Gallery This is used for filter gallery
=============================================== */
$(function(){
var $margin = $("#kehl-grid").isotope({
itemSelector:".grid-box",
// Different transition duration
transitionDuration: "0.5s"
});
// on filter button click
$( ".filter-container li" ).click( function( e ) {
var $this = $(this);
// Prevent default behaviour
e.preventDefault();
$('.filter li').removeClass('active');
$this.addClass('active');
// Get the filter data attribute from the button
var $filter = $this.attr( "data-filter" );
// filter
$margin.isotope({
filter: $filter
});
});
});
/* ===============================================
14. Masonry Gallery Loader - This is used on the grid gallery to avoid image overlapping
=============================================== */
// external js: masonry.pkgd.js, imagesloaded.pkgd.js
// init Masonry after all images have loaded
var $grid = $('.grid').imagesLoaded( function() {
$grid.masonry({
itemSelector: '.grid-box',
percentPosition: true,
columnWidth: '.grid-sizer'
});
});
/* ===============================================
15. Grid Carousel - This is used on the grid carousel on the default home page
=============================================== */
function services_carousel(){
$('.grid-carousel').slick({
slidesToShow: 3,
slidesToScroll: 1,
autoplay: true,
autoplaySpeed: 1500,
arrows: false,
dots: false,
pauseOnHover: false,
responsive: [{
breakpoint: 1500,
settings: {
slidesToShow: 2
}
}, {
breakpoint: 650,
settings: {
slidesToShow:1
}
}]
});
};
/* ===============================================
16. Team Carousel - This is used on the team carousel located on the construction home page
=============================================== */
function team_carousel_alt(){
$('.team-carousel-alt').slick({
slidesToShow: 3,
slidesToScroll: 1,
autoplay: false,
autoplaySpeed: 1500,
arrows: false,
dots: false,
pauseOnHover: false,
responsive: [{
breakpoint: 992,
settings: {
slidesToShow: 2
}
}, {
breakpoint: 650,
settings: {
slidesToShow:1
}
}]
});
};
/* ===============================================
17. Grid Carousel Alt - This is used on the grid carousel
=============================================== */
function grid_carousel_alt(){
$('.services-carousel').slick({
slidesToShow: 3,
slidesToScroll: 1,
autoplay: true,
autoplaySpeed: 1500,
arrows: false,
dots: false,
pauseOnHover: false,
responsive: [{
breakpoint: 1200,
settings: {
slidesToShow: 2
}
}, {
breakpoint: 768,
settings: {
slidesToShow:1
}
}]
});
};
/* ===============================================
18. News Carousel - This is used on the blog news at the template pages bottom
=============================================== */
function news_carousel_alt(){
$('.news-carousel').slick({
slidesToShow: 3,
slidesToScroll: 1,
autoplay: false,
autoplaySpeed: 1500,
arrows: false,
dots: false,
pauseOnHover: false,
responsive: [{
breakpoint: 1200,
settings: {
slidesToShow: 2
}
}, {
breakpoint: 768,
settings: {
slidesToShow:1
}
}]
});
};
/* ===============================================
19. Projects Carousel - This is used on the project carousel, it display the related projects
=============================================== */
function projects_carousel(){
$('.projects-carousel').slick({
slidesToShow: 3,
slidesToScroll: 1,
autoplay: false,
autoplaySpeed: 1500,
arrows: false,
dots: false,
pauseOnHover: false,
responsive: [{
breakpoint: 1200,
settings: {
slidesToShow: 2
}
}, {
breakpoint: 768,
settings: {
slidesToShow:1
}
}]
});
};
/* ===============================================
20. Welding Carousel - This is used on the welding home page carousel
=============================================== */
function welding_carousel(){
$('.welding-carousel').slick({
slidesToShow: 3,
slidesToScroll: 1,
autoplay: true,
autoplaySpeed: 1500,
arrows: false,
dots: false,
pauseOnHover: false,
responsive: [{
breakpoint: 1200,
settings: {
slidesToShow: 2
}
}, {
breakpoint: 700,
settings: {
slidesToShow:1
}
}]
});
};
/* ===============================================
21. Contact Form - This is used for the contact form
=============================================== */
function testimonial_carousel(){
$("#testimonial-carousel").owlCarousel({
items:2,
itemsDesktop:[1000,2],
itemsDesktopSmall:[992,2],
itemsTablet:[750,1],
pagination:true,
navigation:false,
slideSpeed:1000,
singleItem:false,
navigationText:["",""],
autoPlay:true
});
};
/* ===============================================
21. Contact Form - This is used for the contact form
=============================================== */
"use strict";
$(function () {
$('#contact-form').validator();
$('#contact-form').on('submit', function (e) {
if (!e.isDefaultPrevented()) {
var url = "contact.php";
$.ajax({
type: "POST",
url: url,
data: $(this).serialize(),
success: function (data)
{
var messageAlert = 'alert-' + data.type;
var messageText = data.message;
var alertBox = '' + messageText + '
';
if (messageAlert && messageText) {
$('#contact-form').find('.messages').html(alertBox);
$('#contact-form')[0].reset();
}
}
});
return false;
}
})
});
"use strict";
+function ($) {
// VALIDATOR CLASS DEFINITION
// ==========================
function getValue($el) {
return $el.is('[type="checkbox"]') ? $el.prop('checked') :
$el.is('[type="radio"]') ? !!$('[name="' + $el.attr('name') + '"]:checked').length :
$el.val()
}
var Validator = function (element, options) {
this.options = options
this.validators = $.extend({}, Validator.VALIDATORS, options.custom)
this.$element = $(element)
this.$btn = $('button[type="submit"], input[type="submit"]')
.filter('[form="' + this.$element.attr('id') + '"]')
.add(this.$element.find('input[type="submit"], button[type="submit"]'))
this.update()
this.$element.on('input.bs.validator change.bs.validator focusout.bs.validator', $.proxy(this.onInput, this))
this.$element.on('submit.bs.validator', $.proxy(this.onSubmit, this))
this.$element.on('reset.bs.validator', $.proxy(this.reset, this))
this.$element.find('[data-match]').each(function () {
var $this = $(this)
var target = $this.data('match')
$(target).on('input.bs.validator', function (e) {
getValue($this) && $this.trigger('input.bs.validator')
})
})
this.$inputs.filter(function () { return getValue($(this)) }).trigger('focusout')
this.$element.attr('novalidate', true) // disable automatic native validation
this.toggleSubmit()
}
Validator.VERSION = '0.11.5'
Validator.INPUT_SELECTOR = ':input:not([type="hidden"], [type="submit"], [type="reset"], button)'
Validator.FOCUS_OFFSET = 20
Validator.DEFAULTS = {
delay: 500,
html: false,
disable: true,
focus: true,
custom: {},
errors: {
match: 'Does not match',
minlength: 'Not long enough'
},
feedback: {
success: 'glyphicon-ok',
error: 'glyphicon-remove'
}
}
Validator.VALIDATORS = {
'native': function ($el) {
var el = $el[0]
if (el.checkValidity) {
return !el.checkValidity() && !el.validity.valid && (el.validationMessage || "error!")
}
},
'match': function ($el) {
var target = $el.data('match')
return $el.val() !== $(target).val() && Validator.DEFAULTS.errors.match
},
'minlength': function ($el) {
var minlength = $el.data('minlength')
return $el.val().length < minlength && Validator.DEFAULTS.errors.minlength
}
}
Validator.prototype.update = function () {
this.$inputs = this.$element.find(Validator.INPUT_SELECTOR)
.add(this.$element.find('[data-validate="true"]'))
.not(this.$element.find('[data-validate="false"]'))
return this
}
Validator.prototype.onInput = function (e) {
var self = this
var $el = $(e.target)
var deferErrors = e.type !== 'focusout'
if (!this.$inputs.is($el)) return
this.validateInput($el, deferErrors).done(function () {
self.toggleSubmit()
})
}
Validator.prototype.validateInput = function ($el, deferErrors) {
var value = getValue($el)
var prevErrors = $el.data('bs.validator.errors')
var errors
if ($el.is('[type="radio"]')) $el = this.$element.find('input[name="' + $el.attr('name') + '"]')
var e = $.Event('validate.bs.validator', {relatedTarget: $el[0]})
this.$element.trigger(e)
if (e.isDefaultPrevented()) return
var self = this
return this.runValidators($el).done(function (errors) {
$el.data('bs.validator.errors', errors)
errors.length
? deferErrors ? self.defer($el, self.showErrors) : self.showErrors($el)
: self.clearErrors($el)
if (!prevErrors || errors.toString() !== prevErrors.toString()) {
e = errors.length
? $.Event('invalid.bs.validator', {relatedTarget: $el[0], detail: errors})
: $.Event('valid.bs.validator', {relatedTarget: $el[0], detail: prevErrors})
self.$element.trigger(e)
}
self.toggleSubmit()
self.$element.trigger($.Event('validated.bs.validator', {relatedTarget: $el[0]}))
})
}
Validator.prototype.runValidators = function ($el) {
var errors = []
var deferred = $.Deferred()
$el.data('bs.validator.deferred') && $el.data('bs.validator.deferred').reject()
$el.data('bs.validator.deferred', deferred)
function getValidatorSpecificError(key) {
return $el.data(key + '-error')
}
function getValidityStateError() {
var validity = $el[0].validity
return validity.typeMismatch ? $el.data('type-error')
: validity.patternMismatch ? $el.data('pattern-error')
: validity.stepMismatch ? $el.data('step-error')
: validity.rangeOverflow ? $el.data('max-error')
: validity.rangeUnderflow ? $el.data('min-error')
: validity.valueMissing ? $el.data('required-error')
: null
}
function getGenericError() {
return $el.data('error')
}
function getErrorMessage(key) {
return getValidatorSpecificError(key)
|| getValidityStateError()
|| getGenericError()
}
$.each(this.validators, $.proxy(function (key, validator) {
var error = null
if ((getValue($el) || $el.attr('required')) &&
($el.data(key) || key == 'native') &&
(error = validator.call(this, $el))) {
error = getErrorMessage(key) || error
!~errors.indexOf(error) && errors.push(error)
}
}, this))
if (!errors.length && getValue($el) && $el.data('remote')) {
this.defer($el, function () {
var data = {}
data[$el.attr('name')] = getValue($el)
$.get($el.data('remote'), data)
.fail(function (jqXHR, textStatus, error) { errors.push(getErrorMessage('remote') || error) })
.always(function () { deferred.resolve(errors)})
})
} else deferred.resolve(errors)
return deferred.promise()
}
Validator.prototype.validate = function () {
var self = this
$.when(this.$inputs.map(function (el) {
return self.validateInput($(this), false)
})).then(function () {
self.toggleSubmit()
self.focusError()
})
return this
}
Validator.prototype.focusError = function () {
if (!this.options.focus) return
var $input = this.$element.find(".has-error:first :input")
if ($input.length === 0) return
$('html, body').animate({scrollTop: $input.offset().top - Validator.FOCUS_OFFSET}, 250)
$input.focus()
}
Validator.prototype.showErrors = function ($el) {
var method = this.options.html ? 'html' : 'text'
var errors = $el.data('bs.validator.errors')
var $group = $el.closest('.form-group')
var $block = $group.find('.help-block.with-errors')
var $feedback = $group.find('.form-control-feedback')
if (!errors.length) return
errors = $('')
.addClass('list-unstyled')
.append($.map(errors, function (error) { return $('')[method](error) }))
$block.data('bs.validator.originalContent') === undefined && $block.data('bs.validator.originalContent', $block.html())
$block.empty().append(errors)
$group.addClass('has-error has-danger')
$group.hasClass('has-feedback')
&& $feedback.removeClass(this.options.feedback.success)
&& $feedback.addClass(this.options.feedback.error)
&& $group.removeClass('has-success')
}
Validator.prototype.clearErrors = function ($el) {
var $group = $el.closest('.form-group')
var $block = $group.find('.help-block.with-errors')
var $feedback = $group.find('.form-control-feedback')
$block.html($block.data('bs.validator.originalContent'))
$group.removeClass('has-error has-danger has-success')
$group.hasClass('has-feedback')
&& $feedback.removeClass(this.options.feedback.error)
&& $feedback.removeClass(this.options.feedback.success)
&& getValue($el)
&& $feedback.addClass(this.options.feedback.success)
&& $group.addClass('has-success')
}
Validator.prototype.hasErrors = function () {
function fieldErrors() {
return !!($(this).data('bs.validator.errors') || []).length
}
return !!this.$inputs.filter(fieldErrors).length
}
Validator.prototype.isIncomplete = function () {
function fieldIncomplete() {
var value = getValue($(this))
return !(typeof value == "string" ? $.trim(value) : value)
}
return !!this.$inputs.filter('[required]').filter(fieldIncomplete).length
}
Validator.prototype.onSubmit = function (e) {
this.validate()
if (this.isIncomplete() || this.hasErrors()) e.preventDefault()
}
Validator.prototype.toggleSubmit = function () {
if (!this.options.disable) return
this.$btn.toggleClass('disabled', this.isIncomplete() || this.hasErrors())
}
Validator.prototype.defer = function ($el, callback) {
callback = $.proxy(callback, this, $el)
if (!this.options.delay) return callback()
window.clearTimeout($el.data('bs.validator.timeout'))
$el.data('bs.validator.timeout', window.setTimeout(callback, this.options.delay))
}
Validator.prototype.reset = function () {
this.$element.find('.form-control-feedback')
.removeClass(this.options.feedback.error)
.removeClass(this.options.feedback.success)
this.$inputs
.removeData(['bs.validator.errors', 'bs.validator.deferred'])
.each(function () {
var $this = $(this)
var timeout = $this.data('bs.validator.timeout')
window.clearTimeout(timeout) && $this.removeData('bs.validator.timeout')
})
this.$element.find('.help-block.with-errors')
.each(function () {
var $this = $(this)
var originalContent = $this.data('bs.validator.originalContent')
$this
.removeData('bs.validator.originalContent')
.html(originalContent)
})
this.$btn.removeClass('disabled')
this.$element.find('.has-error, .has-danger, .has-success').removeClass('has-error has-danger has-success')
return this
}
Validator.prototype.destroy = function () {
this.reset()
this.$element
.removeAttr('novalidate')
.removeData('bs.validator')
.off('.bs.validator')
this.$inputs
.off('.bs.validator')
this.options = null
this.validators = null
this.$element = null
this.$btn = null
return this
}
// VALIDATOR PLUGIN DEFINITION
// ===========================
function Plugin(option) {
return this.each(function () {
var $this = $(this)
var options = $.extend({}, Validator.DEFAULTS, $this.data(), typeof option == 'object' && option)
var data = $this.data('bs.validator')
if (!data && option == 'destroy') return
if (!data) $this.data('bs.validator', (data = new Validator(this, options)))
if (typeof option == 'string') data[option]()
})
}
var old = $.fn.validator
$.fn.validator = Plugin
$.fn.validator.Constructor = Validator
// VALIDATOR NO CONFLICT
// =====================
$.fn.validator.noConflict = function () {
$.fn.validator = old
return this
}
// VALIDATOR DATA-API
// ==================
$(window).on('load', function () {
$('form[data-toggle="validator"]').each(function () {
var $form = $(this)
Plugin.call($form, $form.data())
})
})
}(jQuery);