IGNITE-9811 Web Console: Do not block "Save" button in case some inputs are invalid and show validation when clicked.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/070819a5 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/070819a5 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/070819a5 Branch: refs/heads/ignite-9720 Commit: 070819a528dfe944f39cee8f08331891820242f7 Parents: 4fb1fc3 Author: Ilya Borisov <klast...@gmail.com> Authored: Tue Nov 20 17:34:38 2018 +0700 Committer: Alexey Kuznetsov <akuznet...@apache.org> Committed: Tue Nov 20 17:34:38 2018 +0700 ---------------------------------------------------------------------- .../components/form-field-size/controller.js | 19 +++++++++++++++++- .../components/form-field-size/template.pug | 1 + .../form-field/showValidationError.directive.js | 21 +++++++++++++++++--- .../page-configure/components/pcValidation.js | 18 ++++++++++++++++- .../app/components/page-profile/controller.js | 12 +++++++++-- .../app/components/page-profile/template.pug | 5 +---- .../app/components/page-signin/controller.ts | 3 +++ 7 files changed, 68 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/070819a5/modules/web-console/frontend/app/components/form-field/components/form-field-size/controller.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/components/form-field/components/form-field-size/controller.js b/modules/web-console/frontend/app/components/form-field/components/form-field-size/controller.js index 7f2f1b1..e158c0a 100644 --- a/modules/web-console/frontend/app/components/form-field/components/form-field-size/controller.js +++ b/modules/web-console/frontend/app/components/form-field/components/form-field-size/controller.js @@ -67,7 +67,8 @@ export default class PCFormFieldSizeController { } $onDestroy() { - this.$element = null; + delete this.$element[0].focus; + this.$element = this.inputElement = null; } $onInit() { @@ -84,6 +85,8 @@ export default class PCFormFieldSizeController { this.ngModel.$validators.max = (value) => this.ngModel.$isEmpty(value) || value === void 0 || value <= this.max; this.ngModel.$validators.step = (value) => this.ngModel.$isEmpty(value) || value === void 0 || Math.floor(value) === value; + this.inputElement = this.$element[0].querySelector('input'); + this.$element[0].focus = () => this.inputElement.focus(); } $onChanges(changes) { @@ -143,4 +146,18 @@ export default class PCFormFieldSizeController { this.sizesMenu = PCFormFieldSizeController.sizeTypes.bytes; this.sizeScale = this.chooseSizeScale(); } + + notifyAboutError() { + if (this.$element) + this.$element.find('.form-field__error [bs-tooltip]').trigger('mouseenter'); + } + + hideError() { + if (this.$element) + this.$element.find('.form-field__error [bs-tooltip]').trigger('mouseleave'); + } + + triggerBlur() { + this.$element[0].dispatchEvent(new FocusEvent('blur', {relatedTarget: this.inputElement})); + } } http://git-wip-us.apache.org/repos/asf/ignite/blob/070819a5/modules/web-console/frontend/app/components/form-field/components/form-field-size/template.pug ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/components/form-field/components/form-field-size/template.pug b/modules/web-console/frontend/app/components/form-field/components/form-field-size/template.pug index 147440b..6a2974d 100644 --- a/modules/web-console/frontend/app/components/form-field/components/form-field-size/template.pug +++ b/modules/web-console/frontend/app/components/form-field/components/form-field-size/template.pug @@ -40,6 +40,7 @@ include /app/helpers/jade/mixins ng-required='$ctrl.required' ng-disabled='$ctrl.ngDisabled' ignite-form-field-input-autofocus='{{$ctrl.autofocus}}' + ng-on-blur='$ctrl.triggerBlur()' ) button.select-toggle( bs-select http://git-wip-us.apache.org/repos/asf/ignite/blob/070819a5/modules/web-console/frontend/app/components/form-field/showValidationError.directive.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/components/form-field/showValidationError.directive.js b/modules/web-console/frontend/app/components/form-field/showValidationError.directive.js index 8720c56..31a8f2d 100644 --- a/modules/web-console/frontend/app/components/form-field/showValidationError.directive.js +++ b/modules/web-console/frontend/app/components/form-field/showValidationError.directive.js @@ -21,8 +21,17 @@ */ export function directive($timeout) { return { - require: ['ngModel', '?^^bsCollapseTarget', '?^^igniteFormField', '?^^panelCollapsible'], - link(scope, el, attr, [ngModel, bsCollapseTarget, igniteFormField, panelCollapsible]) { + require: ['ngModel', '?^^bsCollapseTarget', '?^^igniteFormField', '?formFieldSize', '?^^panelCollapsible'], + link(scope, el, attr, [ngModel, bsCollapseTarget, igniteFormField, formFieldSize, panelCollapsible]) { + const formFieldController = igniteFormField || formFieldSize; + + let onBlur; + + scope.$on('$destroy', () => { + el[0].removeEventListener('blur', onBlur); + onBlur = null; + }); + const off = scope.$on('$showValidationError', (e, target) => { if (target !== ngModel) return; @@ -32,6 +41,12 @@ export function directive($timeout) { bsCollapseTarget && bsCollapseTarget.open(); panelCollapsible && panelCollapsible.open(); + if (!onBlur && formFieldController) { + onBlur = () => formFieldController.hideError(); + + el[0].addEventListener('blur', onBlur, {passive: true}); + } + $timeout(() => { if (el[0].scrollIntoViewIfNeeded) el[0].scrollIntoViewIfNeeded(); @@ -41,7 +56,7 @@ export function directive($timeout) { if (!attr.bsSelect) $timeout(() => el[0].focus()); - igniteFormField && igniteFormField.notifyAboutError(); + formFieldController && formFieldController.notifyAboutError(); }); }); } http://git-wip-us.apache.org/repos/asf/ignite/blob/070819a5/modules/web-console/frontend/app/components/page-configure/components/pcValidation.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/components/page-configure/components/pcValidation.js b/modules/web-console/frontend/app/components/page-configure/components/pcValidation.js index 1702c35..697e9e9 100644 --- a/modules/web-console/frontend/app/components/page-configure/components/pcValidation.js +++ b/modules/web-console/frontend/app/components/page-configure/components/pcValidation.js @@ -21,21 +21,37 @@ export class IgniteFormField { static animName = 'ignite-form-field__error-blink'; static eventName = 'webkitAnimationEnd oAnimationEnd msAnimationEnd animationend'; static $inject = ['$element', '$scope']; + constructor($element, $scope) { Object.assign(this, {$element}); this.$scope = $scope; } + $postLink() { this.onAnimEnd = () => this.$element.removeClass(IgniteFormField.animName); this.$element.on(IgniteFormField.eventName, this.onAnimEnd); } + $onDestroy() { this.$element.off(IgniteFormField.eventName, this.onAnimEnd); this.$element = this.onAnimEnd = null; } + notifyAboutError() { - if (this.$element) this.$element.addClass(IgniteFormField.animName); + if (!this.$element) + return; + + this.$element.addClass(IgniteFormField.animName); + this.$element.find('.form-field__error [bs-tooltip]').trigger('mouseenter'); } + + hideError() { + if (!this.$element) + return; + + this.$element.find('.form-field__error [bs-tooltip]').trigger('mouseleave'); + } + /** * Exposes control in $scope * @param {ng.INgModelController} control http://git-wip-us.apache.org/repos/asf/ignite/blob/070819a5/modules/web-console/frontend/app/components/page-profile/controller.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/components/page-profile/controller.js b/modules/web-console/frontend/app/components/page-profile/controller.js index 8586656..a2f344e 100644 --- a/modules/web-console/frontend/app/components/page-profile/controller.js +++ b/modules/web-console/frontend/app/components/page-profile/controller.js @@ -19,7 +19,7 @@ import _ from 'lodash'; export default class PageProfileController { static $inject = [ - '$rootScope', '$scope', '$http', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteFocus', 'IgniteConfirm', 'IgniteCountries', 'User' + '$rootScope', '$scope', '$http', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteFocus', 'IgniteConfirm', 'IgniteCountries', 'User', 'IgniteFormUtils' ]; /** @@ -32,8 +32,9 @@ export default class PageProfileController { * @param {import('app/services/Confirm.service').Confirm} Confirm * @param {ReturnType<typeof import('app/services/Countries.service').default>} Countries * @param {ReturnType<typeof import('app/modules/user/User.service').default>} User + * @param {ReturnType<typeof import('app/services/FormUtils.service').default>} FormUtils */ - constructor($root, $scope, $http, LegacyUtils, Messages, Focus, Confirm, Countries, User) { + constructor($root, $scope, $http, LegacyUtils, Messages, Focus, Confirm, Countries, User, FormUtils) { this.$root = $root; this.$scope = $scope; this.$http = $http; @@ -43,6 +44,7 @@ export default class PageProfileController { this.Confirm = Confirm; this.Countries = Countries; this.User = User; + this.FormUtils = FormUtils; } $onInit() { @@ -69,6 +71,12 @@ export default class PageProfileController { } saveUser() { + if (this.form.$invalid) { + this.FormUtils.triggerValidation(this.form); + + return; + } + return this.$http.post('/api/v1/profile/save', this.ui.user) .then(this.User.load) .then(() => { http://git-wip-us.apache.org/repos/asf/ignite/blob/070819a5/modules/web-console/frontend/app/components/page-profile/template.pug ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/components/page-profile/template.pug b/modules/web-console/frontend/app/components/page-profile/template.pug index 3c5fb52..68c321f 100644 --- a/modules/web-console/frontend/app/components/page-profile/template.pug +++ b/modules/web-console/frontend/app/components/page-profile/template.pug @@ -154,9 +154,6 @@ div footer a.btn-ignite.btn-ignite--link-success(type='button' ui-sref='default-state') Cancel - button.btn-ignite.btn-ignite--success( - ng-click='$ctrl.saveUser()' - ng-disabled='$ctrl.form.$invalid' - ) + button.btn-ignite.btn-ignite--success(ng-click='$ctrl.saveUser()') svg.icon-left(ignite-icon='checkmark') | Save Changes http://git-wip-us.apache.org/repos/asf/ignite/blob/070819a5/modules/web-console/frontend/app/components/page-signin/controller.ts ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/components/page-signin/controller.ts b/modules/web-console/frontend/app/components/page-signin/controller.ts index 724da41..c461b86 100644 --- a/modules/web-console/frontend/app/components/page-signin/controller.ts +++ b/modules/web-console/frontend/app/components/page-signin/controller.ts @@ -66,7 +66,10 @@ export default class { return this.Auth.signin(this.data.email, this.data.password).catch((res) => { this.IgniteMessages.showError(null, res.data); + this.setServerError(res.data); + + this.IgniteFormUtils.triggerValidation(this.form); }); } }