Skip to content

Commit c81ed92

Browse files
committed
Merge branch 'feature/validation-helpers' into develop
2 parents 10a3a6e + 7cd4660 commit c81ed92

File tree

3 files changed

+118
-0
lines changed

3 files changed

+118
-0
lines changed

src/app/main.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ import de_CHTranslation from './../locales/de_CH.json';
2828
import 'isomorphic-fetch';
2929
import LanguageDetector from 'i18next-browser-languagedetector';
3030

31+
/**
32+
* Polyfills
33+
*/
34+
import 'utils/polyfills.utils';
35+
3136
// Fontawesome setup
3237
import fontawesome from '@fortawesome/fontawesome';
3338
import fontawesomeSolid from '@fortawesome/fontawesome-free-solid';

src/app/utils/polyfills.utils.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// tslint:disable-next-line:interface-name
2+
interface StringConstructor {
3+
isEmpty(str: string | undefined): boolean;
4+
emptyIfUndefined(str: string): string;
5+
}
6+
7+
// tslint:disable-next-line:no-null-keyword
8+
String.isEmpty = str => str === undefined || str === null || str.length === 0;
9+
10+
String.emptyIfUndefined = str => String.isEmpty(str) ? '' : str;

src/app/utils/validation.utils.ts

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import { Rule, ValidationController } from 'aurelia-validation';
2+
3+
/**
4+
* Some regex pattern for validation
5+
*/
6+
export const isInteger = /^[0-9]*$/;
7+
export const isNumber = /^[0-9]+(?:\.[0-9]+)?$/;
8+
export const isAmount = /^[0-9]{1,3}('[0-9]{3})*$/; //matches amounts, separated by comma, e.g. 12'555'432
9+
export const amount = /\B(?=(\d{3})+(?!\d))/g; //format a string of numbers to separate thousands, e.g. 10'000
10+
export const swissPrefix = /^0041[\d ]*$/; //check if number has swiss prefix
11+
export const specialPrefix = /^0[8,9]00[\d ]*$/; //check if number has 0800 or 0900 prefix
12+
export const swissPhoneNumber = /^0041 \d{2} \d{3}( \d{2}){2}$/; //matches swiss number, eg. 0041 44 761 11 11
13+
export const specialPhoneNumber = /^0[8,9]00 \d{3} \d{3}$/; //matches swiss number, eg. 0800 800 800
14+
export const generalPhoneNumber = /^\d{4} \d{2} \d{3} \d{2}( \d{1,2}){1,}$/; //matches phone number, eg. 0043 11 233 44 55 6
15+
export const urlString = /^https?:\/\//; //matches urls
16+
export const protocol = /.*:\/\/.*/; //matches any string which contains ://
17+
18+
/**
19+
* Checkes if someting is empty or satisfies a function
20+
*/
21+
export const isEmptyOrSatisfies = (
22+
value: any,
23+
satisfies: (value: any) => boolean
24+
): boolean => {
25+
if (!value || String.isEmpty(value) || (Array.isArray(value) && value.length === 0)) {
26+
return true;
27+
}
28+
return satisfies(value);
29+
};
30+
31+
/**
32+
* Count the applicable rules for an object
33+
*/
34+
export const countApplicableRules = <T>(rules: Rule<T, any>[][], object: T): number => {
35+
return rules && rules.reduce(
36+
(total, rules) =>
37+
rules.reduce((acc, rule) => acc + (!rule.when || rule.when(object) ? 1 : 0), total)
38+
, 0);
39+
};
40+
41+
/**
42+
* Usefull in activate or attached methods to check filled fields or to force check a field
43+
* This method can even check objects in arrays
44+
*/
45+
export const validateFilledFieldsWithValidationRules = <M, T>(
46+
rules: Rule<M, any>[][],
47+
model: T,
48+
controller: ValidationController,
49+
forceProperty?: string,
50+
): void => {
51+
rules.forEach(rulesItem =>
52+
rulesItem.forEach(rule => {
53+
if (
54+
(rule.property.name && !String.isEmpty(model[rule.property.name]))
55+
|| rule.config[`length`]
56+
|| (forceProperty && forceProperty === rule.property.name)
57+
) {
58+
controller.validate({
59+
object: model,
60+
propertyName: rule.property.name
61+
});
62+
} else if (Array.isArray(model)) {
63+
model.forEach(arrayModel => {
64+
validateFilledFieldsWithValidationRules(rules, arrayModel, controller, forceProperty);
65+
});
66+
}
67+
})
68+
);
69+
};
70+
71+
export const controllerValidByRules = <T>(
72+
rules: Rule<T, any>[][],
73+
model: T,
74+
controller: ValidationController
75+
): boolean => {
76+
return !controller.validating
77+
&& controller[`results`].length >= countApplicableRules<T>(rules, model)
78+
&& controller.errors.length === 0;
79+
};
80+
81+
export const validatePhoneNumber = (
82+
value: string
83+
): boolean => {
84+
if (swissPrefix.test(value)) {
85+
return swissPhoneNumber.test(value);
86+
}
87+
if (specialPrefix.test(value)) {
88+
return specialPhoneNumber.test(value);
89+
}
90+
return generalPhoneNumber.test(value);
91+
};
92+
93+
export const validateURL = (
94+
value: string
95+
): boolean => {
96+
return urlString.test(value);
97+
};
98+
99+
export const validateProtocol = (
100+
value: string
101+
): boolean => {
102+
return protocol.test(value);
103+
};

0 commit comments

Comments
 (0)