@fagon/ngx-intellitoolx 16.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +5 -0
- package/README.md +959 -0
- package/esm2022/fagon-ngx-intellitoolx.mjs +5 -0
- package/esm2022/lib/directives/required-marker/required-marker.config.mjs +2 -0
- package/esm2022/lib/directives/required-marker/required-marker.defaults.mjs +9 -0
- package/esm2022/lib/directives/required-marker/required-marker.directive.mjs +79 -0
- package/esm2022/lib/directives/required-marker/required-marker.token.mjs +3 -0
- package/esm2022/lib/form-errors/form-errors.component.mjs +110 -0
- package/esm2022/lib/form-update/confirm-handler.type.mjs +2 -0
- package/esm2022/lib/form-update/form-update-message-config.interface.mjs +2 -0
- package/esm2022/lib/form-update/form-update-message.component.mjs +53 -0
- package/esm2022/lib/form-update/unsaved-changes.guard.mjs +19 -0
- package/esm2022/lib/form-validators/index.mjs +6 -0
- package/esm2022/lib/form-validators/max-amount.validator.mjs +18 -0
- package/esm2022/lib/form-validators/max-words.validator.mjs +11 -0
- package/esm2022/lib/form-validators/min-amount.validator.mjs +18 -0
- package/esm2022/lib/form-validators/password-mismatch.validator.mjs +16 -0
- package/esm2022/lib/form-validators/unique-email.validators.mjs +40 -0
- package/esm2022/lib/helpers/intellitoolx.helper.mjs +156 -0
- package/esm2022/lib/ngx-intellitoolx.component.mjs +11 -0
- package/esm2022/lib/ngx-intellitoolx.module.mjs +17 -0
- package/esm2022/lib/pipes/json-parse.pipe.mjs +18 -0
- package/esm2022/lib/regex/regex.utils.mjs +7 -0
- package/esm2022/public-api.mjs +27 -0
- package/fesm2022/fagon-ngx-intellitoolx.mjs +576 -0
- package/fesm2022/fagon-ngx-intellitoolx.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/directives/required-marker/required-marker.config.d.ts +9 -0
- package/lib/directives/required-marker/required-marker.defaults.d.ts +2 -0
- package/lib/directives/required-marker/required-marker.directive.d.ts +17 -0
- package/lib/directives/required-marker/required-marker.token.d.ts +3 -0
- package/lib/form-errors/form-errors.component.d.ts +29 -0
- package/lib/form-update/confirm-handler.type.d.ts +1 -0
- package/lib/form-update/form-update-message-config.interface.d.ts +11 -0
- package/lib/form-update/form-update-message.component.d.ts +14 -0
- package/lib/form-update/unsaved-changes.guard.d.ts +11 -0
- package/lib/form-validators/index.d.ts +5 -0
- package/lib/form-validators/max-amount.validator.d.ts +2 -0
- package/lib/form-validators/max-words.validator.d.ts +2 -0
- package/lib/form-validators/min-amount.validator.d.ts +2 -0
- package/lib/form-validators/password-mismatch.validator.d.ts +2 -0
- package/lib/form-validators/unique-email.validators.d.ts +2 -0
- package/lib/helpers/intellitoolx.helper.d.ts +16 -0
- package/lib/ngx-intellitoolx.component.d.ts +5 -0
- package/lib/ngx-intellitoolx.module.d.ts +7 -0
- package/lib/pipes/json-parse.pipe.d.ts +7 -0
- package/lib/regex/regex.utils.d.ts +6 -0
- package/package.json +29 -0
- package/public-api.d.ts +14 -0
package/README.md
ADDED
|
@@ -0,0 +1,959 @@
|
|
|
1
|
+
# IntelliToolxHelper
|
|
2
|
+
|
|
3
|
+
Utility helpers for working with Angular Reactive Forms, deep comparisons, change detection, and common data transformations.
|
|
4
|
+
Designed to simplify form state management, prevent accidental navigation, and normalize user input.
|
|
5
|
+
|
|
6
|
+
### Installation
|
|
7
|
+
|
|
8
|
+
npm install intellitoolx-helper
|
|
9
|
+
|
|
10
|
+
## Import
|
|
11
|
+
|
|
12
|
+
import { IntelliToolxHelper } from 'intellitoolx-helper';
|
|
13
|
+
|
|
14
|
+
Methods
|
|
15
|
+
|
|
16
|
+
## captureInitialValue(form)
|
|
17
|
+
|
|
18
|
+
Captures and clones the initial value of a form and marks it as pristine.
|
|
19
|
+
|
|
20
|
+
static captureInitialValue(form: AbstractControl): any
|
|
21
|
+
|
|
22
|
+
Features
|
|
23
|
+
Uses getRawValue() when available
|
|
24
|
+
Marks form as pristine
|
|
25
|
+
Returns a deep clone of the initial value
|
|
26
|
+
|
|
27
|
+
Example
|
|
28
|
+
const initial = IntelliToolxHelper.captureInitialValue(this.form);
|
|
29
|
+
|
|
30
|
+
## trimFormGroup(control)
|
|
31
|
+
|
|
32
|
+
Recursively trims whitespace from all string values in a form.
|
|
33
|
+
|
|
34
|
+
static trimFormGroup(control: AbstractControl): void
|
|
35
|
+
|
|
36
|
+
Supports
|
|
37
|
+
FormGroup
|
|
38
|
+
FormArray
|
|
39
|
+
FormControl
|
|
40
|
+
|
|
41
|
+
Example
|
|
42
|
+
IntelliToolxHelper.trimFormGroup(this.form);
|
|
43
|
+
|
|
44
|
+
## deepEqual(obj1, obj2)
|
|
45
|
+
|
|
46
|
+
Performs a deep comparison between two values.
|
|
47
|
+
|
|
48
|
+
static deepEqual(obj1: any, obj2: any): boolean
|
|
49
|
+
|
|
50
|
+
Special behavior
|
|
51
|
+
Treats null, undefined, and "" as equal
|
|
52
|
+
Normalizes numeric comparisons
|
|
53
|
+
Compares File objects by metadata
|
|
54
|
+
Supports nested objects & arrays
|
|
55
|
+
|
|
56
|
+
Example
|
|
57
|
+
IntelliToolxHelper.deepEqual(a, b);
|
|
58
|
+
|
|
59
|
+
## isEmpty(value)
|
|
60
|
+
|
|
61
|
+
Checks if a value is empty.
|
|
62
|
+
|
|
63
|
+
static isEmpty(value: any): boolean
|
|
64
|
+
|
|
65
|
+
Returns true for:
|
|
66
|
+
null
|
|
67
|
+
undefined
|
|
68
|
+
empty string
|
|
69
|
+
whitespace-only string
|
|
70
|
+
|
|
71
|
+
## clone(value)
|
|
72
|
+
|
|
73
|
+
Creates a deep clone.
|
|
74
|
+
|
|
75
|
+
static clone(value: any): any
|
|
76
|
+
|
|
77
|
+
Uses structuredClone (Angular 14+ compatible).
|
|
78
|
+
|
|
79
|
+
## formHasChanges(initialValue, form)
|
|
80
|
+
|
|
81
|
+
Determines whether a form value has changed.
|
|
82
|
+
|
|
83
|
+
static formHasChanges(initialValue: any, form: AbstractControl): boolean
|
|
84
|
+
|
|
85
|
+
Example
|
|
86
|
+
if (IntelliToolxHelper.formHasChanges(initial, this.form)) {
|
|
87
|
+
// prompt user
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
## confirmIfChanged(hasChanges, confirmHandler?)
|
|
91
|
+
|
|
92
|
+
Shows confirmation if changes exist.
|
|
93
|
+
|
|
94
|
+
static confirmIfChanged(
|
|
95
|
+
hasChanges: boolean,
|
|
96
|
+
confirmHandler?: ConfirmHandler
|
|
97
|
+
): Promise<boolean>
|
|
98
|
+
|
|
99
|
+
Behavior
|
|
100
|
+
Returns true if no changes
|
|
101
|
+
Uses provided handler if available
|
|
102
|
+
Falls back to browser confirm()
|
|
103
|
+
|
|
104
|
+
Example
|
|
105
|
+
const canLeave = await IntelliToolxHelper.confirmIfChanged(
|
|
106
|
+
hasChanges,
|
|
107
|
+
() => dialog.confirm()
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
## registerBeforeUnload(shouldBlock, message?)
|
|
111
|
+
|
|
112
|
+
Prevents accidental page exit when changes exist.
|
|
113
|
+
|
|
114
|
+
static registerBeforeUnload(
|
|
115
|
+
shouldBlock: () => boolean,
|
|
116
|
+
message?: string
|
|
117
|
+
): () => void
|
|
118
|
+
|
|
119
|
+
Returns
|
|
120
|
+
Cleanup function to remove the listener.
|
|
121
|
+
|
|
122
|
+
Example
|
|
123
|
+
const cleanup = IntelliToolxHelper.registerBeforeUnload(() =>
|
|
124
|
+
this.form.dirty
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
// later
|
|
128
|
+
cleanup();
|
|
129
|
+
|
|
130
|
+
## getFormControl(form, path)
|
|
131
|
+
|
|
132
|
+
Retrieves a nested FormControl using dot notation.
|
|
133
|
+
|
|
134
|
+
static getFormControl<T>(
|
|
135
|
+
form: AbstractControl,
|
|
136
|
+
path: string
|
|
137
|
+
): FormControl<T> | null
|
|
138
|
+
|
|
139
|
+
Supports
|
|
140
|
+
Nested FormGroups
|
|
141
|
+
FormArrays using numeric indexes
|
|
142
|
+
|
|
143
|
+
Example
|
|
144
|
+
const control = IntelliToolxHelper.getFormControl(this.form, 'address.street');
|
|
145
|
+
const item = IntelliToolxHelper.getFormControl(this.form, 'items.0.name');
|
|
146
|
+
|
|
147
|
+
## convertImageToBase64(file)
|
|
148
|
+
|
|
149
|
+
Converts an image file to a Base64 string.
|
|
150
|
+
|
|
151
|
+
static convertImageToBase64(file: File): Promise<string>
|
|
152
|
+
|
|
153
|
+
Example
|
|
154
|
+
const base64 = await IntelliToolxHelper.convertImageToBase64(file);
|
|
155
|
+
|
|
156
|
+
## replaceCharacter(text, replaceChar, replaceWithChar)
|
|
157
|
+
|
|
158
|
+
Replaces all occurrences of a character in a string.
|
|
159
|
+
|
|
160
|
+
static replaceCharacter(
|
|
161
|
+
text: any,
|
|
162
|
+
replaceChar: string,
|
|
163
|
+
replaceWithChar: string
|
|
164
|
+
): string
|
|
165
|
+
|
|
166
|
+
Example
|
|
167
|
+
IntelliToolxHelper.replaceCharacter('1-2-3', '-', ':');
|
|
168
|
+
// 1:2:3
|
|
169
|
+
|
|
170
|
+
## convertJsonStringToJson(value)
|
|
171
|
+
|
|
172
|
+
Safely converts a JSON string into an object.
|
|
173
|
+
|
|
174
|
+
static convertJsonStringToJson<T>(
|
|
175
|
+
value: T | string | null | undefined
|
|
176
|
+
): T | null
|
|
177
|
+
|
|
178
|
+
Behavior
|
|
179
|
+
Returns parsed object if valid JSON string
|
|
180
|
+
Returns original object if already parsed
|
|
181
|
+
Returns null if parsing fails
|
|
182
|
+
|
|
183
|
+
Example
|
|
184
|
+
const data = IntelliToolxHelper.convertJsonStringToJson<MyType>(jsonString);
|
|
185
|
+
|
|
186
|
+
### Usage Pattern (Recommended)
|
|
187
|
+
|
|
188
|
+
initialValue = IntelliToolxHelper.captureInitialValue(this.form);
|
|
189
|
+
|
|
190
|
+
save() {
|
|
191
|
+
IntelliToolxHelper.trimFormGroup(this.form);
|
|
192
|
+
|
|
193
|
+
if (!IntelliToolxHelper.formHasChanges(this.initialValue, this.form)) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// proceed with save
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
# IntellitoolxRegExps
|
|
201
|
+
|
|
202
|
+
A collection of commonly used regular expressions for validation in Angular and TypeScript applications.
|
|
203
|
+
|
|
204
|
+
Designed for:
|
|
205
|
+
Reactive Forms validation
|
|
206
|
+
Input sanitization
|
|
207
|
+
Reusable validation patterns
|
|
208
|
+
Consistent form behavior across projects
|
|
209
|
+
|
|
210
|
+
Import
|
|
211
|
+
import { IntellitoolxRegExps } from 'intellitoolx-helper';
|
|
212
|
+
|
|
213
|
+
Available Regular Expressions
|
|
214
|
+
|
|
215
|
+
## EMAIL_REGEX
|
|
216
|
+
|
|
217
|
+
EMAIL*REGEX: /^(?=.{1,50}$)[a-zA-Z0-9.*%+-]+@[a-zA-Z0-9.-]+\.[A-Za-z]{2,}$/
|
|
218
|
+
|
|
219
|
+
Validates an email address with:
|
|
220
|
+
Maximum length of 50 characters
|
|
221
|
+
Standard email format
|
|
222
|
+
Requires valid domain suffix (min 2 characters)
|
|
223
|
+
|
|
224
|
+
Valid Examples
|
|
225
|
+
test@example.com
|
|
226
|
+
user.name@mail-domain.org
|
|
227
|
+
info123@test.co
|
|
228
|
+
|
|
229
|
+
Invalid Examples
|
|
230
|
+
invalid-email
|
|
231
|
+
user@
|
|
232
|
+
@test.com
|
|
233
|
+
|
|
234
|
+
Usage (Angular Validator)
|
|
235
|
+
|
|
236
|
+
this.form = new FormGroup({
|
|
237
|
+
email: new FormControl('', [
|
|
238
|
+
Validators.pattern(IntellitoolxRegExps.EMAIL_REGEX),
|
|
239
|
+
]),
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
## NUMBER_REGEX
|
|
243
|
+
|
|
244
|
+
NUMBER_REGEX: /^\d+$/
|
|
245
|
+
|
|
246
|
+
Validates:
|
|
247
|
+
Whole numbers only
|
|
248
|
+
No decimals
|
|
249
|
+
No negative values
|
|
250
|
+
No spaces or characters
|
|
251
|
+
|
|
252
|
+
Valid Examples
|
|
253
|
+
1, 25, 99999
|
|
254
|
+
|
|
255
|
+
Invalid Examples
|
|
256
|
+
1.5, -10, abc
|
|
257
|
+
|
|
258
|
+
## AMOUNT_REGEX
|
|
259
|
+
|
|
260
|
+
AMOUNT_REGEX: /^\d+(\.\d{1,2})?$/
|
|
261
|
+
|
|
262
|
+
Validates monetary amounts:
|
|
263
|
+
Whole numbers
|
|
264
|
+
Optional decimal
|
|
265
|
+
Maximum 2 decimal places
|
|
266
|
+
|
|
267
|
+
Valid Examples
|
|
268
|
+
10, 10.5, 10.50, 9999.99
|
|
269
|
+
|
|
270
|
+
Invalid Examples
|
|
271
|
+
10., 10.999, abc
|
|
272
|
+
|
|
273
|
+
## DOMAIN_REGEX
|
|
274
|
+
|
|
275
|
+
DOMAIN_REGEX:
|
|
276
|
+
/^(?=.{1,255}$)(https?|ftp):\/\/([\w.-]+)\.([a-z\.]{2,6})(:[0-9]{1,5})?(\/\S*)?$/
|
|
277
|
+
|
|
278
|
+
Validates full URLs with:
|
|
279
|
+
http, https, or ftp protocol
|
|
280
|
+
|
|
281
|
+
Valid domain
|
|
282
|
+
Optional port
|
|
283
|
+
Optional path
|
|
284
|
+
Maximum length of 255 characters
|
|
285
|
+
|
|
286
|
+
Valid Examples
|
|
287
|
+
https://example.com, http://sub.domain.org, https://example.com:8080/path, ftp://files.server.net
|
|
288
|
+
|
|
289
|
+
Invalid Examples
|
|
290
|
+
example.com, http:/example.com, htp://domain.com
|
|
291
|
+
|
|
292
|
+
### Usage in Angular Reactive Forms
|
|
293
|
+
|
|
294
|
+
this.form = new FormGroup({
|
|
295
|
+
email: new FormControl('', [
|
|
296
|
+
Validators.pattern(IntellitoolxRegExps.EMAIL_REGEX),
|
|
297
|
+
]),
|
|
298
|
+
amount: new FormControl('', [
|
|
299
|
+
Validators.pattern(IntellitoolxRegExps.AMOUNT_REGEX),
|
|
300
|
+
]),
|
|
301
|
+
website: new FormControl('', [
|
|
302
|
+
Validators.pattern(IntellitoolxRegExps.DOMAIN_REGEX),
|
|
303
|
+
]),
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
# IntellitoolxFormUpdateMessage
|
|
307
|
+
|
|
308
|
+
A lightweight Angular standalone component that displays a configurable warning message when a form has no changes to save.
|
|
309
|
+
|
|
310
|
+
Designed to improve user experience by clearly informing users why an action (such as saving) cannot proceed.
|
|
311
|
+
|
|
312
|
+
## Import
|
|
313
|
+
|
|
314
|
+
import { IntellitoolxFormUpdateMessage } from 'intellitoolx-helper';
|
|
315
|
+
Because it is standalone, import it directly:
|
|
316
|
+
|
|
317
|
+
@Component({
|
|
318
|
+
standalone: true,
|
|
319
|
+
imports: [IntellitoolxFormUpdateMessage],
|
|
320
|
+
})
|
|
321
|
+
|
|
322
|
+
## Basic Usage
|
|
323
|
+
|
|
324
|
+
<itx-form-update-message></itx-form-update-message>
|
|
325
|
+
|
|
326
|
+
### Default message:
|
|
327
|
+
|
|
328
|
+
There are no changes to save. Please modify a field to continue.
|
|
329
|
+
With Configuration
|
|
330
|
+
|
|
331
|
+
Customize text and styling using itxFormUpdateMessageConfig.
|
|
332
|
+
|
|
333
|
+
<itx-form-update-message
|
|
334
|
+
[itxFormUpdateMessageConfig]="updateMessageConfig"
|
|
335
|
+
|
|
336
|
+
> </itx-form-update-message>
|
|
337
|
+
> updateMessageConfig = {
|
|
338
|
+
> message: 'Nothing changed yet.',
|
|
339
|
+
> textColor: '#0c5460',
|
|
340
|
+
> backgroundColor: '#d1ecf1',
|
|
341
|
+
> borderColor: '#bee5eb',
|
|
342
|
+
> };
|
|
343
|
+
|
|
344
|
+
## Configuration Interface
|
|
345
|
+
|
|
346
|
+
export interface IntellitoolxFormUpdateMessageConfig {
|
|
347
|
+
message?: string;
|
|
348
|
+
textColor?: string;
|
|
349
|
+
backgroundColor?: string;
|
|
350
|
+
borderColor?: string;
|
|
351
|
+
padding?: string;
|
|
352
|
+
iconAndMessageGap?: string;
|
|
353
|
+
borderRadius?: string;
|
|
354
|
+
fontWeight?: number | string;
|
|
355
|
+
iconSize?: string;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
All properties are optional.
|
|
359
|
+
|
|
360
|
+
## Default Styling Behavior
|
|
361
|
+
|
|
362
|
+
If no configuration is provided, the component uses accessible warning styles.
|
|
363
|
+
|
|
364
|
+
Property Default
|
|
365
|
+
text color #963C00
|
|
366
|
+
background #fff3cd
|
|
367
|
+
border #f3cd5a
|
|
368
|
+
padding 1rem
|
|
369
|
+
border radius 0.5rem
|
|
370
|
+
gap 0.5rem
|
|
371
|
+
font weight 400
|
|
372
|
+
icon size 1rem
|
|
373
|
+
Accessibility
|
|
374
|
+
|
|
375
|
+
Uses role="alert" to notify assistive technologies
|
|
376
|
+
Icon is hidden from screen readers with aria-hidden="true"
|
|
377
|
+
Provides clear visual contrast for warning context
|
|
378
|
+
|
|
379
|
+
Example: Show When No Changes Exist
|
|
380
|
+
<itx-form-update-message
|
|
381
|
+
\*ngIf="!formHasChanges"
|
|
382
|
+
|
|
383
|
+
> </itx-form-update-message>
|
|
384
|
+
> formHasChanges = false;
|
|
385
|
+
> Example: Integrating With IntelliToolxHelper
|
|
386
|
+
> hasChanges = IntelliToolxHelper.formHasChanges(this.initialValue, this.form);
|
|
387
|
+
> <itx-form-update-message
|
|
388
|
+
> *ngIf="!hasChanges"
|
|
389
|
+
> </itx-form-update-message>
|
|
390
|
+
|
|
391
|
+
## Theming Examples
|
|
392
|
+
|
|
393
|
+
Success Style
|
|
394
|
+
updateMessageConfig = {
|
|
395
|
+
message: 'No updates were made.',
|
|
396
|
+
textColor: '#155724',
|
|
397
|
+
backgroundColor: '#d4edda',
|
|
398
|
+
borderColor: '#c3e6cb',
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
Minimal Style
|
|
402
|
+
updateMessageConfig = {
|
|
403
|
+
backgroundColor: 'transparent',
|
|
404
|
+
borderColor: '#ddd',
|
|
405
|
+
textColor: '#555',
|
|
406
|
+
};
|
|
407
|
+
|
|
408
|
+
## When to Use
|
|
409
|
+
|
|
410
|
+
Use this component when:
|
|
411
|
+
A save/update action is triggered without changes
|
|
412
|
+
Preventing redundant submissions
|
|
413
|
+
Improving form UX clarity
|
|
414
|
+
Displaying inline form state feedback
|
|
415
|
+
|
|
416
|
+
# IntellitoolxFormErrors
|
|
417
|
+
|
|
418
|
+
A lightweight Angular standalone component for displaying reactive form validation errors with customizable and extensible error messages.
|
|
419
|
+
|
|
420
|
+
Built to:
|
|
421
|
+
standardize validation messages
|
|
422
|
+
support component-level overrides
|
|
423
|
+
allow global extension of error messages
|
|
424
|
+
simplify template error handling
|
|
425
|
+
|
|
426
|
+
Import
|
|
427
|
+
import { IntellitoolxFormErrors } from 'intellitoolx-helper';
|
|
428
|
+
|
|
429
|
+
You can import it directly into any component.
|
|
430
|
+
|
|
431
|
+
## Basic Usage
|
|
432
|
+
|
|
433
|
+
<input [formControl]="emailControl" />
|
|
434
|
+
<itx-form-errors [control]="emailControl"></itx-form-errors>
|
|
435
|
+
|
|
436
|
+
Errors will display automatically when:
|
|
437
|
+
control is touched
|
|
438
|
+
control is invalid
|
|
439
|
+
|
|
440
|
+
Default Supported Errors
|
|
441
|
+
The component includes built-in messages for common validators:
|
|
442
|
+
|
|
443
|
+
Error Key Message
|
|
444
|
+
required This field is required
|
|
445
|
+
email The email entered is invalid
|
|
446
|
+
minlength You must enter at least X characters
|
|
447
|
+
maxlength You must not enter more than X characters
|
|
448
|
+
pattern Your entry must match the required pattern
|
|
449
|
+
passwordMismatch Password and confirm password do not match
|
|
450
|
+
futureDate Future date is not allowed
|
|
451
|
+
duplicateEmail Each email must be unique
|
|
452
|
+
maxWords Exceeded maximum number of words
|
|
453
|
+
maxMonthYear Date is later than allowed
|
|
454
|
+
minMonthYear Date is earlier than allowed
|
|
455
|
+
exceededAllowedDateDifference Date difference can only be one month
|
|
456
|
+
exceededLeastDateAllowed Start date cannot be greater than end date
|
|
457
|
+
|
|
458
|
+
## Adding Control Labels (User-Friendly Messages)
|
|
459
|
+
|
|
460
|
+
<itx-form-errors
|
|
461
|
+
[control]="amountControl"
|
|
462
|
+
controlLabel="Amount"
|
|
463
|
+
|
|
464
|
+
> </itx-form-errors>
|
|
465
|
+
|
|
466
|
+
Example output:
|
|
467
|
+
Amount cannot be greater than 100
|
|
468
|
+
|
|
469
|
+
Component-Level Custom Messages
|
|
470
|
+
Override messages for a specific field.
|
|
471
|
+
|
|
472
|
+
componentValidation = {
|
|
473
|
+
required: { message: 'Email is mandatory' },
|
|
474
|
+
minlength: { message: 'Too short' },
|
|
475
|
+
};
|
|
476
|
+
|
|
477
|
+
<itx-form-errors
|
|
478
|
+
[control]="emailControl"
|
|
479
|
+
[componentValidation]="componentValidation"
|
|
480
|
+
|
|
481
|
+
> </itx-form-errors>
|
|
482
|
+
|
|
483
|
+
### Using Custom Validators with Messages
|
|
484
|
+
|
|
485
|
+
If your validator returns an object:
|
|
486
|
+
return { customMinValue: { message: 'Value is too small' } };
|
|
487
|
+
|
|
488
|
+
The component will display:
|
|
489
|
+
Value is too small
|
|
490
|
+
|
|
491
|
+
## Extending Error Messages (Recommended)
|
|
492
|
+
|
|
493
|
+
Consumers can extend the component to add global or shared messages.
|
|
494
|
+
|
|
495
|
+
### Option 1 — Extend the Component
|
|
496
|
+
|
|
497
|
+
Create your own reusable error component:
|
|
498
|
+
|
|
499
|
+
import { Component } from '@angular/core';
|
|
500
|
+
import { IntellitoolxFormErrors } from 'intellitoolx-helper';
|
|
501
|
+
|
|
502
|
+
@Component({
|
|
503
|
+
selector: 'app-form-errors',
|
|
504
|
+
standalone: true,
|
|
505
|
+
imports: [IntellitoolxFormErrors],
|
|
506
|
+
template: ` <itx-form-errors
|
|
507
|
+
[control]="control"
|
|
508
|
+
[componentValidation]="componentValidation"
|
|
509
|
+
[controlLabel]="controlLabel"
|
|
510
|
+
/>
|
|
511
|
+
`,
|
|
512
|
+
})
|
|
513
|
+
export class AppFormErrors extends IntellitoolxFormErrors {
|
|
514
|
+
override errorMessages = {
|
|
515
|
+
...this.errorMessages,
|
|
516
|
+
required: 'This field cannot be empty',
|
|
517
|
+
phone: 'Phone number is invalid',
|
|
518
|
+
usernameTaken: 'This username is already taken',
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
Now use:
|
|
523
|
+
<app-form-errors [control]="control"></app-form-errors>
|
|
524
|
+
|
|
525
|
+
### Option 2 — Extend via Custom Validator Keys
|
|
526
|
+
|
|
527
|
+
Return new error keys from validators:
|
|
528
|
+
|
|
529
|
+
return { usernameTaken: true };
|
|
530
|
+
|
|
531
|
+
Then provide the message:
|
|
532
|
+
|
|
533
|
+
componentValidation = {
|
|
534
|
+
usernameTaken: { message: 'Username already exists' },
|
|
535
|
+
};
|
|
536
|
+
|
|
537
|
+
### Option 3 — Global Shared Messages Service (Advanced)
|
|
538
|
+
|
|
539
|
+
Create a shared constant:
|
|
540
|
+
|
|
541
|
+
export const APP_ERROR_MESSAGES = {
|
|
542
|
+
required: 'Required field',
|
|
543
|
+
email: 'Invalid email address',
|
|
544
|
+
};
|
|
545
|
+
|
|
546
|
+
Then extend:
|
|
547
|
+
override errorMessages = {
|
|
548
|
+
...APP_ERROR_MESSAGES,
|
|
549
|
+
};
|
|
550
|
+
|
|
551
|
+
## Supported Error Value Types
|
|
552
|
+
|
|
553
|
+
The component intelligently handles different validator outputs:
|
|
554
|
+
|
|
555
|
+
Boolean
|
|
556
|
+
{ required: true }
|
|
557
|
+
→ uses default or custom message
|
|
558
|
+
|
|
559
|
+
String
|
|
560
|
+
{ customError: 'Invalid value provided' }
|
|
561
|
+
→ displays string directly
|
|
562
|
+
|
|
563
|
+
Object
|
|
564
|
+
{ minlength: { requiredLength: 5 } }
|
|
565
|
+
→ dynamic message rendering
|
|
566
|
+
|
|
567
|
+
Built-in Smart Messages
|
|
568
|
+
Pattern Errors
|
|
569
|
+
|
|
570
|
+
## Displays:
|
|
571
|
+
|
|
572
|
+
Please provide a valid {controlLabel}
|
|
573
|
+
Min / Max Validators
|
|
574
|
+
Age cannot be less than 18
|
|
575
|
+
Price cannot be greater than 100
|
|
576
|
+
Ngb Date Errors
|
|
577
|
+
Invalid date format provided
|
|
578
|
+
|
|
579
|
+
### Best Practices
|
|
580
|
+
|
|
581
|
+
✔ Always provide controlLabel for better UX
|
|
582
|
+
✔ Use componentValidation for field-specific overrides
|
|
583
|
+
✔ Extend the component for app-wide consistency
|
|
584
|
+
✔ Return structured error objects from custom validators
|
|
585
|
+
✔ Keep error keys consistent across the application
|
|
586
|
+
|
|
587
|
+
Example (Full Integration)
|
|
588
|
+
<input formControlName="email" />
|
|
589
|
+
|
|
590
|
+
<app-form-errors
|
|
591
|
+
[control]="form.controls.email"
|
|
592
|
+
controlLabel="Email Address"
|
|
593
|
+
|
|
594
|
+
> </app-form-errors>
|
|
595
|
+
|
|
596
|
+
# RequiredMarkerDirective
|
|
597
|
+
|
|
598
|
+
An Angular standalone directive that automatically adds a visual required marker to form labels when the associated form control has a required validator.
|
|
599
|
+
This ensures consistent UX and eliminates manual asterisk management.
|
|
600
|
+
|
|
601
|
+
## Import
|
|
602
|
+
|
|
603
|
+
import { RequiredMarkerDirective } from 'intellitoolx-helper';
|
|
604
|
+
|
|
605
|
+
Because it is standalone, import it directly:
|
|
606
|
+
|
|
607
|
+
@Component({
|
|
608
|
+
standalone: true,
|
|
609
|
+
imports: [RequiredMarkerDirective],
|
|
610
|
+
})
|
|
611
|
+
|
|
612
|
+
## Basic Usage
|
|
613
|
+
|
|
614
|
+
Add the directive to a <label> element.
|
|
615
|
+
|
|
616
|
+
<label for="email" itxRequired>Email</label>
|
|
617
|
+
<input id="email" formControlName="email" />
|
|
618
|
+
|
|
619
|
+
If the control has Validators.required, the output becomes:
|
|
620
|
+
Email \*
|
|
621
|
+
|
|
622
|
+
## How It Works
|
|
623
|
+
|
|
624
|
+
Reads the label’s for attribute.
|
|
625
|
+
Finds the matching control inside the parent FormGroup.
|
|
626
|
+
Checks for Validators.required.
|
|
627
|
+
Adds or removes the required marker dynamically.
|
|
628
|
+
Updates when value or status changes.
|
|
629
|
+
|
|
630
|
+
## Dynamic Updates
|
|
631
|
+
|
|
632
|
+
If required validation is added or removed at runtime:
|
|
633
|
+
control.setValidators([Validators.required]);
|
|
634
|
+
control.updateValueAndValidity();
|
|
635
|
+
The label updates automatically.
|
|
636
|
+
|
|
637
|
+
## Default Marker Behavior
|
|
638
|
+
|
|
639
|
+
Property Default
|
|
640
|
+
marker sign \*
|
|
641
|
+
color red
|
|
642
|
+
spacing 0.25rem
|
|
643
|
+
position after label text
|
|
644
|
+
Global Configuration
|
|
645
|
+
|
|
646
|
+
## You can configure marker appearance globally using the provided injection token.
|
|
647
|
+
|
|
648
|
+
Step 1 — Provide Configuration
|
|
649
|
+
import { REQUIRED_MARKER_GLOBAL_CONFIG } from 'intellitoolx-helper';
|
|
650
|
+
|
|
651
|
+
providers: [
|
|
652
|
+
{
|
|
653
|
+
provide: REQUIRED_MARKER_GLOBAL_CONFIG,
|
|
654
|
+
useValue: {
|
|
655
|
+
sign: '*',
|
|
656
|
+
color: '#d9534f',
|
|
657
|
+
spacing: '4px',
|
|
658
|
+
position: 'after', // 'before' | 'after'
|
|
659
|
+
},
|
|
660
|
+
},
|
|
661
|
+
];
|
|
662
|
+
|
|
663
|
+
Configuration Options
|
|
664
|
+
export interface ResolvedRequiredMarkerConfig {
|
|
665
|
+
sign: string;
|
|
666
|
+
color: string;
|
|
667
|
+
spacing: string;
|
|
668
|
+
position: 'before' | 'after';
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
Positioning the Marker
|
|
672
|
+
After (default)
|
|
673
|
+
Email \*
|
|
674
|
+
Before
|
|
675
|
+
position: 'before'
|
|
676
|
+
|
|
677
|
+
- Email
|
|
678
|
+
|
|
679
|
+
Preserves Additional Label Text
|
|
680
|
+
The directive preserves text in parentheses or suffix content.
|
|
681
|
+
<label for="dob" itxRequired>Date of Birth (optional)</label>
|
|
682
|
+
|
|
683
|
+
Output when required:
|
|
684
|
+
Date of Birth \* (optional)
|
|
685
|
+
Works With Nested Form Groups
|
|
686
|
+
Ensure the for attribute matches the control name.
|
|
687
|
+
<label for="address.street" itxRequired>Street</label>
|
|
688
|
+
<input formControlName="street" />
|
|
689
|
+
|
|
690
|
+
## Requirements
|
|
691
|
+
|
|
692
|
+
Must be used inside a form with FormGroupDirective
|
|
693
|
+
Label for attribute must match control name
|
|
694
|
+
|
|
695
|
+
## Common Mistakes
|
|
696
|
+
|
|
697
|
+
Missing for attribute
|
|
698
|
+
Label not associated with control
|
|
699
|
+
Control name mismatch
|
|
700
|
+
|
|
701
|
+
Example (Complete)
|
|
702
|
+
|
|
703
|
+
<form [formGroup]="form">
|
|
704
|
+
<label for="email" itxRequired>Email</label>
|
|
705
|
+
<input id="email" formControlName="email" />
|
|
706
|
+
</form>
|
|
707
|
+
email: new FormControl('', Validators.required);
|
|
708
|
+
|
|
709
|
+
# JsonParsePipe
|
|
710
|
+
|
|
711
|
+
An Angular standalone pipe that safely parses JSON strings into JavaScript objects.
|
|
712
|
+
|
|
713
|
+
Built on top of IntelliToolxHelper.convertJsonStringToJson, this pipe prevents template errors when dealing with dynamic or stringified JSON data.
|
|
714
|
+
|
|
715
|
+
## Import
|
|
716
|
+
|
|
717
|
+
import { JsonParsePipe } from 'intellitoolx-helper';
|
|
718
|
+
|
|
719
|
+
Because it is standalone, import it directly:
|
|
720
|
+
|
|
721
|
+
@Component({
|
|
722
|
+
standalone: true,
|
|
723
|
+
imports: [JsonParsePipe],
|
|
724
|
+
})
|
|
725
|
+
|
|
726
|
+
## Usage
|
|
727
|
+
|
|
728
|
+
Basic Example
|
|
729
|
+
{{ jsonString | jsonParse | json }}
|
|
730
|
+
|
|
731
|
+
Input
|
|
732
|
+
jsonString = '{"name":"John","age":30}';
|
|
733
|
+
|
|
734
|
+
Output
|
|
735
|
+
{
|
|
736
|
+
"name": "John",
|
|
737
|
+
"age": 30
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
## When to Use
|
|
741
|
+
|
|
742
|
+
Use jsonParse when:
|
|
743
|
+
API responses contain stringified JSON
|
|
744
|
+
Form values store serialized objects
|
|
745
|
+
LocalStorage data needs parsing
|
|
746
|
+
Preventing template crashes from invalid JSON
|
|
747
|
+
|
|
748
|
+
## Behavior
|
|
749
|
+
|
|
750
|
+
The pipe safely handles multiple input types:
|
|
751
|
+
|
|
752
|
+
Input Result
|
|
753
|
+
Valid JSON string Parsed object
|
|
754
|
+
Invalid JSON string null
|
|
755
|
+
Object Returned unchanged
|
|
756
|
+
null / undefined null
|
|
757
|
+
|
|
758
|
+
Examples
|
|
759
|
+
Parse API Data
|
|
760
|
+
|
|
761
|
+
<div *ngIf="user.data | jsonParse as parsed">
|
|
762
|
+
{{ parsed.name }}
|
|
763
|
+
</div>
|
|
764
|
+
|
|
765
|
+
Parse Stored JSON
|
|
766
|
+
{{ localStorageValue | jsonParse | json }}
|
|
767
|
+
|
|
768
|
+
Safe Access with Optional Chaining
|
|
769
|
+
{{ (settings | jsonParse)?.theme }}
|
|
770
|
+
|
|
771
|
+
Equivalent TypeScript Logic
|
|
772
|
+
|
|
773
|
+
The pipe internally performs:
|
|
774
|
+
IntelliToolxHelper.convertJsonStringToJson(value);
|
|
775
|
+
|
|
776
|
+
Error Safety
|
|
777
|
+
Unlike JSON.parse() directly in templates, this pipe:
|
|
778
|
+
prevents runtime template errors
|
|
779
|
+
avoids breaking change detection
|
|
780
|
+
returns null on parsing failure
|
|
781
|
+
|
|
782
|
+
For large datasets or repeated bindings:
|
|
783
|
+
Prefer parsing in the component
|
|
784
|
+
parsedData = IntelliToolxHelper.convertJsonStringToJson(data);
|
|
785
|
+
|
|
786
|
+
# IntelliToolx Validators
|
|
787
|
+
|
|
788
|
+
A set of reusable Angular Reactive Form validators designed for common business rules such as amount limits, password matching, word limits, and duplicate detection.
|
|
789
|
+
|
|
790
|
+
These validators integrate seamlessly with Angular forms and work perfectly with IntellitoolxFormErrors for displaying user-friendly messages.
|
|
791
|
+
|
|
792
|
+
Import
|
|
793
|
+
import {
|
|
794
|
+
customMaxAmountValidator,
|
|
795
|
+
customMinAmountValidator,
|
|
796
|
+
MaxWordsValidator,
|
|
797
|
+
PasswordMismatchValidator,
|
|
798
|
+
uniqueEmailsValidator
|
|
799
|
+
} from 'intellitoolx-helper';
|
|
800
|
+
|
|
801
|
+
## Validators Overview
|
|
802
|
+
|
|
803
|
+
Validator Purpose
|
|
804
|
+
customMaxAmountValidator Enforces maximum numeric value
|
|
805
|
+
customMinAmountValidator Enforces minimum numeric value
|
|
806
|
+
MaxWordsValidator Limits number of words
|
|
807
|
+
PasswordMismatchValidator Ensures password fields match
|
|
808
|
+
uniqueEmailsValidator Prevents duplicate emails in FormArray
|
|
809
|
+
|
|
810
|
+
## customMaxAmountValidator(maxValue)
|
|
811
|
+
|
|
812
|
+
Ensures a numeric value does not exceed a specified maximum.
|
|
813
|
+
customMaxAmountValidator(maxValue: number): ValidatorFn
|
|
814
|
+
|
|
815
|
+
Example
|
|
816
|
+
amount = new FormControl('', [
|
|
817
|
+
customMaxAmountValidator(1000)
|
|
818
|
+
]);
|
|
819
|
+
|
|
820
|
+
Error Output
|
|
821
|
+
{
|
|
822
|
+
customMaxValue: {
|
|
823
|
+
requiredMin: 1000,
|
|
824
|
+
actual: 1200,
|
|
825
|
+
message: "The value must not exceed 1000.00"
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
Notes
|
|
830
|
+
Accepts numeric values only
|
|
831
|
+
Returns a formatted error message
|
|
832
|
+
Works with IntellitoolxFormErrors automatically
|
|
833
|
+
|
|
834
|
+
## customMinAmountValidator(minValue)
|
|
835
|
+
|
|
836
|
+
Ensures a numeric value is at least the specified minimum.
|
|
837
|
+
customMinAmountValidator(minValue: number): ValidatorFn
|
|
838
|
+
|
|
839
|
+
Example
|
|
840
|
+
amount = new FormControl('', [
|
|
841
|
+
customMinAmountValidator(10)
|
|
842
|
+
]);
|
|
843
|
+
Error Output
|
|
844
|
+
{
|
|
845
|
+
customMinValue: {
|
|
846
|
+
requiredMin: 10,
|
|
847
|
+
actual: 5,
|
|
848
|
+
message: "The value must be at least 10.00"
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
## MaxWordsValidator(maxWords)
|
|
853
|
+
|
|
854
|
+
Limits the number of words in a text input.
|
|
855
|
+
MaxWordsValidator(maxWords: number): ValidatorFn
|
|
856
|
+
|
|
857
|
+
Example
|
|
858
|
+
description = new FormControl('', [
|
|
859
|
+
MaxWordsValidator(20)
|
|
860
|
+
]);
|
|
861
|
+
|
|
862
|
+
### Behavior
|
|
863
|
+
|
|
864
|
+
Ignores extra whitespace
|
|
865
|
+
Counts words separated by spaces
|
|
866
|
+
|
|
867
|
+
Error Output
|
|
868
|
+
{
|
|
869
|
+
maxWords: {
|
|
870
|
+
actual: 25,
|
|
871
|
+
max: 20
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
## PasswordMismatchValidator(controlName, matchingControlName)
|
|
876
|
+
|
|
877
|
+
Validates that two form fields match (commonly used for password confirmation).
|
|
878
|
+
PasswordMismatchValidator(
|
|
879
|
+
controlName: string,
|
|
880
|
+
matchingControlName: string
|
|
881
|
+
)
|
|
882
|
+
|
|
883
|
+
Example
|
|
884
|
+
this.form = new FormGroup(
|
|
885
|
+
{
|
|
886
|
+
password: new FormControl(''),
|
|
887
|
+
confirmPassword: new FormControl('')
|
|
888
|
+
},
|
|
889
|
+
{
|
|
890
|
+
validators: PasswordMismatchValidator('password', 'confirmPassword')
|
|
891
|
+
}
|
|
892
|
+
);
|
|
893
|
+
|
|
894
|
+
Error Output
|
|
895
|
+
{ passwordMismatch: true }
|
|
896
|
+
|
|
897
|
+
Notes
|
|
898
|
+
Error is applied to the matching control
|
|
899
|
+
Ideal for password confirmation fields
|
|
900
|
+
|
|
901
|
+
## uniqueEmailsValidator()
|
|
902
|
+
|
|
903
|
+
Ensures all email addresses inside a FormArray are unique.
|
|
904
|
+
uniqueEmailsValidator(): ValidatorFn
|
|
905
|
+
|
|
906
|
+
Example
|
|
907
|
+
this.form = new FormGroup({
|
|
908
|
+
contacts: new FormArray([
|
|
909
|
+
new FormGroup({
|
|
910
|
+
email: new FormControl('')
|
|
911
|
+
})
|
|
912
|
+
])
|
|
913
|
+
});
|
|
914
|
+
|
|
915
|
+
this.contacts.setValidators(uniqueEmailsValidator());
|
|
916
|
+
|
|
917
|
+
### Behavior
|
|
918
|
+
|
|
919
|
+
Ignores case and whitespace
|
|
920
|
+
Flags duplicates automatically
|
|
921
|
+
Updates errors dynamically
|
|
922
|
+
|
|
923
|
+
Error Output (control level)
|
|
924
|
+
{ duplicateEmail: true }
|
|
925
|
+
Error Output (form array level)
|
|
926
|
+
{ duplicateEmails: true }
|
|
927
|
+
|
|
928
|
+
### Integration with IntellitoolxFormErrors
|
|
929
|
+
|
|
930
|
+
These validators return error keys compatible with the error component:
|
|
931
|
+
Validator Error Key
|
|
932
|
+
customMaxAmountValidator customMaxValue
|
|
933
|
+
customMinAmountValidator customMinValue
|
|
934
|
+
MaxWordsValidator maxWords
|
|
935
|
+
PasswordMismatchValidator passwordMismatch
|
|
936
|
+
uniqueEmailsValidator duplicateEmail
|
|
937
|
+
|
|
938
|
+
### Best Practices
|
|
939
|
+
|
|
940
|
+
✔ Use with Reactive Forms only
|
|
941
|
+
✔ Combine with required validators when necessary
|
|
942
|
+
✔ Provide control labels for better error messages
|
|
943
|
+
✔ Normalize numeric inputs before validation
|
|
944
|
+
✔ Use FormArray validators for dynamic lists
|
|
945
|
+
|
|
946
|
+
### Complete Example
|
|
947
|
+
|
|
948
|
+
this.form = new FormGroup({
|
|
949
|
+
amount: new FormControl('', [
|
|
950
|
+
customMinAmountValidator(10),
|
|
951
|
+
customMaxAmountValidator(1000),
|
|
952
|
+
]),
|
|
953
|
+
description: new FormControl('', [
|
|
954
|
+
MaxWordsValidator(20)
|
|
955
|
+
]),
|
|
956
|
+
});
|
|
957
|
+
|
|
958
|
+
License
|
|
959
|
+
MIT
|