agenda-libre-ruby/public/webshims/shims/form-validation.js

1020 lines
29 KiB
JavaScript
Raw Normal View History

webshims.register('form-validation', function($, webshims, window, document, undefined, options){
"use strict";
var isWebkit = 'webkitURL' in window;
var support = webshims.support;
var hasNative = support.formvalidation && !webshims.bugs.bustedValidity;
var chromeBugs = isWebkit && hasNative;
var ua = navigator.userAgent;
var isIE = ua.indexOf('MSIE') != -1;
var webkitVersion = chromeBugs && parseFloat((ua.match(/Safari\/([\d\.]+)/) || ['', '999999'])[1], 10);
var iVal = options.iVal;
var invalidClass = iVal.errorClass || (iVal.errorClass = 'user-error');
var validClass = iVal.successClass || (iVal.successClass = 'user-success');
var markedClases = '.'+validClass+', .'+invalidClass;
var invalidWrapperClass = iVal.errorWrapperClass || (iVal.errorWrapperClass = 'ws-invalid');
var successWrapperClass = iVal.successWrapperClass || (iVal.successWrapperClass = 'ws-success');
var errorBoxClass = iVal.errorBoxClass || (iVal.errorBoxClass = 'ws-errorbox');
var errorMessageClass = iVal.errorMessageClass || (iVal.errorMessageClass = 'ws-errormessage');
var errorBoxWrapper = iVal.errorBoxWrapper || (iVal.errorBoxWrapper = 'div');
var errorMessageWrapper = iVal.errorMessageWrapper || (iVal.errorMessageWrapper = 'p');
var checkTypes = {checkbox: 1, radio: 1};
var loader = webshims.loader;
var addModule = loader.addModule;
var emptyJ = $([]);
var nonFormFilter = function(){
return !$.prop(this, 'form');
};
var getGroupElements = webshims.modules["form-core"].getGroupElements || function(elem){
elem = $(elem);
var name;
var form;
var ret = emptyJ;
if(elem[0].type == 'radio'){
form = elem.prop('form');
name = elem[0].name;
if(!name){
ret = elem;
} else if(form){
ret = $(form).jProp(name);
} else {
ret = $(document.getElementsByName(name)).filter(nonFormFilter);
}
ret = ret.filter('[type="radio"]');
}
return ret;
};
var returnValidityCause = function(validity, elem){
var ret;
$.each(validity, function(name, value){
if(value){
ret = name + $.prop(elem, 'validationMessage');
return false;
}
});
return ret;
};
var isInGroup = function(name){
var ret;
try {
ret = document.activeElement.name === name;
} catch(e){}
return ret;
};
//actually we could always use the change event, but chrome messed it up and does not respect the commit action definition of the html spec
//see: http://code.google.com/p/chromium/issues/detail?id=155747
var changeTypes = {
radio: 1,
checkbox: 1,
'select-one': 1,
'select-multiple': 1,
file: 1,
date: 1,
month: 1,
week: 1,
text: 1
};
//see: http://code.google.com/p/chromium/issues/detail?id=179708 and bug above
var noFocusWidgets = {
time: 1,
date: 1,
month: 1,
datetime: 1,
week: 1,
'datetime-local': 1
};
var updateValidationEvents = {
refreshvalidityui: 1,
updatevalidation: 1
};
var iValClasses = '.'+ iVal.errorClass +', .'+iVal.successClass;
var switchValidityClass = function(e){
if(!iVal.sel){return;}
var elem, timer, shadowElem, shadowType;
if(!e.target){return;}
elem = $(e.target).getNativeElement()[0];
shadowElem = $(elem).getShadowElement();
if(elem.type == 'submit' || !$.prop(elem, 'willValidate') || (e.type == 'change' && (shadowType = shadowElem.prop('type')) && !changeTypes[shadowType])){return;}
timer = $.data(elem, 'webshimsswitchvalidityclass');
var switchClass = function(){
if(!shadowType){
shadowType = shadowElem.prop('type');
}
if(
2014-07-20 02:43:13 +02:00
(chromeBugs && (e.type == 'change' || webkitVersion < 537.36) && noFocusWidgets[shadowType] && $.find.matchesSelector(e.target, ':focus')) ||
(e.type == 'focusout' && elem.type == 'radio' && isInGroup(elem.name))
){
return;
}
if(webshims.refreshCustomValidityRules && webshims.refreshCustomValidityRules(elem) == 'async'){
$(elem).one('updatevalidation.webshims', switchValidityClass);
return;
}
var validity = $.prop(elem, 'validity');
var addClass, removeClass, trigger, generaltrigger, validityCause;
if(validity.valid){
if(!shadowElem.hasClass(validClass)){
addClass = validClass;
removeClass = invalidClass;
generaltrigger = 'changedvaliditystate';
trigger = 'changedvalid';
if(checkTypes[elem.type] && elem.checked){
getGroupElements(elem).not(elem).removeClass(removeClass).addClass(addClass).removeAttr('aria-invalid');
}
shadowElem.removeAttr('aria-invalid');
$.removeData(elem, 'webshimsinvalidcause');
}
} else {
validityCause = returnValidityCause(validity, elem);
if($.data(elem, 'webshimsinvalidcause') != validityCause){
$.data(elem, 'webshimsinvalidcause', validityCause);
generaltrigger = 'changedvaliditystate';
}
if(!shadowElem.hasClass(invalidClass)){
addClass = invalidClass;
removeClass = validClass;
if (checkTypes[elem.type] && !elem.checked) {
getGroupElements(elem).not(elem).removeClass(removeClass).addClass(addClass).attr('aria-invalid', 'true');
}
shadowElem.attr('aria-invalid', 'true');
trigger = 'changedinvalid';
}
}
if(addClass){
shadowElem.addClass(addClass).removeClass(removeClass);
//jQuery 1.6.1 IE9 bug (doubble trigger bug)
setTimeout(function(){
$(elem).trigger(trigger);
});
}
if(generaltrigger){
setTimeout(function(){
$(elem).trigger(generaltrigger);
});
}
$.removeData(elem, 'webshimsswitchvalidityclass');
};
if(shadowElem.triggerHandler('wsallowinstantvalidation', [e]) !== false){
if(timer){
clearTimeout(timer);
}
if(updateValidationEvents[e.type]){
if(e.type == 'refreshvalidityui'){
webshims.error('refreshvalidityui was renamed to updatevalidation');
}
switchClass();
} else {
$.data(elem, 'webshimsswitchvalidityclass', setTimeout(switchClass));
}
}
};
var eachReset = function(){
webshims.errorbox.reset(this);
};
if('validityUIEvents' in options){
webshims.error('validityUIEvents was renamed to iVal.events');
iVal.events = options.validityUIEvents;
}
if('events' in iVal){
iVal.events = iVal.events || '';
} else {
iVal.events = 'focusout change';
}
if(iVal.events){
iVal.events += ' ';
}
if(!iVal.fieldWrapper){
iVal.fieldWrapper = ':not(span):not(label):not(em):not(strong):not(p):not(.ws-custom-file)';
}
if(!webshims.modules["form-core"].getGroupElements){
webshims.modules["form-core"].getGroupElements = getGroupElements;
}
$(document.body || 'html')
.on(iVal.events+'refreshvalidityui updatevalidation.webshims invalid', switchValidityClass)
.on('refreshvalidationui.webshims', function(e){
if($(e.target).getShadowElement().is(markedClases)){
switchValidityClass({type: 'updatevalidation', target: e.target});
}
})
.on('reset resetvalidation.webshims resetvalui', function(e){
var noIValTrigger;
var elems = $(e.target);
if(e.type == 'resetvalui'){
webshims.error('resetvalui was renamed to resetvalidation');
}
if(elems.is('form, fieldset')){
if(elems[0].nodeName.toLowerCase() == 'form'){
noIValTrigger = !elems.is(iVal.sel);
}
elems = elems.jProp('elements');
}
elems = elems
.filter(iValClasses)
.removeAttr('aria-invalid')
.removeClass(iVal.errorClass +' '+ iVal.successClass)
.getNativeElement()
.each(function(){
$.removeData(this, 'webshimsinvalidcause');
})
;
if(!noIValTrigger){
if(noIValTrigger === false){
elems.each(eachReset);
} else {
elems.trigger('resetvalidityui.webshims');
}
}
})
;
var setRoot = function(){
webshims.scrollRoot = (isWebkit || document.compatMode == 'BackCompat') ?
$(document.body) :
$(document.documentElement)
;
};
var hasTransition = ('transitionDelay' in document.documentElement.style);
var resetPos = {display: 'inline-block', left: 0, top: 0, marginTop: 0, marginLeft: 0, marginRight: 0, marginBottom: 0};
var fx = {
slide: {
show: 'slideDown',
hide: 'slideUp'
},
fade: {
show: 'fadeIn',
hide: 'fadeOut'
},
no: {
show: 'show',
hide: 'hide'
}
};
setRoot();
webshims.ready('DOM', setRoot);
var rtlReg = /right|left/g;
var rtlReplace = function(ret){
return ret == 'left' ? 'right' : 'left';
};
webshims.getRelOffset = function(posElem, relElem, opts){
var offset, bodyOffset, dirs;
posElem = $(posElem);
$.swap(posElem[0], resetPos, function(){
var isRtl;
if($.position && opts && $.position.getScrollInfo){
if(!opts.of){
opts.of = relElem;
}
isRtl = $(opts.of).css('direction') == 'rtl';
if(!opts.isRtl){
opts.isRtl = false;
}
if(opts.isRtl != isRtl){
opts.my = (opts.my || 'center').replace(rtlReg, rtlReplace);
opts.at = (opts.at || 'center').replace(rtlReg, rtlReplace);
opts.isRtl = isRtl;
}
posElem[opts.isRtl ? 'addClass' : 'removeClass']('ws-is-rtl');
opts.using = function(calced, data){
posElem.attr({'data-horizontal': data.horizontal, 'data-vertical': data.vertical});
offset = calced;
};
posElem.attr({
'data-horizontal': '',
'data-vertical': '',
'data-my': opts.my,
'data-at': opts.at
});
posElem.position(opts);
} else {
offset = $(relElem).offset();
bodyOffset = posElem.offset();
offset.top -= bodyOffset.top;
offset.left -= bodyOffset.left;
offset.top += relElem.outerHeight();
}
});
return offset;
};
$.extend(webshims.wsPopover, {
isInElement: function(containers, contained){
if(!$.isArray(containers)){
containers = [containers];
}
var i, len, container;
var ret = false;
for(i = 0, len = containers.length; i < len; i++){
container = containers[i];
if(container && container.jquery){
container = container[0];
}
if(container && (container == contained || $.contains(container, contained))){
ret = true;
break;
}
}
return ret;
},
show: function(element){
var showAction;
if(this.isVisible){return;}
var e = $.Event('wspopoverbeforeshow');
this.element.trigger(e);
if(e.isDefaultPrevented()){return;}
this.isVisible = true;
if(!this._shadowAdded && webshims.shadowClass){
this.element.addClass(webshims.shadowClass);
this._shadowAdded = true;
}
element = $(element || this.options.prepareFor).getNativeElement() ;
var that = this;
var closeOnOutSide = function(e){
if(that.options.hideOnBlur && !that.stopBlur && !that.isInElement([that.lastElement[0], element[0], that.element[0]], e.target)){
that.hide();
}
};
var visual = $(element).getShadowElement();
var delayedRepos = function(e){
clearTimeout(that.timers.repos);
that.timers.repos = setTimeout(function(){
that.position(visual);
}, e && e.type == 'pospopover' ? 4 : 200);
};
this.clear();
this.element.css('display', 'none');
this.prepareFor(element, visual);
this.position(visual);
if(this.options.inline){
showAction = (fx[this.options.inline] || fx.slide).show;
that.element[showAction]().trigger('wspopovershow');
} else {
this.element.removeClass('ws-po-visible');
that.timers.show = setTimeout(function(){
that.element.css('display', '');
that.timers.show = setTimeout(function(){
that.element.addClass('ws-po-visible').trigger('wspopovershow');
}, 14);
}, 4);
}
$(document.body)
.on('focusin'+this.eventns+' mousedown'+this.eventns, closeOnOutSide)
//http://www.quirksmode.org/m/tests/eventdelegation2.html
.children(':not(script), :not(iframe), :not(noscript)')
.on('mousedown'+this.eventns, closeOnOutSide)
;
this.element.off('pospopover').on('pospopover', delayedRepos);
$(window).on('resize'+this.eventns + ' pospopover'+this.eventns, delayedRepos);
},
_getAutoAppendElement: (function(){
var invalidParent = /^(?:span|i|label|b|p|tr|thead|tbody|table|strong|em|ul|ol|dl|html)$/i;
return function(element){
var appendElement;
var parent = element[0];
var body = document.body;
while((parent = parent[appendElement ? 'offsetParent' : 'parentNode']) && parent.nodeType == 1 && parent != body){
if(!appendElement && !invalidParent.test(parent.nodeName)){
appendElement = parent;
}
if(appendElement && $.css(parent, 'overflow') == 'hidden' && $.css(parent, 'position') != 'static'){
appendElement = false;
}
}
return $(appendElement || body);
};
})(),
prepareFor: function(element, visual){
var onBlur, parentElem;
var that = this;
var css = {};
var opts = $.extend(true, {}, this.options, element.jProp('form').data('wspopover') || {}, element.data('wspopover'));
this.lastOpts = opts;
this.lastElement = $(element).getShadowFocusElement();
if(!this.prepared || !this.options.prepareFor){
if(opts.appendTo == 'element' || (opts.inline && opts.appendTo == 'auto')){
2014-07-20 02:43:13 +02:00
parentElem = visual.parent();
} else if(opts.appendTo == 'auto'){
2014-07-20 02:43:13 +02:00
parentElem = this._getAutoAppendElement(visual);
} else {
parentElem = $(opts.appendTo);
}
if(!this.prepared || parentElem[0] != this.element[0].parentNode){
this.element.appendTo(parentElem);
}
}
this.element.attr({
'data-class': element.prop('className'),
'data-id': element.prop('id')
});
if(opts.constrainWidth){
this.element.addClass('ws-popover-constrained-width');
css.minWidth = visual.outerWidth();
} else {
this.element.removeClass('ws-popover-constrained-width');
css.minWidth = '';
}
if(opts.inline){
this.element.addClass('ws-popinline ws-po-visible');
} else {
this.element.removeClass('ws-popinline');
}
this.element.css(css);
if(opts.hideOnBlur){
onBlur = function(e){
if(that.stopBlur){
e.stopImmediatePropagation();
} else {
that.hide();
}
};
that.timers.bindBlur = setTimeout(function(){
that.lastElement.off(that.eventns).on('focusout'+that.eventns + ' blur'+that.eventns, onBlur);
that.lastElement.getNativeElement().off(that.eventns);
}, 10);
}
this.prepared = true;
},
clear: function(){
$(window).off(this.eventns);
$(document).off(this.eventns);
$(document.body)
.off(this.eventns)
.children(':not(script), :not(iframe), :not(noscript)')
.off(this.eventns)
;
this.element.off('transitionend'+this.eventns);
this.stopBlur = false;
this.lastOpts = false;
$.each(this.timers, function(timerName, val){
clearTimeout(val);
});
},
hide: function(){
var hideAction;
var e = $.Event('wspopoverbeforehide');
this.element.trigger(e);
if(e.isDefaultPrevented() || !this.isVisible){return;}
this.isVisible = false;
var that = this;
var forceHide = function(e){
if(!(e && e.type == 'transitionend' && (e = e.originalEvent) && e.target == that.element[0] && that.element.css('visibility') == 'hidden')){
that.element.off('transitionend'+that.eventns).css('display', 'none').attr({'data-id': '', 'data-class': '', 'hidden': 'hidden'});
clearTimeout(that.timers.forcehide);
$(window).off('resize'+that.eventns);
}
};
this.clear();
if(this.options.inline){
hideAction = (fx[this.options.inline] || fx.slide).hide;
this.element[hideAction]();
} else {
this.element.removeClass('ws-po-visible');
$(window).on('resize'+this.eventns, forceHide);
if(hasTransition){
this.element.off('transitionend'+this.eventns).on('transitionend'+this.eventns, forceHide);
}
that.timers.forcehide = setTimeout(forceHide, hasTransition ? 600 : 40);
}
this.element.trigger('wspopoverhide');
},
position: function(element){
var offset;
var opts = this.lastOpts || this.options;
if(!opts.inline){
offset = webshims.getRelOffset(this.element.removeAttr('hidden'), element, (this.lastOpts || this.options).position);
this.element.css(offset);
}
}
});
/* some extra validation UI */
webshims.validityAlert = (function(){
options.messagePopover.position = $.extend({}, {
at: 'left bottom',
my: 'left top',
collision: 'none'
}, options.messagePopover.position || {});
var api = webshims.objectCreate(webshims.wsPopover, undefined, options.messagePopover);
var boundHide = api.hide.bind(api);
api.element.addClass('validity-alert').attr({role: 'alert'});
$.extend(api, {
hideDelay: 5000,
showFor: function(elem, message, noFocusElem, noBubble){
elem = $(elem).getNativeElement();
this.clear();
this.hide();
if(!noBubble){
this.getMessage(elem, message);
this.show(elem);
if(this.hideDelay){
this.timers.delayedHide = setTimeout(boundHide, this.hideDelay);
}
}
if(!noFocusElem){
this.setFocus(elem);
}
},
setFocus: function(element){
var focusElem = $(element).getShadowFocusElement();
var scrollTop = webshims.scrollRoot.scrollTop() + (options.viewportOffset || 0);
var elemTop = focusElem.offset().top - (options.scrollOffset || 30);
var focus = function(){
try {
focusElem[0].focus();
} catch(e){}
if(!focusElem[0].offsetWidth && !focusElem[0].offsetHeight){
webshims.warn('invalid element seems to be hidden. Make element either visible or use disabled/readonly to bar elements from validation. With fieldset[disabled] a group of elements can be ignored! In case of select replacement see shims/form-combat.js to fix issue.');
}
api.element.triggerHandler('pospopover');
};
if(scrollTop > elemTop){
webshims.scrollRoot.animate(
{scrollTop: elemTop - 5 - (options.viewportOffset || 0)},
{
queue: false,
duration: Math.max( Math.min( 600, (scrollTop - elemTop) * 1.5 ), 80 ),
complete: focus
}
);
} else {
focus();
}
},
getMessage: function(elem, message){
if (!message) {
message = elem.getErrorMessage();
}
if (message) {
api.contentElement.html(message);
} else {
this.hide();
}
}
});
return api;
})();
if(!iVal.fx || !fx[iVal.fx]){
iVal.fx = 'slide';
}
if(!$.fn[fx[iVal.fx].show]){
iVal.fx = 'no';
}
var errorBoxId = 0;
webshims.errorbox = {
create: function(elem, fieldWrapper){
if(!fieldWrapper){
fieldWrapper = this.getFieldWrapper(elem);
}
var errorBox = $('.'+errorBoxClass, fieldWrapper);
if(!errorBox.length){
errorBox = $('<'+errorBoxWrapper+' class="'+ errorBoxClass +'" hidden="hidden" style="display: none;">');
fieldWrapper.append(errorBox);
}
if(!errorBox.prop('id')){
errorBoxId++;
errorBox.prop('id', 'errorbox-'+errorBoxId);
}
fieldWrapper.data('errorbox', errorBox);
return errorBox;
},
getFieldWrapper: function(elem){
var fieldWrapper;
fieldWrapper = (typeof iVal.fieldWrapper == "function") ? iVal.fieldWrapper.apply(this, arguments) : $(elem).parent().closest(iVal.fieldWrapper);
if(!fieldWrapper.length){
webshims.error("could not find fieldwrapper: "+ iVal.fieldWrapper);
}
return fieldWrapper;
},
_createContentMessage: (function(){
var noValidate = function(){
return !noValidate.types[this.type];
};
noValidate.types = {
hidden: 1,
image: 1,
button: 1,
reset: 1,
submit: 1
};
var fields = {};
var deCamelCase = function(c){
return '-'+(c).toLowerCase();
};
var getErrorName = function(elem){
var ret = $(elem).data('errortype');
if(!ret){
$.each(fields, function(errorName, cNames){
2014-07-20 02:43:13 +02:00
if($.find.matchesSelector(elem, cNames)){
ret = errorName;
return false;
}
});
}
return ret || 'defaultMessage';
};
$.each(["customError","badInput","typeMismatch","rangeUnderflow","rangeOverflow","stepMismatch","tooLong","tooShort","patternMismatch","valueMissing"], function(i, name){
var cName = name.replace(/[A-Z]/, deCamelCase);
fields[name] = '.'+cName+', .'+name+', .'+(name).toLowerCase()+', [data-errortype="'+ name +'"]';
});
return function(elem, errorBox, fieldWrapper){
var extended = false;
var descriptiveMessages = {};
$(errorBox).children().each(function(){
var name = getErrorName(this);
descriptiveMessages[name] = $(this).html();
});
$('input, select, textarea', fieldWrapper).filter(noValidate).each(function(i, elem){
var errorMessages = $(elem).data('errormessage') || {};
if(typeof errorMessages == 'string'){
errorMessages = {defaultMessage: errorMessages};
}
$.each(descriptiveMessages, function(name, val){
if(!errorMessages[name]){
extended = true;
errorMessages[name] = val;
}
});
if(extended){
$(elem).data('errormessage', errorMessages);
}
if(webshims.getOptions){
webshims.getOptions(elem, 'errormessage', false, true);
}
});
};
})(),
initIvalContentMessage: function(elem){
2014-07-20 02:43:13 +02:00
var form;
if(iVal.sel && (form = $.prop(elem, 'form')) && $.find.matchesSelector(form, iVal.sel)){
this.get(elem);
}
},
get: function(elem, fieldWrapper){
if(!fieldWrapper){
fieldWrapper = this.getFieldWrapper(elem);
}
var type;
var errorBox = fieldWrapper.data('errorbox');
if((type = typeof errorBox) != 'object'){
if(!errorBox){
errorBox = this.create(elem, fieldWrapper);
} else if(type == 'string'){
errorBox = $('#'+errorBox);
fieldWrapper.data('errorbox', errorBox, fieldWrapper);
}
this._createContentMessage(elem, errorBox, fieldWrapper);
}
return errorBox;
},
addSuccess: function(elem, fieldWrapper){
var type = $.prop(elem, 'type');
var check = function(){
var hasVal = checkTypes[type] ? $.prop(elem, 'checked') : $(elem).val();
fieldWrapper[hasVal ? 'addClass' : 'removeClass'](successWrapperClass);
};
var evt = changeTypes[type] ? 'change' : 'blur';
$(elem).off('.recheckvalid').on(evt+'.recheckinvalid', check);
check();
},
hideError: function(elem, reset){
var invalid, errorBox, afterHide;
var fieldWrapper = this.getFieldWrapper(elem);
if(fieldWrapper.hasClass(invalidWrapperClass)){
$(elem).filter('input').off('.recheckinvalid');
if(!reset && (invalid = $('input:invalid, select:invalid, textarea:invalid', fieldWrapper)[0])){
$(invalid).trigger('updatevalidation.webshims');
} else {
errorBox = this.get(elem, fieldWrapper);
fieldWrapper.removeClass(invalidWrapperClass);
errorBox.message = '';
afterHide = function(){
if(this.id == elem.getAttribute('aria-describedby')){
elem.removeAttribute('aria-describedby');
}
$(this).attr({hidden: 'hidden'});
};
if(iVal.fx != 'no'){
errorBox[fx[iVal.fx].hide](afterHide);
} else {
errorBox[fx[iVal.fx].hide]().each(afterHide);
}
}
}
if(!reset && !invalid){
this.addSuccess(elem, fieldWrapper);
}
return fieldWrapper;
},
recheckInvalidInput: function(input){
if(iVal.recheckDelay && iVal.recheckDelay > 90){
var timer;
var throttle = function(){
switchValidityClass({type: 'input', target: input});
};
$(input)
2014-07-20 02:43:13 +02:00
.filter('input:not([type="checkbox"]):not([type="radio"]), textarea')
.off('.recheckinvalid')
.on('input.recheckinvalid', function(){
clearTimeout(timer);
timer = setTimeout(throttle, iVal.recheckDelay);
})
.on('focusout.recheckinvalid', function(){
clearTimeout(timer);
})
;
}
},
showError: function(elem){
var fieldWrapper = this.getFieldWrapper(elem);
var box = this.get(elem, fieldWrapper);
var message = $(elem).getErrorMessage();
if(box.message != message){
if(box.stop){
box.stop(true, true);
}
box.html('<'+ errorMessageWrapper +' class="'+ errorMessageClass +'">'+ message +'</'+ errorMessageWrapper +'>');
box.message = message;
fieldWrapper.addClass(invalidWrapperClass).removeClass(successWrapperClass);
this.recheckInvalidInput(elem);
if(box.is('[hidden]') || box.css('display') == 'none'){
if(!elem.getAttribute('aria-describedby')){
elem.setAttribute('aria-describedby', box.prop('id'));
}
box
.css({display: 'none'})
.removeAttr('hidden')
[fx[iVal.fx].show]()
;
}
}
fieldWrapper.removeClass(successWrapperClass);
$(elem).off('.recheckvalid');
return fieldWrapper;
},
reset: function(elem){
this.hideError(elem, true).removeClass(successWrapperClass);
},
toggle: function(elem){
2014-07-20 02:43:13 +02:00
if($.find.matchesSelector(elem, ':invalid')){
this.showError(elem);
} else {
this.hideError(elem);
}
}
};
$(document.body)
.on({
'changedvaliditystate': function(e){
2014-07-20 02:43:13 +02:00
var form;
if(iVal.sel && (form = $.prop(e.target, 'form')) && $.find.matchesSelector(form, iVal.sel)){
webshims.errorbox.toggle(e.target);
}
},
'resetvalidityui.webshims': function(e){
2014-07-20 02:43:13 +02:00
var form;
if(iVal.sel && (form = $.prop(e.target, 'form')) && $.find.matchesSelector(form, iVal.sel)){
webshims.errorbox.reset(e.target);
}
},
firstinvalid: function(e){
2014-07-20 02:43:13 +02:00
var form;
if(iVal.sel && iVal.handleBubble){
2014-07-20 02:43:13 +02:00
if(iVal.sel && (form = $.prop(e.target, 'form')) && $.find.matchesSelector(form, iVal.sel)){
e.preventDefault();
if(iVal.handleBubble != 'none'){
webshims.validityAlert.showFor( e.target, false, false, iVal.handleBubble == 'hide' );
}
}
}
},
submit: function(e){
2014-07-20 02:43:13 +02:00
if(iVal.sel && iVal.submitCheck && $.find.matchesSelector(e.target, iVal.sel) && $.prop(e.target, 'noValidate') && !$(e.target).checkValidity()){
e.stopImmediatePropagation();
return false;
}
}
})
;
if(/[\s\:\>\~\+]/.test(iVal.sel || '')){
webshims.error('please use a simple selector for iVal.sel: for example .validate');
}
if(options.replaceValidationUI){
$(document).on('firstinvalid', function(e){
if(!e.isDefaultPrevented()){
e.preventDefault();
setTimeout(function(){
webshims.validityAlert.showFor( e.target );
}, 4);
}
});
}
/* extension, but also used to fix native implementation workaround/bugfixes */
(function(){
var firstEvent,
invalids = [],
stopSubmitTimer,
stop
;
$(document).on('invalid', function(e){
if(e.wrongWebkitInvalid || stop){return;}
var jElm = $(e.target);
if(!firstEvent){
//trigger firstinvalid
firstEvent = $.Event('firstinvalid');
jElm.addClass('first-invalid').trigger(firstEvent);
}
//if firstinvalid was prevented all invalids will be also prevented
if( firstEvent && firstEvent.isDefaultPrevented() ){
e.preventDefault();
}
invalids.push(e.target);
e.extraData = 'fix';
clearTimeout(stopSubmitTimer);
stopSubmitTimer = setTimeout(function(){
var lastEvent = {type: 'lastinvalid', cancelable: false, invalidlist: $(invalids)};
//reset firstinvalid
invalids = [];
stop = true;
$(e.target).trigger(lastEvent, [lastEvent]);
$(firstEvent.target).removeClass('first-invalid');
firstEvent = false;
/*
if(hasNative && !$.nodeName(e.target, 'form')){
$(e.target).jProp('form').triggerHandler('invalid');
}
*/
stop = false;
}, 9);
jElm = null;
});
})();
function getFileNames(file){
return file.name;
}
function customFile(){
if($.data(this, 'wsCustomFile')){return;}
var map = Array.prototype.map;
var $module = $(this);
var $file = $('input[type="file"]', $module);
var $valueDisplay = $('.ws-file-value', $module);
var emptyHtml = $.trim($valueDisplay.html()) || '&#160;';
var showSelected = function(){
var files = $file.prop('files') || [];
var names = map.call(files, getFileNames).join(', ') || $file.val();
if(names){
$valueDisplay.text(names);
} else {
$valueDisplay.html(emptyHtml);
}
};
$.data(this, 'wsCustomFile', {showSelected: showSelected});
$('button', $module).attr('tabindex', '-1');
$file
.on('change.webshim', showSelected)
.each(showSelected)
.jProp('form')
.on('reset', function(){
setTimeout(showSelected);
})
;
if(isIE){
$('<div class="ws-coverfile" />')
.insertAfter($file)
.on('click.webshim', function(e){
e.stopImmediatePropagation();
$file.trigger('click');
})
;
}
}
webshims.addReady(function(context, contextElem){
$(context.querySelectorAll('.ws-custom-file')).add($(contextElem).filter('.ws-custom-file')).each(customFile);
});
addModule('form-fixrangechange', {
test: !(!$.event.special.change && !$.event.special.input && support.inputtypes.range && options.fixRangeChange)
});
addModule('form-inputmode', {
test: !(!options.noInputmodeFix && document.addEventListener && support.inputtypes.number && ua.indexOf('Mobile') != -1 && !('inputMode' in document.createElement('input') && !('inputmode' in document.createElement('input'))) )
});
addModule('form-combat', {
d: ['dom-support'],
test: !(($.mobile && ($.mobile.selectmenu || $.mobile.checkboxradio)) || ($.ui && $.ui.selectmenu) || $.fn.select2 || $.fn.chosen || $.fn.selectpicker || $.fn.selectBoxIt)
});
addModule('position', {
src: 'plugins/jquery.ui.position.js',
test: !!($.position && $.position.getScrollInfo)
});
loader.loadList(['form-combat', 'position', 'form-fixrangechange', 'form-inputmode']);
});