diff --git a/packages/oui-field/src/field.controller.js b/packages/oui-field/src/field.controller.js index e11dac85..2b521a6f 100644 --- a/packages/oui-field/src/field.controller.js +++ b/packages/oui-field/src/field.controller.js @@ -38,7 +38,7 @@ export default class FieldController { this.ids = []; this.validationParameters = {}; this.invalid = false; - this.invalidOnBlur = false; + this.blurred = false; this.hasFocus = false; this.size = this.size || "auto"; } @@ -130,35 +130,28 @@ export default class FieldController { angular.element(controlElement).on("focus", () => { this.$timeout(() => { - this.hideErrors(controlElement, name); + this.form[name].$touched = false; this.hasFocus = true; }); }); } checkControlErrors (controlElement, name) { + this.blurred = true; if (this.form[name] && this.form[name].$invalid) { - this.invalidOnBlur = true; this.currentErrorField = name; } else { - this.invalidOnBlur = false; this.currentErrorField = null; } } - hideErrors (controlElement, name) { - this.form[name].$touched = false; - this.invalidOnBlur = false; - } - isErrorVisible () { if (!this.form) { return false; } this.checkAllErrors(); - return this.invalidOnBlur || // true if invalid after blur event - (this.form.$submitted && this.invalid && !this.hasFocus); // true if invalid after submit event + return this.invalid && !this.hasFocus && (this.blurred || this.form.$submitted); } checkAllErrors () { diff --git a/packages/oui-password/README.md b/packages/oui-password/README.md index 4647e5f0..ce116ee5 100644 --- a/packages/oui-password/README.md +++ b/packages/oui-password/README.md @@ -62,6 +62,32 @@ ``` +#### Confirm Validation + +Useful when you have a password field and a confirm password field. The confirm property takes the expression, the value of which should match with it's model value. + +```html:preview +
+``` + #### Custom strength feedback The feedback of password strength can be overridden by adding your custom feedback in `oui-password-strength`. @@ -105,6 +131,7 @@ It can also be globally changed with `ouiPasswordProvider` (see **Configuration* | `pattern` | string<regexp> | @? | yes | n/a | n/a | pattern of the model value | `required` | boolean | | no | `true`, `false` | `false` | required flag | `on-change` | function | & | no | n/a | n/a | handler triggered when value has changed +| `confirm` | string | | no | n/a | n/a | an expression, used for confirm password, which should match with the model value ### oui-rule diff --git a/packages/oui-password/src/index.spec.js b/packages/oui-password/src/index.spec.js index abab4053..1b9f167d 100644 --- a/packages/oui-password/src/index.spec.js +++ b/packages/oui-password/src/index.spec.js @@ -141,6 +141,73 @@ describe("ouiPassword", () => { }); }); + describe("ConfirmValidation", () => { + let form; + let passwords; + let password; + let confirmPassword; + let confirmPasswordController; + let passwordInput; + let confirmPasswordInput; + + beforeEach(() => { + form = TestUtils.compileTemplate(` + `); + + $timeout.flush(); + passwords = form.find("oui-password"); + password = angular.element(passwords[0]); + confirmPassword = angular.element(passwords[1]); + password.controller("ouiPassword"); + confirmPasswordController = confirmPassword.controller("ouiPassword"); + passwordInput = getInput(password); + confirmPasswordInput = getInput(confirmPassword); + }); + + it("should get an error 'confirm'", () => { + passwordInput.val("foobar"); + passwordInput.triggerHandler("input"); + confirmPasswordInput.val("foo"); + confirmPasswordInput.triggerHandler("input"); + + expect(confirmPasswordController.form.$error).toBeTruthy(); + expect(confirmPasswordController.form.$error.password).toBeTruthy(); + }); + + it("should not get an error if passwords match", () => { + passwordInput.val("foobar"); + passwordInput.triggerHandler("input"); + confirmPasswordInput.val("foobar"); + confirmPasswordInput.triggerHandler("input"); + + expect(confirmPasswordController.form.$error.password).toBeFalsy(); + }); + + it("should detect a change in the confirm property value and trigger validation", () => { + passwordInput.val("foobar"); + passwordInput.triggerHandler("input"); + confirmPasswordInput.val("foobar"); + confirmPasswordInput.triggerHandler("input"); + passwordInput.val("foobar123"); + passwordInput.triggerHandler("input"); + + expect(confirmPasswordController.form.$error).toBeTruthy(); + expect(confirmPasswordController.form.$error.password).toBeTruthy(); + }); + }); + describe("Strength", () => { const compileStrength = (score) => TestUtils.compileTemplate(`