mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-02 04:37:42 +08:00
Fix #17147: Fix form attribute validations for empty select inputs
This commit is contained in:
committed by
GitHub
parent
1ade4993f9
commit
cf364f5e00
@ -4,6 +4,7 @@ Yii Framework 2 Change Log
|
|||||||
2.0.37 under development
|
2.0.37 under development
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
|
- Bug #17147: Fix form attribute validations for empty select inputs (kartik-v)
|
||||||
- Bug #18171: Change case of column names in SQL query for `findConstraints` to fix MySQL 8 compatibility (darkdef)
|
- Bug #18171: Change case of column names in SQL query for `findConstraints` to fix MySQL 8 compatibility (darkdef)
|
||||||
- Bug #18170: Fix 2.0.36 regression in passing extra console command arguments to the action (darkdef)
|
- Bug #18170: Fix 2.0.36 regression in passing extra console command arguments to the action (darkdef)
|
||||||
- Bug #18182: `yii\db\Expression` was not supported as condition in `ActiveRecord::findOne()` and `ActiveRecord::findAll()` (rhertogh)
|
- Bug #18182: `yii\db\Expression` was not supported as condition in `ActiveRecord::findOne()` and `ActiveRecord::findAll()` (rhertogh)
|
||||||
|
|||||||
@ -14,11 +14,13 @@
|
|||||||
$.fn.yiiActiveForm = function (method) {
|
$.fn.yiiActiveForm = function (method) {
|
||||||
if (methods[method]) {
|
if (methods[method]) {
|
||||||
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
|
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
|
||||||
} else if (typeof method === 'object' || !method) {
|
|
||||||
return methods.init.apply(this, arguments);
|
|
||||||
} else {
|
} else {
|
||||||
$.error('Method ' + method + ' does not exist on jQuery.yiiActiveForm');
|
if (typeof method === 'object' || !method) {
|
||||||
return false;
|
return methods.init.apply(this, arguments);
|
||||||
|
} else {
|
||||||
|
$.error('Method ' + method + ' does not exist on jQuery.yiiActiveForm');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -178,14 +180,14 @@
|
|||||||
|
|
||||||
var submitDefer;
|
var submitDefer;
|
||||||
|
|
||||||
var setSubmitFinalizeDefer = function($form) {
|
var setSubmitFinalizeDefer = function ($form) {
|
||||||
submitDefer = $.Deferred();
|
submitDefer = $.Deferred();
|
||||||
$form.data('yiiSubmitFinalizePromise', submitDefer.promise());
|
$form.data('yiiSubmitFinalizePromise', submitDefer.promise());
|
||||||
};
|
};
|
||||||
|
|
||||||
// finalize yii.js $form.submit
|
// finalize yii.js $form.submit
|
||||||
var submitFinalize = function($form) {
|
var submitFinalize = function ($form) {
|
||||||
if(submitDefer) {
|
if (submitDefer) {
|
||||||
submitDefer.resolve();
|
submitDefer.resolve();
|
||||||
submitDefer = undefined;
|
submitDefer = undefined;
|
||||||
$form.removeData('yiiSubmitFinalizePromise');
|
$form.removeData('yiiSubmitFinalizePromise');
|
||||||
@ -327,15 +329,22 @@
|
|||||||
this.$form = $form;
|
this.$form = $form;
|
||||||
var $input = findInput($form, this);
|
var $input = findInput($form, this);
|
||||||
|
|
||||||
if ($input.is(":disabled")) {
|
if ($input.is(':disabled')) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// pass SELECT without options
|
// validate markup for select input
|
||||||
if ($input.length && $input[0].tagName.toLowerCase() === 'select') {
|
if ($input.length && $input[0].tagName.toLowerCase() === 'select') {
|
||||||
if (!$input[0].options.length) {
|
var opts = $input[0].options, isEmpty = !opts || !opts.length, isRequired = $input.attr('required'),
|
||||||
return true;
|
isMultiple = $input.attr('multiple'), size = $input.attr('size') || 1;
|
||||||
} else if (($input[0].options.length === 1) && ($input[0].options[0].value === '')) {
|
// check if valid HTML markup for select input, else return validation as `true`
|
||||||
return true;
|
// https://w3c.github.io/html-reference/select.html
|
||||||
|
if (isRequired && !isMultiple && parseInt(size, 10) === 1) { // invalid select markup condition
|
||||||
|
if (isEmpty) { // empty option elements for the select
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (opts[0] && (opts[0].value !== '' && opts[0].text !== '')) { // first option is not empty
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.cancelled = false;
|
this.cancelled = false;
|
||||||
@ -363,7 +372,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
// ajax validation
|
// ajax validation
|
||||||
$.when.apply(this, deferreds).always(function() {
|
$.when.apply(this, deferreds).always(function () {
|
||||||
// Remove empty message arrays
|
// Remove empty message arrays
|
||||||
for (var i in messages) {
|
for (var i in messages) {
|
||||||
if (0 === messages[i].length) {
|
if (0 === messages[i].length) {
|
||||||
@ -404,13 +413,15 @@
|
|||||||
submitFinalize($form);
|
submitFinalize($form);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (data.submitting) {
|
|
||||||
// delay callback so that the form can be submitted without problem
|
|
||||||
window.setTimeout(function () {
|
|
||||||
updateInputs($form, messages, submitting);
|
|
||||||
}, 200);
|
|
||||||
} else {
|
} else {
|
||||||
updateInputs($form, messages, submitting);
|
if (data.submitting) {
|
||||||
|
// delay callback so that the form can be submitted without problem
|
||||||
|
window.setTimeout(function () {
|
||||||
|
updateInputs($form, messages, submitting);
|
||||||
|
}, 200);
|
||||||
|
} else {
|
||||||
|
updateInputs($form, messages, submitting);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -459,9 +470,9 @@
|
|||||||
$errorElement = data.settings.validationStateOn === 'input' ? $input : $container;
|
$errorElement = data.settings.validationStateOn === 'input' ? $input : $container;
|
||||||
|
|
||||||
$errorElement.removeClass(
|
$errorElement.removeClass(
|
||||||
data.settings.validatingCssClass + ' ' +
|
data.settings.validatingCssClass + ' ' +
|
||||||
data.settings.errorCssClass + ' ' +
|
data.settings.errorCssClass + ' ' +
|
||||||
data.settings.successCssClass
|
data.settings.successCssClass
|
||||||
);
|
);
|
||||||
$container.find(this.error).html('');
|
$container.find(this.error).html('');
|
||||||
});
|
});
|
||||||
@ -492,7 +503,7 @@
|
|||||||
* @param id attribute ID
|
* @param id attribute ID
|
||||||
* @param messages array with error messages
|
* @param messages array with error messages
|
||||||
*/
|
*/
|
||||||
updateAttribute: function(id, messages) {
|
updateAttribute: function (id, messages) {
|
||||||
var attribute = methods.find.call(this, id);
|
var attribute = methods.find.call(this, id);
|
||||||
if (attribute != undefined) {
|
if (attribute != undefined) {
|
||||||
var msg = {};
|
var msg = {};
|
||||||
@ -518,7 +529,7 @@
|
|||||||
}
|
}
|
||||||
if (attribute.validateOnType) {
|
if (attribute.validateOnType) {
|
||||||
$input.on('keyup.yiiActiveForm', function (e) {
|
$input.on('keyup.yiiActiveForm', function (e) {
|
||||||
if ($.inArray(e.which, [16, 17, 18, 37, 38, 39, 40]) !== -1 ) {
|
if ($.inArray(e.which, [16, 17, 18, 37, 38, 39, 40]) !== -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (attribute.value !== getValue($form, attribute)) {
|
if (attribute.value !== getValue($form, attribute)) {
|
||||||
@ -571,7 +582,7 @@
|
|||||||
* @param val2
|
* @param val2
|
||||||
* @returns boolean
|
* @returns boolean
|
||||||
*/
|
*/
|
||||||
var isEqual = function(val1, val2) {
|
var isEqual = function (val1, val2) {
|
||||||
// objects
|
// objects
|
||||||
if (val1 instanceof Object) {
|
if (val1 instanceof Object) {
|
||||||
return isObjectsEqual(val1, val2)
|
return isObjectsEqual(val1, val2)
|
||||||
@ -592,7 +603,7 @@
|
|||||||
* @param obj2
|
* @param obj2
|
||||||
* @returns boolean
|
* @returns boolean
|
||||||
*/
|
*/
|
||||||
var isObjectsEqual = function(obj1, obj2) {
|
var isObjectsEqual = function (obj1, obj2) {
|
||||||
if (!(obj1 instanceof Object) || !(obj2 instanceof Object)) {
|
if (!(obj1 instanceof Object) || !(obj2 instanceof Object)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -621,7 +632,7 @@
|
|||||||
* @param arr2
|
* @param arr2
|
||||||
* @returns boolean
|
* @returns boolean
|
||||||
*/
|
*/
|
||||||
var isArraysEqual = function(arr1, arr2) {
|
var isArraysEqual = function (arr1, arr2) {
|
||||||
if (!Array.isArray(arr1) || !Array.isArray(arr2)) {
|
if (!Array.isArray(arr1) || !Array.isArray(arr2)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -644,7 +655,7 @@
|
|||||||
*/
|
*/
|
||||||
var deferredArray = function () {
|
var deferredArray = function () {
|
||||||
var array = [];
|
var array = [];
|
||||||
array.add = function(callback) {
|
array.add = function (callback) {
|
||||||
this.push(new $.Deferred(callback));
|
this.push(new $.Deferred(callback));
|
||||||
};
|
};
|
||||||
return array;
|
return array;
|
||||||
@ -707,10 +718,11 @@
|
|||||||
|
|
||||||
var errorAttributes = [], $input;
|
var errorAttributes = [], $input;
|
||||||
$.each(data.attributes, function () {
|
$.each(data.attributes, function () {
|
||||||
var hasError = (submitting && updateInput($form, this, messages)) || (!submitting && attrHasError($form, this, messages));
|
var hasError = (submitting && updateInput($form, this, messages)) || (!submitting && attrHasError($form,
|
||||||
|
this, messages));
|
||||||
$input = findInput($form, this);
|
$input = findInput($form, this);
|
||||||
|
|
||||||
if (!$input.is(":disabled") && !this.cancelled && hasError) {
|
if (!$input.is(':disabled') && !this.cancelled && hasError) {
|
||||||
errorAttributes.push(this);
|
errorAttributes.push(this);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -721,14 +733,10 @@
|
|||||||
updateSummary($form, messages);
|
updateSummary($form, messages);
|
||||||
if (errorAttributes.length) {
|
if (errorAttributes.length) {
|
||||||
if (data.settings.scrollToError) {
|
if (data.settings.scrollToError) {
|
||||||
var top = $form.find($.map(errorAttributes, function(attribute) {
|
var h = $(document).height(), top = $form.find($.map(errorAttributes, function (attribute) {
|
||||||
return attribute.input;
|
return attribute.input;
|
||||||
}).join(',')).first().closest(':visible').offset().top - data.settings.scrollToErrorOffset;
|
}).join(',')).first().closest(':visible').offset().top - data.settings.scrollToErrorOffset;
|
||||||
if (top < 0) {
|
top = top < 0 ? 0 : (top > h ? h : top);
|
||||||
top = 0;
|
|
||||||
} else if (top > $(document).height()) {
|
|
||||||
top = $(document).height();
|
|
||||||
}
|
|
||||||
var wtop = $(window).scrollTop();
|
var wtop = $(window).scrollTop();
|
||||||
if (top < wtop || top > wtop + $(window).height()) {
|
if (top < wtop || top > wtop + $(window).height()) {
|
||||||
$(window).scrollTop(top);
|
$(window).scrollTop(top);
|
||||||
@ -809,11 +817,11 @@
|
|||||||
$error.html(messages[attribute.id][0]);
|
$error.html(messages[attribute.id][0]);
|
||||||
}
|
}
|
||||||
$errorElement.removeClass(data.settings.validatingCssClass + ' ' + data.settings.successCssClass)
|
$errorElement.removeClass(data.settings.validatingCssClass + ' ' + data.settings.successCssClass)
|
||||||
.addClass(data.settings.errorCssClass);
|
.addClass(data.settings.errorCssClass);
|
||||||
} else {
|
} else {
|
||||||
$error.empty();
|
$error.empty();
|
||||||
$errorElement.removeClass(data.settings.validatingCssClass + ' ' + data.settings.errorCssClass + ' ')
|
$errorElement.removeClass(data.settings.validatingCssClass + ' ' + data.settings.errorCssClass + ' ')
|
||||||
.addClass(data.settings.successCssClass);
|
.addClass(data.settings.successCssClass);
|
||||||
}
|
}
|
||||||
attribute.value = getValue($form, attribute);
|
attribute.value = getValue($form, attribute);
|
||||||
}
|
}
|
||||||
@ -878,7 +886,7 @@
|
|||||||
var $realInput = $input.filter(':checked');
|
var $realInput = $input.filter(':checked');
|
||||||
if ($realInput.length > 1) {
|
if ($realInput.length > 1) {
|
||||||
var values = [];
|
var values = [];
|
||||||
$realInput.each(function(index) {
|
$realInput.each(function (index) {
|
||||||
values.push($($realInput.get(index)).val());
|
values.push($($realInput.get(index)).val());
|
||||||
});
|
});
|
||||||
return values;
|
return values;
|
||||||
@ -909,4 +917,4 @@
|
|||||||
$form.find(attribute.input).attr('aria-invalid', hasError ? 'true' : 'false');
|
$form.find(attribute.input).attr('aria-invalid', hasError ? 'true' : 'false');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})(window.jQuery);
|
})(window.jQuery);
|
||||||
Reference in New Issue
Block a user