mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-01 11:39:41 +08:00
Fixes #4955: Replaced callbacks with events for ActiveForm
This commit is contained in:
@ -258,6 +258,9 @@ Yii Framework 2 Change Log
|
||||
- Chg #4591: `yii\helpers\Url::to()` will no longer prefix relative URLs with the base URL (qiangxue)
|
||||
- Chg #4595: `yii\widgets\LinkPager`'s `nextPageLabel`, `prevPageLabel`, `firstPageLabel`, `lastPageLabel` are now taking `false` instead of `null` for "no label" (samdark)
|
||||
- Chg #4911: Changed callback signature used in `yii\base\ArrayableTrait::fields()` from `function ($field, $model) {` to `function ($model, $field) {` (samdark)
|
||||
- Chg #4955: Replaced callbacks with events for `ActiveForm` (qiangxue)
|
||||
- Removed `beforeValidate()`, `beforeValidateAll()`, `afterValidate()`, `afterValidateAll()`, `ajaxBeforeSend()` and `ajaxComplete()` from `ActiveForm`.
|
||||
- Added `beforeValidate`, `afterValidate`, `beforeSubmit`, `ajaxBeforeSend` and `ajaxComplete` events to `yii.activeForm`.
|
||||
- Chg: Replaced `clearAll()` and `clearAllAssignments()` in `yii\rbac\ManagerInterface` with `removeAll()`, `removeAllRoles()`, `removeAllPermissions()`, `removeAllRules()` and `removeAllAssignments()` (qiangxue)
|
||||
- Chg: Added `$user` as the first parameter of `yii\rbac\Rule::execute()` (qiangxue)
|
||||
- Chg: `yii\grid\DataColumn::getDataCellValue()` visibility is now `public` to allow accessing the value from a GridView directly (cebe)
|
||||
|
||||
@ -213,3 +213,18 @@ new ones save the following code as `convert.php` that should be placed in the s
|
||||
* `Html::radio()`, `Html::checkbox()`, `Html::radioList()`, `Html::checkboxList()` no longer generate the container
|
||||
tag around each radio/checkbox when you specify labels for them. You should manually render such container tags,
|
||||
or set the `item` option for `Html::radioList()`, `Html::checkboxList()` to generate the container tags.
|
||||
|
||||
* `beforeValidate()`, `beforeValidateAll()`, `afterValidate()`, `afterValidateAll()`, `ajaxBeforeSend()` and `ajaxComplete()`
|
||||
are removed from `ActiveForm`. The same functionality is now achieved via JavaScript event mechanism. For example,
|
||||
if you want to do something before performing validation on the client side, you can write the following
|
||||
JavaScript code:
|
||||
|
||||
```js
|
||||
$('#myform').on('beforeValidate', function (event, messages, deferreds, attribute) {
|
||||
if (attribute === undefined) {
|
||||
// the event is triggered when submitting the form
|
||||
} elseif (attribute.id === 'something') {
|
||||
// the event is triggered before validating "something"
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
@ -22,6 +22,66 @@
|
||||
}
|
||||
};
|
||||
|
||||
var events = {
|
||||
/**
|
||||
* beforeValidate event is triggered before validating the whole form and each attribute.
|
||||
* The signature of the event handler should be:
|
||||
* function (event, messages, deferreds, attribute)
|
||||
* where
|
||||
* - event: an Event object. You can set event.isValid to be false to stop validating the form or attribute
|
||||
* - messages: error messages. When attribute is undefined, this parameter is an associative array
|
||||
* with keys being attribute IDs and values being error messages for the corresponding attributes.
|
||||
* When attribute is given, this parameter is an array of the error messages for that attribute.
|
||||
* - deferreds: an array of Deferred objects. You can use deferreds.add(callback) to add a new deferred validation.
|
||||
* - attribute: an attribute object. Please refer to attributeDefaults for the structure.
|
||||
* If this is undefined, it means the event is triggered before validating the whole form.
|
||||
* Otherwise it means the event is triggered before validating the specified attribute.
|
||||
*/
|
||||
beforeValidate: 'beforeValidate',
|
||||
/**
|
||||
* afterValidate event is triggered after validating the whole form and each attribute.
|
||||
* The signature of the event handler should be:
|
||||
* function (event, messages, attribute)
|
||||
* where
|
||||
* - event: an Event object.
|
||||
* - messages: error messages. When attribute is undefined, this parameter is an associative array
|
||||
* with keys being attribute IDs and values being error messages for the corresponding attributes.
|
||||
* When attribute is given, this parameter is an array of the error messages for that attribute.
|
||||
* If the array length is greater than 0, it means the attribute has validation errors.
|
||||
* - attribute: an attribute object. Please refer to attributeDefaults for the structure.
|
||||
* If this is undefined, it means the event is triggered before validating the whole form.
|
||||
* Otherwise it means the event is triggered before validating the specified attribute.
|
||||
*/
|
||||
afterValidate: 'afterValidate',
|
||||
/**
|
||||
* beforeSubmit event is triggered before submitting the form (after all validations pass).
|
||||
* The signature of the event handler should be:
|
||||
* function (event)
|
||||
* where event is an Event object.
|
||||
*/
|
||||
beforeSubmit: 'beforeSubmit',
|
||||
/**
|
||||
* ajaxBeforeSend event is triggered before sending an AJAX request for AJAX-based validation.
|
||||
* The signature of the event handler should be:
|
||||
* function (event, jqXHR, settings)
|
||||
* where
|
||||
* - event: an Event object.
|
||||
* - jqXHR: a jqXHR object
|
||||
* - settings: the settings for the AJAX request
|
||||
*/
|
||||
ajaxBeforeSend: 'ajaxBeforeSend',
|
||||
/**
|
||||
* ajaxComplete event is triggered after completing an AJAX request for AJAX-based validation.
|
||||
* The signature of the event handler should be:
|
||||
* function (event, jqXHR, textStatus)
|
||||
* where
|
||||
* - event: an Event object.
|
||||
* - jqXHR: a jqXHR object
|
||||
* - settings: the status of the request ("success", "notmodified", "error", "timeout", "abort", or "parsererror").
|
||||
*/
|
||||
ajaxComplete: 'ajaxComplete'
|
||||
};
|
||||
|
||||
// NOTE: If you change any of these defaults, make sure you update yii\widgets\ActiveForm::getClientOptions() as well
|
||||
var defaults = {
|
||||
// whether to encode the error summary
|
||||
@ -41,28 +101,7 @@
|
||||
// the type of data that you're expecting back from the server
|
||||
ajaxDataType: 'json',
|
||||
// the URL for performing AJAX-based validation. If not set, it will use the the form's action
|
||||
validationUrl: undefined,
|
||||
// a callback that is called before submitting the form. The signature of the callback should be:
|
||||
// function ($form) { ...return false to cancel submission...}
|
||||
beforeSubmit: undefined,
|
||||
// a callback that is called before validating each attribute. The signature of the callback should be:
|
||||
// function ($form, attribute, messages) { ...return false to cancel the validation...}
|
||||
beforeValidate: undefined,
|
||||
// a callback that is called before validation starts (This callback is only called when the form is submitted). This signature of the callback should be:
|
||||
// function($form, data) { ...return false to cancel the validation...}
|
||||
beforeValidateAll: undefined,
|
||||
// a callback that is called after an attribute is validated. The signature of the callback should be:
|
||||
// function ($form, attribute, messages)
|
||||
afterValidate: undefined,
|
||||
// a callback that is called after all validation has run (This callback is only called when the form is submitted). The signature of the callback should be:
|
||||
// function ($form, data, messages)
|
||||
afterValidateAll: undefined,
|
||||
// a pre-request callback function on AJAX-based validation. The signature of the callback should be:
|
||||
// function ($form, jqXHR, textStatus)
|
||||
ajaxBeforeSend: undefined,
|
||||
// a function to be called when the request finishes on AJAX-based validation. The signature of the callback should be:
|
||||
// function ($form, jqXHR, textStatus)
|
||||
ajaxComplete: undefined
|
||||
validationUrl: undefined
|
||||
};
|
||||
|
||||
// NOTE: If you change any of these defaults, make sure you update yii\widgets\ActiveField::getClientOptions() as well
|
||||
@ -151,7 +190,7 @@
|
||||
var $form = $(this),
|
||||
attributes = $form.data('yiiActiveForm').attributes,
|
||||
index = -1,
|
||||
attribute;
|
||||
attribute = undefined;
|
||||
$.each(attributes, function (i) {
|
||||
if (attributes[i]['id'] == id) {
|
||||
index = i;
|
||||
@ -168,7 +207,8 @@
|
||||
|
||||
// find an attribute config based on the specified attribute ID
|
||||
find: function (id) {
|
||||
var attributes = $(this).data('yiiActiveForm').attributes, result;
|
||||
var attributes = $(this).data('yiiActiveForm').attributes,
|
||||
result = undefined;
|
||||
$.each(attributes, function (i) {
|
||||
if (attributes[i]['id'] == id) {
|
||||
result = attributes[i];
|
||||
@ -189,66 +229,120 @@
|
||||
return this.data('yiiActiveForm');
|
||||
},
|
||||
|
||||
validate: function () {
|
||||
var $form = $(this),
|
||||
data = $form.data('yiiActiveForm'),
|
||||
needAjaxValidation = false,
|
||||
messages = {},
|
||||
deferreds = deferredArray();
|
||||
|
||||
if (data.submitting) {
|
||||
var event = $.Event(events.beforeValidate, {'isValid': true});
|
||||
$form.trigger(event, [messages, deferreds]);
|
||||
if (!event.isValid) {
|
||||
data.submitting = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// client-side validation
|
||||
$.each(data.attributes, function () {
|
||||
// perform validation only if the form is being submitted or if an attribute is pending validation
|
||||
if (data.submitting || this.status === 2 || this.status === 3) {
|
||||
var msg = messages[this.id];
|
||||
if (msg === undefined) {
|
||||
msg = [];
|
||||
messages[this.id] = msg;
|
||||
}
|
||||
var event = $.Event(events.beforeValidate, {'isValid': true});
|
||||
$form.trigger(event, [msg, deferreds, this]);
|
||||
if (event.isValid) {
|
||||
if (this.validate) {
|
||||
this.validate(this, getValue($form, this), msg, deferreds);
|
||||
}
|
||||
if (this.enableAjaxValidation) {
|
||||
needAjaxValidation = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// ajax validation
|
||||
$.when.apply(this, deferreds).always(function() {
|
||||
// Remove empty message arrays
|
||||
for (var i in messages) {
|
||||
if (0 === messages[i].length) {
|
||||
delete messages[i];
|
||||
}
|
||||
}
|
||||
if (needAjaxValidation && (!data.submitting || $.isEmptyObject(messages))) {
|
||||
// Perform ajax validation when at least one input needs it.
|
||||
// If the validation is triggered by form submission, ajax validation
|
||||
// should be done only when all inputs pass client validation
|
||||
var $button = data.submitObject,
|
||||
extData = '&' + data.settings.ajaxParam + '=' + $form.prop('id');
|
||||
if ($button && $button.length && $button.prop('name')) {
|
||||
extData += '&' + $button.prop('name') + '=' + $button.prop('value');
|
||||
}
|
||||
$.ajax({
|
||||
url: data.settings.validationUrl,
|
||||
type: $form.prop('method'),
|
||||
data: $form.serialize() + extData,
|
||||
dataType: data.settings.ajaxDataType,
|
||||
complete: function (jqXHR, textStatus) {
|
||||
$form.trigger(events.ajaxComplete, [jqXHR, textStatus]);
|
||||
},
|
||||
beforeSend: function (jqXHR, settings) {
|
||||
$form.trigger(events.ajaxBeforeSend, [jqXHR, settings]);
|
||||
},
|
||||
success: function (msgs) {
|
||||
if (msgs !== null && typeof msgs === 'object') {
|
||||
$.each(data.attributes, function () {
|
||||
if (!this.enableAjaxValidation) {
|
||||
delete msgs[this.id];
|
||||
}
|
||||
});
|
||||
updateInputs($form, $.extend(messages, msgs));
|
||||
} else {
|
||||
updateInputs($form, messages);
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
data.submitting = false;
|
||||
}
|
||||
});
|
||||
} else if (data.submitting) {
|
||||
// delay callback so that the form can be submitted without problem
|
||||
setTimeout(function () {
|
||||
updateInputs($form, messages);
|
||||
}, 200);
|
||||
} else {
|
||||
updateInputs($form, messages);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
submitForm: function () {
|
||||
var $form = $(this),
|
||||
data = $form.data('yiiActiveForm');
|
||||
if (data.validated) {
|
||||
if (data.settings.beforeSubmit !== undefined) {
|
||||
if (data.settings.beforeSubmit($form) == false) {
|
||||
data.validated = false;
|
||||
data.submitting = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// continue submitting the form since validation passes
|
||||
return true;
|
||||
}
|
||||
|
||||
if (data.settings.timer !== undefined) {
|
||||
clearTimeout(data.settings.timer);
|
||||
}
|
||||
data.submitting = true;
|
||||
|
||||
if (data.settings.beforeValidateAll && !data.settings.beforeValidateAll($form, data)) {
|
||||
data.submitting = false;
|
||||
if (data.validated) {
|
||||
var event = $.Event(events.beforeSubmit, {'isValid': true});
|
||||
$form.trigger(event, [$form]);
|
||||
if (!event.isValid) {
|
||||
data.validated = false;
|
||||
data.submitting = false;
|
||||
return false;
|
||||
}
|
||||
return true; // continue submitting the form since validation passes
|
||||
} else {
|
||||
if (data.settings.timer !== undefined) {
|
||||
clearTimeout(data.settings.timer);
|
||||
}
|
||||
data.submitting = true;
|
||||
methods.validate.call($form);
|
||||
return false;
|
||||
}
|
||||
validate($form, function (messages) {
|
||||
var errors = [];
|
||||
$.each(data.attributes, function () {
|
||||
if (updateInput($form, this, messages)) {
|
||||
errors.push(this.input);
|
||||
}
|
||||
});
|
||||
|
||||
if (data.settings.afterValidateAll) {
|
||||
data.settings.afterValidateAll($form, data, messages);
|
||||
}
|
||||
|
||||
updateSummary($form, messages);
|
||||
if (errors.length) {
|
||||
var top = $form.find(errors.join(',')).first().offset().top;
|
||||
var wtop = $(window).scrollTop();
|
||||
if (top < wtop || top > wtop + $(window).height) {
|
||||
$(window).scrollTop(top);
|
||||
}
|
||||
} else {
|
||||
data.validated = true;
|
||||
var $button = data.submitObject || $form.find(':submit:first');
|
||||
// TODO: if the submission is caused by "change" event, it will not work
|
||||
if ($button.length) {
|
||||
$button.click();
|
||||
} else {
|
||||
// no submit button in the form
|
||||
$form.submit();
|
||||
}
|
||||
return;
|
||||
}
|
||||
data.submitting = false;
|
||||
}, function () {
|
||||
data.submitting = false;
|
||||
});
|
||||
return false;
|
||||
},
|
||||
|
||||
resetForm: function () {
|
||||
@ -275,31 +369,6 @@
|
||||
}
|
||||
};
|
||||
|
||||
var watchAttributes = function ($form, attributes) {
|
||||
$.each(attributes, function (i, attribute) {
|
||||
var $input = findInput($form, attribute);
|
||||
if (attribute.validateOnChange) {
|
||||
$input.on('change.yiiActiveForm',function () {
|
||||
validateAttribute($form, attribute, false);
|
||||
});
|
||||
}
|
||||
if (attribute.validateOnBlur) {
|
||||
$input.on('blur.yiiActiveForm', function () {
|
||||
if (attribute.status == 0 || attribute.status == 1) {
|
||||
validateAttribute($form, attribute, !attribute.status);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (attribute.validateOnType) {
|
||||
$input.on('keyup.yiiActiveForm', function () {
|
||||
if (attribute.value !== getValue($form, attribute)) {
|
||||
validateAttribute($form, attribute, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var watchAttribute = function ($form, attribute) {
|
||||
var $input = findInput($form, attribute);
|
||||
if (attribute.validateOnChange) {
|
||||
@ -356,14 +425,7 @@
|
||||
$form.find(this.container).addClass(data.settings.validatingCssClass);
|
||||
}
|
||||
});
|
||||
validate($form, function (messages) {
|
||||
var hasError = false;
|
||||
$.each(data.attributes, function () {
|
||||
if (this.status === 2 || this.status === 3) {
|
||||
hasError = updateInput($form, this, messages) || hasError;
|
||||
}
|
||||
});
|
||||
});
|
||||
methods.validate.call($form);
|
||||
}, data.settings.validationDelay);
|
||||
};
|
||||
|
||||
@ -379,88 +441,52 @@
|
||||
};
|
||||
return array;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Performs validation.
|
||||
* @param $form jQuery the jquery representation of the form
|
||||
* @param successCallback function the function to be invoked if the validation completes
|
||||
* @param errorCallback function the function to be invoked if the ajax validation request fails
|
||||
* Updates the error messages and the input containers for all applicable attributes
|
||||
* @param $form the form jQuery object
|
||||
* @param messages array the validation error messages
|
||||
*/
|
||||
var validate = function ($form, successCallback, errorCallback) {
|
||||
var data = $form.data('yiiActiveForm'),
|
||||
needAjaxValidation = false,
|
||||
messages = {},
|
||||
deferreds = deferredArray();
|
||||
var updateInputs = function ($form, messages) {
|
||||
var data = $form.data('yiiActiveForm');
|
||||
|
||||
$.each(data.attributes, function () {
|
||||
if (data.submitting || this.status === 2 || this.status === 3) {
|
||||
var msg = [];
|
||||
messages[this.id] = msg;
|
||||
if (!data.settings.beforeValidate || data.settings.beforeValidate($form, this, msg)) {
|
||||
if (this.validate) {
|
||||
this.validate(this, getValue($form, this), msg, deferreds);
|
||||
}
|
||||
if (this.enableAjaxValidation) {
|
||||
needAjaxValidation = true;
|
||||
}
|
||||
if (data.submitting) {
|
||||
var errorInputs = [];
|
||||
$.each(data.attributes, function () {
|
||||
if (updateInput($form, this, messages)) {
|
||||
errorInputs.push(this.input);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$.when.apply(this, deferreds).always(function() {
|
||||
//Remove empty message arrays
|
||||
for (var i in messages) {
|
||||
if (0 === messages[i].length) {
|
||||
delete messages[i];
|
||||
$form.trigger(events.afterValidate, [messages]);
|
||||
|
||||
updateSummary($form, messages);
|
||||
|
||||
if (errorInputs.length) {
|
||||
var top = $form.find(errorInputs.join(',')).first().offset().top;
|
||||
var wtop = $(window).scrollTop();
|
||||
if (top < wtop || top > wtop + $(window).height) {
|
||||
$(window).scrollTop(top);
|
||||
}
|
||||
}
|
||||
if (needAjaxValidation && (!data.submitting || $.isEmptyObject(messages))) {
|
||||
// Perform ajax validation when at least one input needs it.
|
||||
// If the validation is triggered by form submission, ajax validation
|
||||
// should be done only when all inputs pass client validation
|
||||
var $button = data.submitObject,
|
||||
extData = '&' + data.settings.ajaxParam + '=' + $form.prop('id');
|
||||
if ($button && $button.length && $button.prop('name')) {
|
||||
extData += '&' + $button.prop('name') + '=' + $button.prop('value');
|
||||
}
|
||||
$.ajax({
|
||||
url: data.settings.validationUrl,
|
||||
type: $form.prop('method'),
|
||||
data: $form.serialize() + extData,
|
||||
dataType: data.settings.ajaxDataType,
|
||||
complete: function (jqXHR, textStatus) {
|
||||
if (data.settings.ajaxComplete) {
|
||||
data.settings.ajaxComplete($form, jqXHR, textStatus);
|
||||
}
|
||||
},
|
||||
beforeSend: function (jqXHR, textStatus) {
|
||||
if (data.settings.ajaxBeforeSend) {
|
||||
data.settings.ajaxBeforeSend($form, jqXHR, textStatus);
|
||||
}
|
||||
},
|
||||
success: function (msgs) {
|
||||
if (msgs !== null && typeof msgs === 'object') {
|
||||
$.each(data.attributes, function () {
|
||||
if (!this.enableAjaxValidation) {
|
||||
delete msgs[this.id];
|
||||
}
|
||||
});
|
||||
successCallback($.extend({}, messages, msgs));
|
||||
} else {
|
||||
successCallback(messages);
|
||||
}
|
||||
},
|
||||
error: errorCallback
|
||||
});
|
||||
} else if (data.submitting) {
|
||||
// delay callback so that the form can be submitted without problem
|
||||
setTimeout(function () {
|
||||
successCallback(messages);
|
||||
}, 200);
|
||||
data.submitting = false;
|
||||
} else {
|
||||
successCallback(messages);
|
||||
data.validated = true;
|
||||
var $button = data.submitObject || $form.find(':submit:first');
|
||||
// TODO: if the submission is caused by "change" event, it will not work
|
||||
if ($button.length) {
|
||||
$button.click();
|
||||
} else {
|
||||
// no submit button in the form
|
||||
$form.submit();
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$.each(data.attributes, function () {
|
||||
if (this.status === 2 || this.status === 3) {
|
||||
updateInput($form, this, messages);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -475,12 +501,14 @@
|
||||
$input = findInput($form, attribute),
|
||||
hasError = false;
|
||||
|
||||
if (data.settings.afterValidate) {
|
||||
data.settings.afterValidate($form, attribute, messages);
|
||||
if (!$.isArray(messages[attribute.id])) {
|
||||
messages[attribute.id] = [];
|
||||
}
|
||||
$form.trigger(events.afterValidate, [messages[attribute.id], attribute]);
|
||||
|
||||
attribute.status = 1;
|
||||
if ($input.length) {
|
||||
hasError = messages && $.isArray(messages[attribute.id]) && messages[attribute.id].length;
|
||||
hasError = messages[attribute.id].length > 0;
|
||||
var $container = $form.find(attribute.container);
|
||||
var $error = $container.find(attribute.error);
|
||||
if (hasError) {
|
||||
|
||||
@ -15,7 +15,6 @@ use yii\helpers\ArrayHelper;
|
||||
use yii\helpers\Url;
|
||||
use yii\helpers\Html;
|
||||
use yii\helpers\Json;
|
||||
use yii\web\JsExpression;
|
||||
|
||||
/**
|
||||
* ActiveForm is a widget that builds an interactive HTML form for one or multiple data models.
|
||||
@ -145,79 +144,6 @@ class ActiveForm extends Widget
|
||||
* @var string the type of data that you're expecting back from the server.
|
||||
*/
|
||||
public $ajaxDataType = 'json';
|
||||
/**
|
||||
* @var string|JsExpression a JS callback that will be called when the form is being submitted.
|
||||
* The signature of the callback should be:
|
||||
*
|
||||
* ~~~
|
||||
* function ($form) {
|
||||
* ...return false to cancel submission...
|
||||
* }
|
||||
* ~~~
|
||||
*/
|
||||
public $beforeSubmit;
|
||||
/**
|
||||
* @var string|JsExpression a JS callback that is called before validating an attribute.
|
||||
* The signature of the callback should be:
|
||||
*
|
||||
* ~~~
|
||||
* function ($form, attribute, messages) {
|
||||
* ...return false to cancel the validation...
|
||||
* }
|
||||
* ~~~
|
||||
*/
|
||||
public $beforeValidate;
|
||||
/**
|
||||
* @var string|JsExpression a JS callback that is called before any validation has run (Only called when the form is submitted).
|
||||
* The signature of the callback should be:
|
||||
*
|
||||
* ~~~
|
||||
* function ($form, data) {
|
||||
* ...return false to cancel the validation...
|
||||
* }
|
||||
* ~~~
|
||||
*/
|
||||
public $beforeValidateAll;
|
||||
/**
|
||||
* @var string|JsExpression a JS callback that is called after validating an attribute.
|
||||
* The signature of the callback should be:
|
||||
*
|
||||
* ~~~
|
||||
* function ($form, attribute, messages) {
|
||||
* }
|
||||
* ~~~
|
||||
*/
|
||||
public $afterValidate;
|
||||
/**
|
||||
* @var string|JsExpression a JS callback that is called after all validation has run (Only called when the form is submitted).
|
||||
* The signature of the callback should be:
|
||||
*
|
||||
* ~~~
|
||||
* function ($form, data, messages) {
|
||||
* }
|
||||
* ~~~
|
||||
*/
|
||||
public $afterValidateAll;
|
||||
/**
|
||||
* @var string|JsExpression a JS pre-request callback function on AJAX-based validation.
|
||||
* The signature of the callback should be:
|
||||
*
|
||||
* ~~~
|
||||
* function ($form, jqXHR, textStatus) {
|
||||
* }
|
||||
* ~~~
|
||||
*/
|
||||
public $ajaxBeforeSend;
|
||||
/**
|
||||
* @var string|JsExpression a JS callback to be called when the request finishes on AJAX-based validation.
|
||||
* The signature of the callback should be:
|
||||
*
|
||||
* ~~~
|
||||
* function ($form, jqXHR, textStatus) {
|
||||
* }
|
||||
* ~~~
|
||||
*/
|
||||
public $ajaxComplete;
|
||||
/**
|
||||
* @var array the client validation options for individual attributes. Each element of the array
|
||||
* represents the validation options for a particular attribute.
|
||||
@ -282,11 +208,6 @@ class ActiveForm extends Widget
|
||||
if ($this->validationUrl !== null) {
|
||||
$options['validationUrl'] = Url::to($this->validationUrl);
|
||||
}
|
||||
foreach (['beforeSubmit', 'beforeValidate', 'beforeValidateAll', 'afterValidate', 'afterValidateAll', 'ajaxBeforeSend', 'ajaxComplete'] as $name) {
|
||||
if (($value = $this->$name) !== null) {
|
||||
$options[$name] = $value instanceof JsExpression ? $value : new JsExpression($value);
|
||||
}
|
||||
}
|
||||
|
||||
// only get the options that are different from the default ones (set in yii.activeForm.js)
|
||||
return array_diff_assoc($options, [
|
||||
|
||||
@ -140,7 +140,7 @@ class HtmlTest extends TestCase
|
||||
|
||||
public function testButton()
|
||||
{
|
||||
$this->assertEquals('<button>Button</button>', Html::button());
|
||||
$this->assertEquals('<button type="button">Button</button>', Html::button());
|
||||
$this->assertEquals('<button name="test" value="value">content<></button>', Html::button('content<>', ['name' => 'test', 'value' => 'value']));
|
||||
$this->assertEquals('<button type="submit" class="t" name="test" value="value">content<></button>', Html::button('content<>', ['type' => 'submit', 'name' => 'test', 'value' => 'value', 'class' => "t"]));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user