mirror of
				https://github.com/yiisoft/yii2.git
				synced 2025-10-31 18:47:33 +08:00 
			
		
		
		
	Fixes #5006.
This commit is contained in:
		| @ -194,7 +194,6 @@ Yii Framework 2 Change Log | |||||||
| - Enh #4436: Added callback functions to AJAX-based form validation (thiagotalma) | - Enh #4436: Added callback functions to AJAX-based form validation (thiagotalma) | ||||||
| - Enh #4485: Added support for deferred validation in `ActiveForm` (Alex-Code) | - Enh #4485: Added support for deferred validation in `ActiveForm` (Alex-Code) | ||||||
| - Enh #4520: Added sasl support to `yii\caching\MemCache` (xjflyttp) | - Enh #4520: Added sasl support to `yii\caching\MemCache` (xjflyttp) | ||||||
| - Enh #4559: Added `beforeValidateAll` and `afterValidateAll` callbacks to `ActiveForm` (Alex-Code) |  | ||||||
| - Enh #4566: Added client validation support for image validator (Skysplit, qiangxue) | - Enh #4566: Added client validation support for image validator (Skysplit, qiangxue) | ||||||
| - Enh #4581: Added ability to disable url encoding in `UrlRule` (tadaszelvys) | - Enh #4581: Added ability to disable url encoding in `UrlRule` (tadaszelvys) | ||||||
| - Enh #4602: Added $key param in ActionColumn buttons Closure call (disem) | - Enh #4602: Added $key param in ActionColumn buttons Closure call (disem) | ||||||
| @ -269,7 +268,7 @@ Yii Framework 2 Change Log | |||||||
| - Chg #4911: Changed callback signature used in `yii\base\ArrayableTrait::fields()` from `function ($field, $model) {` to `function ($model, $field) {` (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) | - Chg #4955: Replaced callbacks with events for `ActiveForm` (qiangxue) | ||||||
|     - Removed `beforeValidate()`, `beforeValidateAll()`, `afterValidate()`, `afterValidateAll()`, `ajaxBeforeSend()` and `ajaxComplete()` from `ActiveForm`. |     - Removed `beforeValidate()`, `beforeValidateAll()`, `afterValidate()`, `afterValidateAll()`, `ajaxBeforeSend()` and `ajaxComplete()` from `ActiveForm`. | ||||||
|     - Added `beforeValidate`, `afterValidate`, `beforeSubmit`, `ajaxBeforeSend` and `ajaxComplete` events to `yii.activeForm`. |     - Added `beforeValidate`, `afterValidate`, `beforeValidateAttribute`, `afterValidateAttribute`, `beforeSubmit`, `ajaxBeforeSend` and `ajaxComplete` events to `yii.activeForm` jQuery plugin. | ||||||
| - Chg: Replaced `clearAll()` and `clearAllAssignments()` in `yii\rbac\ManagerInterface` with `removeAll()`, `removeAllRoles()`, `removeAllPermissions()`, `removeAllRules()` and `removeAllAssignments()` (qiangxue) | - 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: 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) | - Chg: `yii\grid\DataColumn::getDataCellValue()` visibility is now `public` to allow accessing the value from a GridView directly (cebe) | ||||||
|  | |||||||
| @ -245,18 +245,23 @@ new ones save the following code as `convert.php` that should be placed in the s | |||||||
|   You can prefix a date format with `php:` to use the old format of the PHP `date()`-function. |   You can prefix a date format with `php:` to use the old format of the PHP `date()`-function. | ||||||
|  |  | ||||||
| * `beforeValidate()`, `beforeValidateAll()`, `afterValidate()`, `afterValidateAll()`, `ajaxBeforeSend()` and `ajaxComplete()` | * `beforeValidate()`, `beforeValidateAll()`, `afterValidate()`, `afterValidateAll()`, `ajaxBeforeSend()` and `ajaxComplete()` | ||||||
|   are removed from `ActiveForm`. The same functionality is now achieved via JavaScript event mechanism. For example, |   are removed from `ActiveForm`. The same functionality is now achieved via JavaScript event mechanism like the following: | ||||||
|   if you want to do something before performing validation on the client side, you can write the following |  | ||||||
|   JavaScript code: |  | ||||||
|  |  | ||||||
|   ```js |   ```js | ||||||
|   $('#myform').on('beforeValidate', function (event, messages, deferreds, attribute) { |   $('#myform').on('beforeValidate', function (event, messages, deferreds) { | ||||||
|       if (attribute === undefined) { |       // called when the validation is triggered by submitting the form | ||||||
|           // the event is triggered when submitting the form |       // return false if you want to cancel the validation for the whole form | ||||||
|       } elseif (attribute.id === 'something') { |   }).on('beforeValidateAttribute', function (event, attribute, messages, deferreds) { | ||||||
|           // the event is triggered before validating "something" |       // before validating an attribute | ||||||
|       } |       // return false if you want to cancel the validation for the attribute | ||||||
|       // if you want to cancel the validation, return a boolean false. |   }).on('afterValidateAttribute', function (event, attribute, messages) { | ||||||
|  |       // ... | ||||||
|  |   }).on('afterValidate', function (event, messages) { | ||||||
|  |       // ... | ||||||
|  |   }).on('beforeSubmit', function () { | ||||||
|  |       // after all validations have passed | ||||||
|  |       // you can do ajax form submission here | ||||||
|  |       // return false if you want to stop form submission | ||||||
|   }); |   }); | ||||||
|   ``` |   ``` | ||||||
|  |  | ||||||
|  | |||||||
| @ -24,44 +24,60 @@ | |||||||
|  |  | ||||||
|     var events = { |     var events = { | ||||||
|         /** |         /** | ||||||
|          * beforeValidate event is triggered before validating the whole form and each attribute. |          * beforeValidate event is triggered before validating the whole form. | ||||||
|          * The signature of the event handler should be: |          * The signature of the event handler should be: | ||||||
|          *     function (event, messages, deferreds, attribute) |          *     function (event, messages, deferreds) | ||||||
|          * where |          * where | ||||||
|          *  - event: an Event object. |          *  - event: an Event object. | ||||||
|          *  - messages: error messages. When attribute is undefined, this parameter is an associative array |          *  - messages: an associative array with keys being attribute IDs and values being error message arrays | ||||||
|          *    with keys being attribute IDs and values being error messages for the corresponding attributes. |          *    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. |          *  - 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. |  | ||||||
|          * |          * | ||||||
|          * If the handler returns a boolean false, it will stop further validation after this event. |          * If the handler returns a boolean false, it will stop further form validation after this event. And as | ||||||
|  |          * a result, afterValidate event will not be triggered. | ||||||
|          */ |          */ | ||||||
|         beforeValidate: 'beforeValidate', |         beforeValidate: 'beforeValidate', | ||||||
|         /** |         /** | ||||||
|          * afterValidate event is triggered after validating the whole form and each attribute. |          * afterValidate event is triggered after validating the whole form. | ||||||
|          * The signature of the event handler should be: |          * The signature of the event handler should be: | ||||||
|          *     function (event, messages, attribute) |          *     function (event, messages) | ||||||
|          * where |          * where | ||||||
|          *  - event: an Event object. |          *  - event: an Event object. | ||||||
|          *  - messages: error messages. When attribute is undefined, this parameter is an associative array |          *  - messages: an associative array with keys being attribute IDs and values being error message arrays | ||||||
|          *    with keys being attribute IDs and values being error messages for the corresponding attributes. |          *    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', |         afterValidate: 'afterValidate', | ||||||
|         /** |         /** | ||||||
|          * beforeSubmit event is triggered before submitting the form (after all validations pass). |          * beforeValidateAttribute event is triggered before validating an attribute. | ||||||
|  |          * The signature of the event handler should be: | ||||||
|  |          *     function (event, attribute, messages, deferreds) | ||||||
|  |          * where | ||||||
|  |          *  - event: an Event object. | ||||||
|  |          *  - attribute: the attribute to be validated. Please refer to attributeDefaults for the structure of this parameter. | ||||||
|  |          *  - messages: an array to which you can add validation error messages for the specified attribute. | ||||||
|  |          *  - deferreds: an array of Deferred objects. You can use deferreds.add(callback) to add a new deferred validation. | ||||||
|  |          * | ||||||
|  |          * If the handler returns a boolean false, it will stop further validation of the specified attribute. | ||||||
|  |          * And as a result, afterValidateAttribute event will not be triggered. | ||||||
|  |          */ | ||||||
|  |         beforeValidateAttribute: 'beforeValidateAttribute', | ||||||
|  |         /** | ||||||
|  |          * afterValidateAttribute event is triggered after validating the whole form and each attribute. | ||||||
|  |          * The signature of the event handler should be: | ||||||
|  |          *     function (event, attribute, messages) | ||||||
|  |          * where | ||||||
|  |          *  - event: an Event object. | ||||||
|  |          *  - attribute: the attribute being validated. Please refer to attributeDefaults for the structure of this parameter. | ||||||
|  |          *  - messages: an array to which you can add additional validation error messages for the specified attribute. | ||||||
|  |          */ | ||||||
|  |         afterValidateAttribute: 'afterValidateAttribute', | ||||||
|  |         /** | ||||||
|  |          * beforeSubmit event is triggered before submitting the form after all validations have passed. | ||||||
|          * The signature of the event handler should be: |          * The signature of the event handler should be: | ||||||
|          *     function (event) |          *     function (event) | ||||||
|          * where event is an Event object. |          * where event is an Event object. | ||||||
|          * |          * | ||||||
|          * If the handler returns a boolean false, it will stop further validation after this event. |          * If the handler returns a boolean false, it will stop form submission. | ||||||
|          */ |          */ | ||||||
|         beforeSubmit: 'beforeSubmit', |         beforeSubmit: 'beforeSubmit', | ||||||
|         /** |         /** | ||||||
| @ -136,6 +152,8 @@ | |||||||
|         validate: undefined, |         validate: undefined, | ||||||
|         // status of the input field, 0: empty, not entered before, 1: validated, 2: pending validation, 3: validating |         // status of the input field, 0: empty, not entered before, 1: validated, 2: pending validation, 3: validating | ||||||
|         status: 0, |         status: 0, | ||||||
|  |         // whether the validation is cancelled by beforeValidateAttribute event handler | ||||||
|  |         cancelled: false, | ||||||
|         // the value of the input |         // the value of the input | ||||||
|         value: undefined |         value: undefined | ||||||
|     }; |     }; | ||||||
| @ -251,6 +269,7 @@ | |||||||
|  |  | ||||||
|             // client-side validation |             // client-side validation | ||||||
|             $.each(data.attributes, function () { |             $.each(data.attributes, function () { | ||||||
|  |                 this.cancelled = false; | ||||||
|                 // perform validation only if the form is being submitted or if an attribute is pending validation |                 // 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) { |                 if (data.submitting || this.status === 2 || this.status === 3) { | ||||||
|                     var msg = messages[this.id]; |                     var msg = messages[this.id]; | ||||||
| @ -258,8 +277,8 @@ | |||||||
|                         msg = []; |                         msg = []; | ||||||
|                         messages[this.id] = msg; |                         messages[this.id] = msg; | ||||||
|                     } |                     } | ||||||
|                     var event = $.Event(events.beforeValidate); |                     var event = $.Event(events.beforeValidateAttribute); | ||||||
|                     $form.trigger(event, [msg, deferreds, this]); |                     $form.trigger(event, [this, msg, deferreds]); | ||||||
|                     if (event.result !== false) { |                     if (event.result !== false) { | ||||||
|                         if (this.validate) { |                         if (this.validate) { | ||||||
|                             this.validate(this, getValue($form, this), msg, deferreds); |                             this.validate(this, getValue($form, this), msg, deferreds); | ||||||
| @ -267,6 +286,8 @@ | |||||||
|                         if (this.enableAjaxValidation) { |                         if (this.enableAjaxValidation) { | ||||||
|                             needAjaxValidation = true; |                             needAjaxValidation = true; | ||||||
|                         } |                         } | ||||||
|  |                     } else { | ||||||
|  |                         this.cancelled = true; | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
| @ -302,7 +323,7 @@ | |||||||
|                         success: function (msgs) { |                         success: function (msgs) { | ||||||
|                             if (msgs !== null && typeof msgs === 'object') { |                             if (msgs !== null && typeof msgs === 'object') { | ||||||
|                                 $.each(data.attributes, function () { |                                 $.each(data.attributes, function () { | ||||||
|                                     if (!this.enableAjaxValidation) { |                                     if (!this.enableAjaxValidation || this.cancelled) { | ||||||
|                                         delete msgs[this.id]; |                                         delete msgs[this.id]; | ||||||
|                                     } |                                     } | ||||||
|                                 }); |                                 }); | ||||||
| @ -457,7 +478,7 @@ | |||||||
|         if (data.submitting) { |         if (data.submitting) { | ||||||
|             var errorInputs = []; |             var errorInputs = []; | ||||||
|             $.each(data.attributes, function () { |             $.each(data.attributes, function () { | ||||||
|                 if (updateInput($form, this, messages)) { |                 if (!this.cancelled && updateInput($form, this, messages)) { | ||||||
|                     errorInputs.push(this.input); |                     errorInputs.push(this.input); | ||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
| @ -486,7 +507,7 @@ | |||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             $.each(data.attributes, function () { |             $.each(data.attributes, function () { | ||||||
|                 if (this.status === 2 || this.status === 3) { |                 if (!this.cancelled && (this.status === 2 || this.status === 3)) { | ||||||
|                     updateInput($form, this, messages); |                     updateInput($form, this, messages); | ||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
| @ -508,7 +529,7 @@ | |||||||
|         if (!$.isArray(messages[attribute.id])) { |         if (!$.isArray(messages[attribute.id])) { | ||||||
|             messages[attribute.id] = []; |             messages[attribute.id] = []; | ||||||
|         } |         } | ||||||
|         $form.trigger(events.afterValidate, [messages[attribute.id], attribute]); |         $form.trigger(events.afterValidateAttribute, [attribute, messages[attribute.id]]); | ||||||
|  |  | ||||||
|         attribute.status = 1; |         attribute.status = 1; | ||||||
|         if ($input.length) { |         if ($input.length) { | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Qiang Xue
					Qiang Xue