Skip to content
This repository was archived by the owner on Aug 7, 2020. It is now read-only.

Commit c440d40

Browse files
authored
Merge pull request #395 from ovh-ux/develop
Develop
2 parents 34123aa + de19bd9 commit c440d40

File tree

5 files changed

+113
-18
lines changed

5 files changed

+113
-18
lines changed

packages/oui-field/src/field.controller.js

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export default class FieldController {
3838
this.ids = [];
3939
this.validationParameters = {};
4040
this.invalid = false;
41-
this.invalidOnBlur = false;
41+
this.blurred = false;
4242
this.hasFocus = false;
4343
this.size = this.size || "auto";
4444
}
@@ -130,35 +130,28 @@ export default class FieldController {
130130

131131
angular.element(controlElement).on("focus", () => {
132132
this.$timeout(() => {
133-
this.hideErrors(controlElement, name);
133+
this.form[name].$touched = false;
134134
this.hasFocus = true;
135135
});
136136
});
137137
}
138138

139139
checkControlErrors (controlElement, name) {
140+
this.blurred = true;
140141
if (this.form[name] && this.form[name].$invalid) {
141-
this.invalidOnBlur = true;
142142
this.currentErrorField = name;
143143
} else {
144-
this.invalidOnBlur = false;
145144
this.currentErrorField = null;
146145
}
147146
}
148147

149-
hideErrors (controlElement, name) {
150-
this.form[name].$touched = false;
151-
this.invalidOnBlur = false;
152-
}
153-
154148
isErrorVisible () {
155149
if (!this.form) {
156150
return false;
157151
}
158152

159153
this.checkAllErrors();
160-
return this.invalidOnBlur || // true if invalid after blur event
161-
(this.form.$submitted && this.invalid && !this.hasFocus); // true if invalid after submit event
154+
return this.invalid && !this.hasFocus && (this.blurred || this.form.$submitted);
162155
}
163156

164157
checkAllErrors () {

packages/oui-password/README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,32 @@
6262
</form>
6363
```
6464

65+
#### Confirm Validation
66+
67+
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.
68+
69+
```html:preview
70+
<form name="form3" novalidate>
71+
<oui-field label="Password" size="xl">
72+
<oui-password model="$ctrl.modelTriggerValidation">
73+
<oui-password-rule validator="$ctrl.checkPasswordLength(modelValue)">
74+
Must contain between 8 and 30 characters
75+
</oui-password-rule>
76+
<oui-password-rule pattern="[0-9]+">
77+
Have at least one number
78+
</oui-password-rule>
79+
<oui-password-rule pattern="[A-Z]+">
80+
Have at least capital letter
81+
</oui-password-rule>
82+
</oui-password>
83+
</oui-field>
84+
<oui-field label="Confirm Password" size="xl">
85+
<oui-password model="$ctrl.modelTriggerValidationConfirmPassword" confirm="$ctrl.modelTriggerValidation">
86+
</oui-password>
87+
</oui-field>
88+
</form>
89+
```
90+
6591
#### Custom strength feedback
6692

6793
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*
105131
| `pattern` | string&lt;regexp&gt; | @? | yes | n/a | n/a | pattern of the model value
106132
| `required` | boolean | <? | no | `true`, `false` | `false` | required flag
107133
| `on-change` | function | & | no | n/a | n/a | handler triggered when value has changed
134+
| `confirm` | string | <? | no | n/a | n/a | an expression, used for confirm password, which should match with the model value
108135

109136
### oui-rule
110137

packages/oui-password/src/index.spec.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,73 @@ describe("ouiPassword", () => {
141141
});
142142
});
143143

144+
describe("ConfirmValidation", () => {
145+
let form;
146+
let passwords;
147+
let password;
148+
let confirmPassword;
149+
let confirmPasswordController;
150+
let passwordInput;
151+
let confirmPasswordInput;
152+
153+
beforeEach(() => {
154+
form = TestUtils.compileTemplate(`
155+
<form name="form">
156+
<oui-password id="password1" name="password1"
157+
model="$ctrl.model1"
158+
minlength="4"
159+
maxlength="16"
160+
pattern="^[a-zA-Z0-9]+$"
161+
required>
162+
</oui-password>
163+
<oui-password id="confirmpassword1" name="confirmpassword1"
164+
model="$ctrl.model2"
165+
confirm="$ctrl.model1">
166+
</oui-password>
167+
</form>`);
168+
169+
$timeout.flush();
170+
passwords = form.find("oui-password");
171+
password = angular.element(passwords[0]);
172+
confirmPassword = angular.element(passwords[1]);
173+
password.controller("ouiPassword");
174+
confirmPasswordController = confirmPassword.controller("ouiPassword");
175+
passwordInput = getInput(password);
176+
confirmPasswordInput = getInput(confirmPassword);
177+
});
178+
179+
it("should get an error 'confirm'", () => {
180+
passwordInput.val("foobar");
181+
passwordInput.triggerHandler("input");
182+
confirmPasswordInput.val("foo");
183+
confirmPasswordInput.triggerHandler("input");
184+
185+
expect(confirmPasswordController.form.$error).toBeTruthy();
186+
expect(confirmPasswordController.form.$error.password).toBeTruthy();
187+
});
188+
189+
it("should not get an error if passwords match", () => {
190+
passwordInput.val("foobar");
191+
passwordInput.triggerHandler("input");
192+
confirmPasswordInput.val("foobar");
193+
confirmPasswordInput.triggerHandler("input");
194+
195+
expect(confirmPasswordController.form.$error.password).toBeFalsy();
196+
});
197+
198+
it("should detect a change in the confirm property value and trigger validation", () => {
199+
passwordInput.val("foobar");
200+
passwordInput.triggerHandler("input");
201+
confirmPasswordInput.val("foobar");
202+
confirmPasswordInput.triggerHandler("input");
203+
passwordInput.val("foobar123");
204+
passwordInput.triggerHandler("input");
205+
206+
expect(confirmPasswordController.form.$error).toBeTruthy();
207+
expect(confirmPasswordController.form.$error.password).toBeTruthy();
208+
});
209+
});
210+
144211
describe("Strength", () => {
145212
const compileStrength = (score) => TestUtils.compileTemplate(`
146213
<oui-password id="foo" name="bar" model="$ctrl.model">

packages/oui-password/src/password.component.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ export default {
1515
minlength: "<?",
1616
pattern: "@?",
1717
required: "<?",
18-
onChange: "&"
18+
onChange: "&",
19+
confirm: "<?"
1920
},
2021
controller,
2122
template,

packages/oui-password/src/password.controller.js

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export default class {
66

77
this.$attrs = $attrs;
88
this.$element = $element;
9-
this.$id = $scope.$id;
9+
this.$scope = $scope;
1010
this.$timeout = $timeout;
1111
this.translations = ouiPasswordConfiguration.translations;
1212
}
@@ -30,19 +30,26 @@ export default class {
3030
addBooleanParameter(this, "disabled");
3131
addBooleanParameter(this, "required");
3232

33-
addDefaultParameter(this, "id", `ouiPassword${this.$id}`);
34-
addDefaultParameter(this, "name", `ouiPassword${this.$id}`);
33+
addDefaultParameter(this, "id", `ouiPassword${this.$scope.$id}`);
34+
addDefaultParameter(this, "name", `ouiPassword${this.$scope.$id}`);
3535

3636
this.errors = {};
3737
this.isVisible = false;
3838
}
3939

4040
$postLink () {
41-
this.$timeout(() =>
41+
this.$timeout(() => {
4242
this.$element
4343
.removeAttr("id")
4444
.removeAttr("name")
45-
.addClass("oui-password")
46-
);
45+
.addClass("oui-password");
46+
47+
if ("confirm" in this.$attrs) {
48+
this.$scope.$watch(
49+
() => this.confirm === this.model,
50+
(value) => this.updateValidity("confirm", value)
51+
);
52+
}
53+
});
4754
}
4855
}

0 commit comments

Comments
 (0)