From 064d0ef6b17e70d12c0366f839a4880691c87681 Mon Sep 17 00:00:00 2001
From: Jean-Daniel Pearson <1476965+JDownloader@users.noreply.github.com>
Date: Tue, 27 Feb 2018 16:12:02 -0500
Subject: [PATCH 1/2] :sparkles: feat(field): add custom error message and
ng-pattern support
---
packages/oui-field/README.md | 32 ++++++-
packages/oui-field/src/field.component.js | 3 +-
packages/oui-field/src/field.controller.js | 13 ++-
packages/oui-field/src/field.html | 2 +
packages/oui-field/src/field.provider.js | 3 +-
packages/oui-field/src/index.spec.js | 98 ++++++++++++++++++++--
6 files changed, 136 insertions(+), 15 deletions(-)
diff --git a/packages/oui-field/README.md b/packages/oui-field/README.md
index 84fc307c..a2408449 100644
--- a/packages/oui-field/README.md
+++ b/packages/oui-field/README.md
@@ -30,6 +30,17 @@
name="email"
ng-model="$ctrl.user.email">
+
+
+
+
```
### Checkbox
@@ -149,7 +160,20 @@
### oui-datagrid
-| Attribute | Type | Binding | One-time binding | Values | Default | Description |
-| ---- | ---- | ---- | ---- | ---- | ---- | ---- |
-| `help-text` | string | @? | yes | | | the field label |
-| `label` | function | @? | yes | | | a text to help fill the form field |
+| Attribute | Type | Binding | One-time binding | Values | Default | Description |
+| ---- | ---- | ---- | ---- | ---- | ---- | ---- |
+| `error-messages` | object | | no | | | a dictionary to override default messages |
+| `help-text` | string | @? | yes | | | the field label |
+| `label` | function | @? | yes | | | a text to help fill the form field |
+
+### error-messages
+
+| Attribute | Type | Binding | One-time binding | Values | Default | Description |
+| ---- | ---- | ---- | ---- | ---- | ---- | ---- |
+| `required` | string | | no | | Mandatory. | |
+| `email` | string | | no | | Invalid email. | |
+| `min` | string | | no | | Too low (1 min). | |
+| `max` | string | | no | | Too high (100 max). | |
+| `minlength` | string | | no | | Too short (6 characters min). | |
+| `maxlength` | string | | no | | Too high (12 characters max). | |
+| `pattern` | string | | no | | Invalid format. | |
diff --git a/packages/oui-field/src/field.component.js b/packages/oui-field/src/field.component.js
index e3364c88..dea42744 100644
--- a/packages/oui-field/src/field.component.js
+++ b/packages/oui-field/src/field.component.js
@@ -4,7 +4,8 @@ import template from "./field.html";
export default {
bindings: {
label: "@?",
- helpText: "@?"
+ helpText: "@?",
+ errorMessages: ""
},
controller,
require: {
diff --git a/packages/oui-field/src/field.controller.js b/packages/oui-field/src/field.controller.js
index 7f1d3a84..76aa5312 100644
--- a/packages/oui-field/src/field.controller.js
+++ b/packages/oui-field/src/field.controller.js
@@ -22,7 +22,8 @@ const VALIDATION_PARAMETERS = {
min: ["min", "ng-min"],
max: ["max", "ng-max"],
minlength: ["minlength", "ng-minlength"],
- maxlength: ["maxlength", "ng-maxlength"]
+ maxlength: ["maxlength", "ng-maxlength"],
+ custumValidation: ["pattern", "ng-pattern"]
};
export default class FieldController {
@@ -124,7 +125,7 @@ export default class FieldController {
showErrors (controlElement, name) {
this.$timeout(() => {
- if (this.form[name].$invalid) {
+ if (this.form[name] && this.form[name].$invalid) {
angular.element(controlElement).addClass(FieldController.getErrorClass(controlElement));
this.$ouiFieldElement.addClass("oui-field_error");
this.isErrorVisible = true;
@@ -149,7 +150,7 @@ export default class FieldController {
getFirstError () {
const names = Object.keys(this.controls);
for (let i = 0; i < names.length; ++i) {
- if (this.form[names[i]].$invalid) {
+ if (this.form[names[i]] && this.form[names[i]].$invalid) {
return this.form[names[i]].$error;
}
}
@@ -157,8 +158,12 @@ export default class FieldController {
return null;
}
+ getMessageString (errorName) {
+ return (this.errorMessages && this.errorMessages[errorName]) || this.ouiFieldConfiguration.translations.errors[errorName];
+ }
+
getErrorMessage (errorName) {
- const message = this.ouiFieldConfiguration.translations.errors[errorName];
+ const message = this.getMessageString(errorName);
const parameterValue = this.validationParameters[this.currentErrorField][errorName];
return message.replace(`{{${errorName}}}`, parameterValue);
}
diff --git a/packages/oui-field/src/field.html b/packages/oui-field/src/field.html
index 8f9ea9cd..7c2bb161 100644
--- a/packages/oui-field/src/field.html
+++ b/packages/oui-field/src/field.html
@@ -22,6 +22,8 @@
ng-bind="$ctrl.getErrorMessage('min')">
+
{
expect(getLabel(element)).toBeNull();
});
- it("should set the for attribute on label", () => {
+ it("should set the 'for' attribute on label", () => {
const id = "lastname";
const element = TestUtils.compileTemplate(`
@@ -90,6 +90,60 @@ describe("ouiField", () => {
expect(getLabel(element).getAttribute("for")).toEqual(id);
});
+ it("should trigger error when invalid format", () => {
+
+ const element = TestUtils.compileTemplate(`
+
+ `);
+ const controller = getField(element).controller("ouiField");
+
+ $timeout.flush();
+
+ const $control = getControl(controller, "username");
+ $control.val("ch@t12");
+ $control.triggerHandler("input");
+ $control.triggerHandler("blur");
+
+ expect(controller.getFirstError().pattern).toBeTruthy();
+ });
+
+ it("should trigger error when length too short", () => {
+
+ const element = TestUtils.compileTemplate(`
+
+ `);
+ const controller = getField(element).controller("ouiField");
+
+ $timeout.flush();
+
+ const $control = getControl(controller, "username");
+ $control.val("abc");
+ $control.triggerHandler("input");
+ $control.triggerHandler("blur");
+
+ expect(controller.getFirstError().minlength).toBeTruthy();
+ });
+
it("should set the name of the form field in the controller", () => {
const name = "lastname";
@@ -128,16 +182,16 @@ describe("ouiField", () => {
id="age"
name="age"
ng-model="$ctrl.user.age"
- min="{{$ctrl.validation.min}}"
- max="{{$ctrl.validation.max}}">
+ ng-min="{{$ctrl.validation.min}}"
+ ng-max="{{$ctrl.validation.max}}">
+ ng-minlength="{{$ctrl.validation.minlength}}"
+ ng-maxlength="{{$ctrl.validation.maxlength}}">
`, {
validation
@@ -466,6 +520,40 @@ describe("ouiField", () => {
});
});
+ describe("with validation", () => {
+ it("should retrieve custom error messages", () => {
+ const message = "Username must be a least 6 characters.";
+
+ const element = TestUtils.compileTemplate(`
+
+ `);
+
+ const controller = getField(element).controller("ouiField");
+
+ $timeout.flush();
+
+ const $control = getControl(controller, "username");
+ $control.val("abc");
+ $control.triggerHandler("input");
+ $control.triggerHandler("blur");
+
+ $timeout.flush();
+
+ expect(controller.getFirstError().minlength).toBeTruthy();
+ expect(controller.getErrorMessage("minlength")).toBe(message);
+ });
+ });
});
});
From 482a8fafb13c8e2194add4f6ec66bcb733b54e67 Mon Sep 17 00:00:00 2001
From: Jean-Daniel Pearson <1476965+JDownloader@users.noreply.github.com>
Date: Mon, 5 Mar 2018 11:51:26 -0500
Subject: [PATCH 2/2] chore(field): add more test and review doc
---
packages/oui-field/README.md | 26 ++++++++---------
packages/oui-field/src/field.controller.js | 2 +-
packages/oui-field/src/index.spec.js | 34 +++++++++++++++++++++-
3 files changed, 46 insertions(+), 16 deletions(-)
diff --git a/packages/oui-field/README.md b/packages/oui-field/README.md
index a2408449..52f0c5f0 100644
--- a/packages/oui-field/README.md
+++ b/packages/oui-field/README.md
@@ -39,7 +39,7 @@
id="username"
name="username"
ng-model="$ctrl.user.username"
- ng-pattern="/^[a-z]{3,8}$/">
+ ng-pattern="/^[a-zA-Z]{3,8}$/">
```
@@ -158,22 +158,20 @@
## API
-### oui-datagrid
-
| Attribute | Type | Binding | One-time binding | Values | Default | Description |
| ---- | ---- | ---- | ---- | ---- | ---- | ---- |
| `error-messages` | object | | no | | | a dictionary to override default messages |
| `help-text` | string | @? | yes | | | the field label |
| `label` | function | @? | yes | | | a text to help fill the form field |
-### error-messages
-
-| Attribute | Type | Binding | One-time binding | Values | Default | Description |
-| ---- | ---- | ---- | ---- | ---- | ---- | ---- |
-| `required` | string | | no | | Mandatory. | |
-| `email` | string | | no | | Invalid email. | |
-| `min` | string | | no | | Too low (1 min). | |
-| `max` | string | | no | | Too high (100 max). | |
-| `minlength` | string | | no | | Too short (6 characters min). | |
-| `maxlength` | string | | no | | Too high (12 characters max). | |
-| `pattern` | string | | no | | Invalid format. | |
+`error-messages` object can override error messages for validation.
+
+| Attribute | Type | Default |
+| ---- | ---- | ---- |
+| `required` | string | Mandatory. |
+| `email` | string | Invalid email. |
+| `min` | string | Too low (1 min). |
+| `max` | string | Too high (100 max). |
+| `minlength` | string | Too short (6 characters min). |
+| `maxlength` | string | Too high (12 characters max). |
+| `pattern` | string | Invalid format. |
diff --git a/packages/oui-field/src/field.controller.js b/packages/oui-field/src/field.controller.js
index 76aa5312..3b2228fa 100644
--- a/packages/oui-field/src/field.controller.js
+++ b/packages/oui-field/src/field.controller.js
@@ -23,7 +23,7 @@ const VALIDATION_PARAMETERS = {
max: ["max", "ng-max"],
minlength: ["minlength", "ng-minlength"],
maxlength: ["maxlength", "ng-maxlength"],
- custumValidation: ["pattern", "ng-pattern"]
+ pattern: ["pattern", "ng-pattern"]
};
export default class FieldController {
diff --git a/packages/oui-field/src/index.spec.js b/packages/oui-field/src/index.spec.js
index 21502a1f..4cf3935f 100644
--- a/packages/oui-field/src/index.spec.js
+++ b/packages/oui-field/src/index.spec.js
@@ -101,7 +101,7 @@ describe("ouiField", () => {
id="username"
name="username"
ng-model="$ctrl.username"
- ng-pattern="/^[a-z]{3,8}$/">
+ ng-pattern="/^[a-zA-Z]{3,8}$/">
`);
@@ -553,6 +553,38 @@ describe("ouiField", () => {
expect(controller.getFirstError().minlength).toBeTruthy();
expect(controller.getErrorMessage("minlength")).toBe(message);
});
+
+ it("should give a message containing parameters", () => {
+ const messageMinlength = 5;
+
+ const element = TestUtils.compileTemplate(`
+
+ `);
+
+ const controller = getField(element).controller("ouiField");
+
+ $timeout.flush();
+
+ const $control = getControl(controller, "username");
+ $control.val("abc");
+ $control.triggerHandler("input");
+ $control.triggerHandler("blur");
+
+ $timeout.flush();
+
+ expect(controller.getFirstError().minlength).toBeTruthy();
+ expect(controller.getErrorMessage("minlength")).toContain(messageMinlength);
+ });
});
});