@fagon/ngx-intellitoolx 16.0.5 → 16.0.6
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/README.md
CHANGED
|
@@ -680,12 +680,6 @@ The component intelligently handles different validator outputs:
|
|
|
680
680
|
- String { customError: 'Invalid value provided' } → displays string directly
|
|
681
681
|
- Object { minlength: { requiredLength: 5 } } → dynamic message rendering
|
|
682
682
|
|
|
683
|
-
Built-in Smart Messages
|
|
684
|
-
|
|
685
|
-
- Pattern Errors Display: `Please provide a valid {controlLabel}`
|
|
686
|
-
- Min / Max Validators Display: `Age cannot be less than 18` / `Price cannot be greater than 100`
|
|
687
|
-
- Ngb Date Errors Display: `Invalid date format provided`
|
|
688
|
-
|
|
689
683
|
Best Practices
|
|
690
684
|
|
|
691
685
|
- Always provide controlLabel for better UX
|
|
@@ -1149,23 +1143,22 @@ this.form = new FormGroup({
|
|
|
1149
1143
|
# Unsaved Changes Protection
|
|
1150
1144
|
|
|
1151
1145
|
Protect Angular routes and modals from accidental navigation or closing when there are unsaved changes.
|
|
1152
|
-
|
|
1153
1146
|
Supports:
|
|
1154
1147
|
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1148
|
+
1. Angular route navigation
|
|
1149
|
+
2. Browser back button
|
|
1150
|
+
3. Browser refresh / tab close
|
|
1151
|
+
4. Modal close (NG Bootstrap / Material / custom)
|
|
1152
|
+
5. Parent + child component setups
|
|
1153
|
+
6. Nested forms
|
|
1161
1154
|
|
|
1162
|
-
|
|
1155
|
+
### The system is built around three core pieces:
|
|
1163
1156
|
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1157
|
+
1. FormChangesTrackerService
|
|
1158
|
+
2. UnsavedChangesGuard
|
|
1159
|
+
3. CanComponentDeactivate interface (for route protection)
|
|
1167
1160
|
|
|
1168
|
-
|
|
1161
|
+
Architecture:
|
|
1169
1162
|
|
|
1170
1163
|
```
|
|
1171
1164
|
Form → TrackerService → Guard → Confirmation → Continue / Block
|
|
@@ -1173,16 +1166,316 @@ Form → TrackerService → Guard → Confirmation → Continue / Block
|
|
|
1173
1166
|
|
|
1174
1167
|
The library does NOT depend on your UI layer.
|
|
1175
1168
|
Your app controls the confirmation modal.
|
|
1169
|
+
Core Exports
|
|
1170
|
+
|
|
1171
|
+
```ts
|
|
1172
|
+
import { FormChangesTrackerService, UnsavedChangesGuard, CanComponentDeactivate } from "ngx-intellitoolx";
|
|
1173
|
+
```
|
|
1174
|
+
|
|
1175
|
+
## FormChangesTrackerService API
|
|
1176
|
+
|
|
1177
|
+
The FormChangesTrackerService tracks changes in Angular forms and provides methods for managing form state across your application.
|
|
1178
|
+
|
|
1179
|
+
1. Single Form Operations
|
|
1180
|
+
|
|
1181
|
+
### register(form)
|
|
1182
|
+
|
|
1183
|
+
Registers a single form for change tracking.
|
|
1184
|
+
|
|
1185
|
+
```ts
|
|
1186
|
+
register(form: AbstractControl): void
|
|
1187
|
+
```
|
|
1188
|
+
|
|
1189
|
+
Behavior:
|
|
1190
|
+
|
|
1191
|
+
- Captures the current form value as the initial state
|
|
1192
|
+
- Marks the form as pristine
|
|
1193
|
+
- Stores the form reference for change detection
|
|
1194
|
+
|
|
1195
|
+
Example:
|
|
1196
|
+
|
|
1197
|
+
```ts
|
|
1198
|
+
ngOnInit() {
|
|
1199
|
+
this.form = this.fb.group({
|
|
1200
|
+
name: [''],
|
|
1201
|
+
email: ['']
|
|
1202
|
+
});
|
|
1203
|
+
|
|
1204
|
+
this.tracker.register(this.form);
|
|
1205
|
+
}
|
|
1206
|
+
```
|
|
1207
|
+
|
|
1208
|
+
### reset(form)
|
|
1209
|
+
|
|
1210
|
+
Resets the tracked initial value to the current form value.
|
|
1211
|
+
|
|
1212
|
+
```ts
|
|
1213
|
+
reset(form: AbstractControl): void
|
|
1214
|
+
```
|
|
1215
|
+
|
|
1216
|
+
Use Case: After patching form data from an API, reset the tracker to prevent false positives.
|
|
1217
|
+
Example:
|
|
1218
|
+
|
|
1219
|
+
```ts
|
|
1220
|
+
loadData() {
|
|
1221
|
+
this.api.getData().subscribe(data => {
|
|
1222
|
+
this.form.patchValue(data);
|
|
1223
|
+
// Reset tracker after patching to track only future changes
|
|
1224
|
+
this.tracker.reset(this.form);
|
|
1225
|
+
});
|
|
1226
|
+
}
|
|
1227
|
+
```
|
|
1228
|
+
|
|
1229
|
+
### unregister(form)
|
|
1230
|
+
|
|
1231
|
+
Removes a form from the tracker.
|
|
1232
|
+
|
|
1233
|
+
```ts
|
|
1234
|
+
unregister(form: AbstractControl): void
|
|
1235
|
+
```
|
|
1236
|
+
|
|
1237
|
+
Example:
|
|
1238
|
+
|
|
1239
|
+
```ts
|
|
1240
|
+
ngOnDestroy() {
|
|
1241
|
+
this.tracker.unregister(this.form);
|
|
1242
|
+
}
|
|
1243
|
+
```
|
|
1244
|
+
|
|
1245
|
+
### hasChanges()
|
|
1246
|
+
|
|
1247
|
+
Checks if any tracked form has unsaved changes.
|
|
1248
|
+
|
|
1249
|
+
```ts
|
|
1250
|
+
hasChanges(): boolean
|
|
1251
|
+
```
|
|
1252
|
+
|
|
1253
|
+
Returns: true if any tracked form has changes, false otherwise.
|
|
1254
|
+
Example:
|
|
1255
|
+
|
|
1256
|
+
```ts
|
|
1257
|
+
if (this.tracker.hasChanges()) {
|
|
1258
|
+
// Show confirmation modal
|
|
1259
|
+
}
|
|
1260
|
+
```
|
|
1261
|
+
|
|
1262
|
+
### clearAll()
|
|
1263
|
+
|
|
1264
|
+
Removes all forms from the tracker.
|
|
1265
|
+
|
|
1266
|
+
```ts
|
|
1267
|
+
clearAll(): void
|
|
1268
|
+
```
|
|
1269
|
+
|
|
1270
|
+
Example:
|
|
1271
|
+
|
|
1272
|
+
```ts
|
|
1273
|
+
ngOnDestroy() {
|
|
1274
|
+
this.tracker.clearAll();
|
|
1275
|
+
}
|
|
1276
|
+
```
|
|
1277
|
+
|
|
1278
|
+
2. Batch Operations
|
|
1279
|
+
For applications with multiple forms that need to be managed together, the service provides batch methods.
|
|
1280
|
+
|
|
1281
|
+
### registerForms(forms)
|
|
1282
|
+
|
|
1283
|
+
Registers multiple forms at once for change tracking.
|
|
1284
|
+
|
|
1285
|
+
```ts
|
|
1286
|
+
registerForms(forms: AbstractControl[]): void
|
|
1287
|
+
```
|
|
1288
|
+
|
|
1289
|
+
Use Case:
|
|
1290
|
+
|
|
1291
|
+
- Multi-step forms
|
|
1292
|
+
- Forms in tabs
|
|
1293
|
+
- Parent component managing multiple child forms
|
|
1294
|
+
|
|
1295
|
+
Example:
|
|
1296
|
+
|
|
1297
|
+
```ts
|
|
1298
|
+
ngOnInit() {
|
|
1299
|
+
this.personalInfoForm = this.fb.group({
|
|
1300
|
+
firstName: [''],
|
|
1301
|
+
lastName: ['']
|
|
1302
|
+
});
|
|
1303
|
+
|
|
1304
|
+
this.contactForm = this.fb.group({
|
|
1305
|
+
email: [''],
|
|
1306
|
+
phone: ['']
|
|
1307
|
+
});
|
|
1308
|
+
|
|
1309
|
+
this.addressForm = this.fb.group({
|
|
1310
|
+
street: [''],
|
|
1311
|
+
city: ['']
|
|
1312
|
+
});
|
|
1313
|
+
|
|
1314
|
+
// Register all forms at once
|
|
1315
|
+
this.tracker.registerForms([
|
|
1316
|
+
this.personalInfoForm,
|
|
1317
|
+
this.contactForm,
|
|
1318
|
+
this.addressForm
|
|
1319
|
+
]);
|
|
1320
|
+
}
|
|
1321
|
+
```
|
|
1322
|
+
|
|
1323
|
+
### resetForms(forms)
|
|
1324
|
+
|
|
1325
|
+
Resets multiple forms to their current values, useful after batch updates or API calls.
|
|
1176
1326
|
|
|
1177
|
-
|
|
1327
|
+
```ts
|
|
1328
|
+
resetForms(forms: AbstractControl[]): void
|
|
1329
|
+
```
|
|
1330
|
+
|
|
1331
|
+
Use Case:
|
|
1332
|
+
|
|
1333
|
+
- After loading data into multiple forms
|
|
1334
|
+
- After bulk form updates
|
|
1335
|
+
- Resetting multiple wizard steps
|
|
1336
|
+
|
|
1337
|
+
Example:
|
|
1178
1338
|
|
|
1179
1339
|
```ts
|
|
1180
|
-
|
|
1340
|
+
loadAllData() {
|
|
1341
|
+
this.api.getUserData().subscribe(data => {
|
|
1342
|
+
this.personalInfoForm.patchValue(data.personal);
|
|
1343
|
+
this.contactForm.patchValue(data.contact);
|
|
1344
|
+
this.addressForm.patchValue(data.address);
|
|
1345
|
+
|
|
1346
|
+
// Reset all forms after patching
|
|
1347
|
+
this.tracker.resetForms([
|
|
1348
|
+
this.personalInfoForm,
|
|
1349
|
+
this.contactForm,
|
|
1350
|
+
this.addressForm
|
|
1351
|
+
]);
|
|
1352
|
+
});
|
|
1353
|
+
}
|
|
1181
1354
|
```
|
|
1182
1355
|
|
|
1183
|
-
###
|
|
1356
|
+
### unregisterForms(forms)
|
|
1184
1357
|
|
|
1185
|
-
|
|
1358
|
+
Removes multiple forms from the tracker at once.
|
|
1359
|
+
|
|
1360
|
+
```ts
|
|
1361
|
+
unregisterForms(forms: AbstractControl[]): void
|
|
1362
|
+
```
|
|
1363
|
+
|
|
1364
|
+
Use Case:
|
|
1365
|
+
|
|
1366
|
+
- Component cleanup with multiple forms
|
|
1367
|
+
- Dynamically removing form sections
|
|
1368
|
+
- Batch cleanup in parent components
|
|
1369
|
+
|
|
1370
|
+
Example:
|
|
1371
|
+
|
|
1372
|
+
```ts
|
|
1373
|
+
ngOnDestroy() {
|
|
1374
|
+
// Unregister all forms at once
|
|
1375
|
+
this.tracker.unregisterForms([
|
|
1376
|
+
this.personalInfoForm,
|
|
1377
|
+
this.contactForm,
|
|
1378
|
+
this.addressForm
|
|
1379
|
+
]);
|
|
1380
|
+
}
|
|
1381
|
+
```
|
|
1382
|
+
|
|
1383
|
+
### Complete Multi-Form Example
|
|
1384
|
+
|
|
1385
|
+
```ts
|
|
1386
|
+
import { Component, OnInit, OnDestroy } from "@angular/core";
|
|
1387
|
+
import { FormBuilder, FormGroup } from "@angular/forms";
|
|
1388
|
+
import { FormChangesTrackerService } from "ngx-intellitoolx";
|
|
1389
|
+
|
|
1390
|
+
@Component({
|
|
1391
|
+
selector: "app-user-profile",
|
|
1392
|
+
templateUrl: "./user-profile.component.html",
|
|
1393
|
+
})
|
|
1394
|
+
export class UserProfileComponent implements OnInit, OnDestroy {
|
|
1395
|
+
personalForm!: FormGroup;
|
|
1396
|
+
contactForm!: FormGroup;
|
|
1397
|
+
preferencesForm!: FormGroup;
|
|
1398
|
+
|
|
1399
|
+
constructor(
|
|
1400
|
+
private fb: FormBuilder,
|
|
1401
|
+
private tracker: FormChangesTrackerService,
|
|
1402
|
+
private api: UserApiService,
|
|
1403
|
+
) {}
|
|
1404
|
+
|
|
1405
|
+
ngOnInit() {
|
|
1406
|
+
// Create multiple forms
|
|
1407
|
+
this.personalForm = this.fb.group({
|
|
1408
|
+
firstName: [""],
|
|
1409
|
+
lastName: [""],
|
|
1410
|
+
dateOfBirth: [""],
|
|
1411
|
+
});
|
|
1412
|
+
|
|
1413
|
+
this.contactForm = this.fb.group({
|
|
1414
|
+
email: [""],
|
|
1415
|
+
phone: [""],
|
|
1416
|
+
address: [""],
|
|
1417
|
+
});
|
|
1418
|
+
|
|
1419
|
+
this.preferencesForm = this.fb.group({
|
|
1420
|
+
newsletter: [false],
|
|
1421
|
+
notifications: [false],
|
|
1422
|
+
theme: ["light"],
|
|
1423
|
+
});
|
|
1424
|
+
|
|
1425
|
+
// Register all forms at once
|
|
1426
|
+
this.tracker.registerForms([this.personalForm, this.contactForm, this.preferencesForm]);
|
|
1427
|
+
|
|
1428
|
+
// Load data
|
|
1429
|
+
this.loadUserData();
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1432
|
+
loadUserData() {
|
|
1433
|
+
this.api.getUserProfile().subscribe((data) => {
|
|
1434
|
+
this.personalForm.patchValue(data.personal);
|
|
1435
|
+
this.contactForm.patchValue(data.contact);
|
|
1436
|
+
this.preferencesForm.patchValue(data.preferences);
|
|
1437
|
+
|
|
1438
|
+
// Reset all trackers after loading
|
|
1439
|
+
this.tracker.resetForms([this.personalForm, this.contactForm, this.preferencesForm]);
|
|
1440
|
+
});
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
saveAll() {
|
|
1444
|
+
if (!this.tracker.hasChanges()) {
|
|
1445
|
+
console.log("No changes to save");
|
|
1446
|
+
return;
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
const allData = {
|
|
1450
|
+
personal: this.personalForm.value,
|
|
1451
|
+
contact: this.contactForm.value,
|
|
1452
|
+
preferences: this.preferencesForm.value,
|
|
1453
|
+
};
|
|
1454
|
+
|
|
1455
|
+
this.api.updateProfile(allData).subscribe(() => {
|
|
1456
|
+
// Reset all forms after successful save
|
|
1457
|
+
this.tracker.resetForms([this.personalForm, this.contactForm, this.preferencesForm]);
|
|
1458
|
+
});
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1461
|
+
ngOnDestroy() {
|
|
1462
|
+
// Clean up all forms at once
|
|
1463
|
+
this.tracker.unregisterForms([this.personalForm, this.contactForm, this.preferencesForm]);
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
```
|
|
1467
|
+
|
|
1468
|
+
### Best Practices
|
|
1469
|
+
|
|
1470
|
+
1. Always unregister forms in ngOnDestroy() to prevent memory leaks
|
|
1471
|
+
2. Use clearAll() when component manages all tracked forms
|
|
1472
|
+
3. Reset after API loads to establish the correct baseline for change detection
|
|
1473
|
+
4. Batch operations improve code readability when managing multiple forms
|
|
1474
|
+
5. Call markAsPristine() after successful saves (handled automatically by `reset()` and `resetForms()`)
|
|
1475
|
+
|
|
1476
|
+
## Protecting Angular Routes
|
|
1477
|
+
|
|
1478
|
+
### Add Guard to Route
|
|
1186
1479
|
|
|
1187
1480
|
```ts
|
|
1188
1481
|
{
|
|
@@ -1194,10 +1487,10 @@ Add Guard to Route
|
|
|
1194
1487
|
|
|
1195
1488
|
### Implement Route Component
|
|
1196
1489
|
|
|
1197
|
-
Your routed component must implement CanComponentDeactivate.
|
|
1490
|
+
Your routed component must implement CanComponentDeactivate. This is not related to the library, as the modal trigger logic exists entirely outside the library's scope.
|
|
1198
1491
|
|
|
1199
1492
|
```ts
|
|
1200
|
-
import {
|
|
1493
|
+
import { FormChangesTrackerService } from "ngx-intellitoolx";
|
|
1201
1494
|
import { UtilityService } from "../services/utility.service";
|
|
1202
1495
|
|
|
1203
1496
|
@Component({
|
|
@@ -1205,10 +1498,7 @@ import { UtilityService } from "../services/utility.service";
|
|
|
1205
1498
|
template: `<app-item-form></app-item-form>`,
|
|
1206
1499
|
})
|
|
1207
1500
|
export class AddItemPageComponent implements CanComponentDeactivate {
|
|
1208
|
-
constructor(
|
|
1209
|
-
private tracker: UnsavedChangesTrackerService,
|
|
1210
|
-
private utils: UtilityService,
|
|
1211
|
-
) {}
|
|
1501
|
+
constructor(private utils: UtilityService) {}
|
|
1212
1502
|
|
|
1213
1503
|
confirmUnsavedChanges(): Promise<boolean> {
|
|
1214
1504
|
return this.utils.confirmUnsavedChanges();
|
|
@@ -1228,7 +1518,7 @@ export class ItemFormComponent implements OnInit {
|
|
|
1228
1518
|
|
|
1229
1519
|
constructor(
|
|
1230
1520
|
private fb: FormBuilder,
|
|
1231
|
-
private tracker:
|
|
1521
|
+
private tracker: FormChangesTrackerService,
|
|
1232
1522
|
) {}
|
|
1233
1523
|
|
|
1234
1524
|
ngOnInit(): void {
|
|
@@ -1240,44 +1530,61 @@ export class ItemFormComponent implements OnInit {
|
|
|
1240
1530
|
this.tracker.register(this.form);
|
|
1241
1531
|
}
|
|
1242
1532
|
|
|
1533
|
+
patchForm() {
|
|
1534
|
+
this.form.patchValue({
|
|
1535
|
+
name: this.data.name,
|
|
1536
|
+
description: this.data.description,
|
|
1537
|
+
});
|
|
1538
|
+
// reset form after patching to track changes afterwards.
|
|
1539
|
+
// Very useful during form update
|
|
1540
|
+
this.tracker.reset(this.form);
|
|
1541
|
+
}
|
|
1542
|
+
|
|
1243
1543
|
save(): void {
|
|
1244
1544
|
// API call
|
|
1245
|
-
this.tracker.markAsPristine();
|
|
1246
1545
|
this.form.markAsPristine();
|
|
1247
1546
|
}
|
|
1547
|
+
|
|
1548
|
+
ngOnDestroy(): void {
|
|
1549
|
+
// This is very important to not keep track of forms from other component
|
|
1550
|
+
this.tracker.clearAll();
|
|
1551
|
+
}
|
|
1248
1552
|
}
|
|
1249
1553
|
```
|
|
1250
1554
|
|
|
1251
|
-
|
|
1555
|
+
## Protecting Browser Refresh / Tab Close
|
|
1252
1556
|
|
|
1253
|
-
Add this inside the routed component:
|
|
1557
|
+
### Add this inside the routed component:
|
|
1254
1558
|
|
|
1255
1559
|
```ts
|
|
1560
|
+
// Declare cleanup callback
|
|
1256
1561
|
private unregister?: () => void;
|
|
1257
1562
|
|
|
1258
1563
|
constructor(
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1564
|
+
private tracker: FormChangesTrackerService,
|
|
1565
|
+
public utilservice: UtilityService
|
|
1566
|
+
) {
|
|
1567
|
+
super();
|
|
1568
|
+
}
|
|
1264
1569
|
|
|
1265
1570
|
ngOnInit() {
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1571
|
+
// Register a beforeunload handler to prevent or warn about navigation when there are unsaved changes.
|
|
1572
|
+
this.unregister = IntelliToolxHelper.registerBeforeUnload(() =>
|
|
1573
|
+
this.tracker.hasChanges(),
|
|
1574
|
+
);
|
|
1269
1575
|
}
|
|
1270
1576
|
|
|
1271
1577
|
confirmUnsavedChanges(): Promise<boolean> {
|
|
1272
|
-
|
|
1273
|
-
|
|
1578
|
+
return this.utilservice.confirmUnsavedChanges();
|
|
1579
|
+
}
|
|
1274
1580
|
|
|
1275
1581
|
ngOnDestroy() {
|
|
1276
|
-
|
|
1582
|
+
// Safely invokes the teardown/unsubscribe callback if it exists.
|
|
1583
|
+
this.unregister?.();
|
|
1277
1584
|
}
|
|
1278
1585
|
```
|
|
1279
1586
|
|
|
1280
|
-
|
|
1587
|
+
## Protecting Modals (NG Bootstrap Example)
|
|
1281
1588
|
|
|
1282
1589
|
Route guards do NOT protect modals.
|
|
1283
1590
|
You must intercept modal close manually.
|
|
@@ -1286,7 +1593,7 @@ Modal Form Component
|
|
|
1286
1593
|
|
|
1287
1594
|
```ts
|
|
1288
1595
|
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
|
1289
|
-
import {
|
|
1596
|
+
import { FormChangesTrackerService } from "ngx-intellitoolx";
|
|
1290
1597
|
import { UtilityService } from "../utility.service";
|
|
1291
1598
|
|
|
1292
1599
|
@Component({
|
|
@@ -1298,7 +1605,7 @@ export class ItemModalComponent implements OnInit {
|
|
|
1298
1605
|
|
|
1299
1606
|
constructor(
|
|
1300
1607
|
private fb: FormBuilder,
|
|
1301
|
-
private tracker:
|
|
1608
|
+
private tracker: FormChangesTrackerService,
|
|
1302
1609
|
private utils: UtilityService,
|
|
1303
1610
|
public activeModal: NgbActiveModal,
|
|
1304
1611
|
) {}
|
|
@@ -1309,34 +1616,31 @@ export class ItemModalComponent implements OnInit {
|
|
|
1309
1616
|
description: [""],
|
|
1310
1617
|
});
|
|
1311
1618
|
|
|
1312
|
-
this.
|
|
1313
|
-
if (this.form.dirty) {
|
|
1314
|
-
this.tracker.markAsDirty();
|
|
1315
|
-
}
|
|
1316
|
-
});
|
|
1619
|
+
this.tracker.register(this.form);
|
|
1317
1620
|
}
|
|
1318
1621
|
|
|
1319
1622
|
async closeModal() {
|
|
1320
1623
|
if (this.tracker.hasChanges()) {
|
|
1321
|
-
const
|
|
1322
|
-
|
|
1323
|
-
if (!confirmed) {
|
|
1324
|
-
return; // cancel close
|
|
1325
|
-
}
|
|
1624
|
+
const allowClose = await IntelliToolxHelper.confirmIfChanged(this.tracker.hasChanges(), () => this.utilsService.confirmUnsavedChanges());
|
|
1625
|
+
if (!allowClose) return;
|
|
1326
1626
|
}
|
|
1327
1627
|
|
|
1328
1628
|
this.activeModal.dismiss();
|
|
1329
1629
|
}
|
|
1330
1630
|
|
|
1331
1631
|
save(): void {
|
|
1332
|
-
this.tracker.markAsPristine();
|
|
1333
1632
|
this.form.markAsPristine();
|
|
1334
1633
|
this.activeModal.close("saved");
|
|
1335
1634
|
}
|
|
1635
|
+
|
|
1636
|
+
ngOnDestroy(): void {
|
|
1637
|
+
// This is very important to not keep track of forms from other component
|
|
1638
|
+
this.tracker.clearAll();
|
|
1639
|
+
}
|
|
1336
1640
|
}
|
|
1337
1641
|
```
|
|
1338
1642
|
|
|
1339
|
-
|
|
1643
|
+
Modal Template
|
|
1340
1644
|
|
|
1341
1645
|
```html
|
|
1342
1646
|
<div class="modal-header">
|
|
@@ -1358,7 +1662,7 @@ export class ItemModalComponent implements OnInit {
|
|
|
1358
1662
|
</div>
|
|
1359
1663
|
```
|
|
1360
1664
|
|
|
1361
|
-
|
|
1665
|
+
## How It Works
|
|
1362
1666
|
|
|
1363
1667
|
| Action | What Happens |
|
|
1364
1668
|
| -------------------- | --------------------- |
|
|
@@ -1368,7 +1672,7 @@ export class ItemModalComponent implements OnInit {
|
|
|
1368
1672
|
| User closes modal | Manual interception |
|
|
1369
1673
|
| User saves form | Tracker resets |
|
|
1370
1674
|
|
|
1371
|
-
|
|
1675
|
+
### Parent + Child Structure
|
|
1372
1676
|
|
|
1373
1677
|
If your form is nested:
|
|
1374
1678
|
|
|
@@ -1384,14 +1688,7 @@ Route component → implements guard interface
|
|
|
1384
1688
|
Modal → manually checks tracker before close
|
|
1385
1689
|
```
|
|
1386
1690
|
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
- Always call markAsPristine() after successful save
|
|
1390
|
-
- Always intercept modal close
|
|
1391
|
-
- Keep confirmation UI inside the consuming app
|
|
1392
|
-
- Do not couple library to UI services
|
|
1393
|
-
|
|
1394
|
-
** Confirmation Modal Example (App Layer) **
|
|
1691
|
+
### Confirmation Modal Example (App Layer)
|
|
1395
1692
|
|
|
1396
1693
|
```ts
|
|
1397
1694
|
@Injectable({ providedIn: "root" })
|
|
@@ -1413,3 +1710,5 @@ export class UtilityService {
|
|
|
1413
1710
|
```
|
|
1414
1711
|
MIT © Fagon Technologies
|
|
1415
1712
|
```
|
|
1713
|
+
|
|
1714
|
+
[REPO]: https://github.com/Nana-Darko-Ampem/ngx-intellitoolx
|
|
@@ -12,6 +12,9 @@ export class FormChangesTrackerService {
|
|
|
12
12
|
});
|
|
13
13
|
form.markAsPristine();
|
|
14
14
|
}
|
|
15
|
+
registerForms(forms) {
|
|
16
|
+
forms.forEach((form) => this.register(form));
|
|
17
|
+
}
|
|
15
18
|
hasChanges() {
|
|
16
19
|
// We iterate over entries [form, metadata]
|
|
17
20
|
for (const [form, { initialValue }] of this.trackedForms.entries()) {
|
|
@@ -24,14 +27,22 @@ export class FormChangesTrackerService {
|
|
|
24
27
|
unregister(form) {
|
|
25
28
|
this.trackedForms.delete(form);
|
|
26
29
|
}
|
|
30
|
+
unregisterForms(forms) {
|
|
31
|
+
forms.forEach((form) => this.unregister(form));
|
|
32
|
+
}
|
|
27
33
|
reset(form) {
|
|
28
34
|
const entry = this.trackedForms.get(form);
|
|
29
|
-
if (!entry)
|
|
35
|
+
if (!entry) {
|
|
36
|
+
this.register(form);
|
|
30
37
|
return;
|
|
38
|
+
}
|
|
31
39
|
const currentRawValue = form.getRawValue?.() ?? form.value;
|
|
32
40
|
entry.initialValue = IntelliToolxHelper.clone(currentRawValue);
|
|
33
41
|
form.markAsPristine();
|
|
34
42
|
}
|
|
43
|
+
resetForms(forms) {
|
|
44
|
+
forms.forEach((form) => this.reset(form));
|
|
45
|
+
}
|
|
35
46
|
clearAll() {
|
|
36
47
|
this.trackedForms.clear();
|
|
37
48
|
}
|
|
@@ -44,4 +55,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
44
55
|
providedIn: 'root',
|
|
45
56
|
}]
|
|
46
57
|
}] });
|
|
47
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
58
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS1jaGFuZ2VzLXRyYWNrZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvZm9ybS1jaGFuZ2VzL2Zvcm0tY2hhbmdlcy10cmFja2VyLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQzs7QUFNcEUsTUFBTSxPQUFPLHlCQUF5QjtJQUh0QztRQUlVLGlCQUFZLEdBQUcsSUFBSSxHQUFHLEVBSzNCLENBQUM7S0FzREw7SUFwREMsUUFBUSxDQUFDLElBQXFCO1FBQzVCLE1BQU0sZUFBZSxHQUFJLElBQVksQ0FBQyxXQUFXLEVBQUUsRUFBRSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUM7UUFFcEUsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFO1lBQzFCLFlBQVksRUFBRSxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDO1NBQ3hELENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUN4QixDQUFDO0lBRUQsYUFBYSxDQUFDLEtBQXdCO1FBQ3BDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUMvQyxDQUFDO0lBRUQsVUFBVTtRQUNSLDJDQUEyQztRQUMzQyxLQUFLLE1BQU0sQ0FBQyxJQUFJLEVBQUUsRUFBRSxZQUFZLEVBQUUsQ0FBQyxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLEVBQUU7WUFDbEUsSUFBSSxrQkFBa0IsQ0FBQyxjQUFjLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxFQUFFO2dCQUN6RCxPQUFPLElBQUksQ0FBQzthQUNiO1NBQ0Y7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRCxVQUFVLENBQUMsSUFBcUI7UUFDOUIsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUVELGVBQWUsQ0FBQyxLQUF3QjtRQUN0QyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDakQsQ0FBQztJQUVELEtBQUssQ0FBQyxJQUFxQjtRQUN6QixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsS0FBSyxFQUFFO1lBQ1YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNwQixPQUFPO1NBQ1I7UUFFRCxNQUFNLGVBQWUsR0FBSSxJQUFZLENBQUMsV0FBVyxFQUFFLEVBQUUsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDO1FBQ3BFLEtBQUssQ0FBQyxZQUFZLEdBQUcsa0JBQWtCLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBRS9ELElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUN4QixDQUFDO0lBRUQsVUFBVSxDQUFDLEtBQXdCO1FBQ2pDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBRUQsUUFBUTtRQUNOLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDNUIsQ0FBQzsrR0EzRFUseUJBQXlCO21IQUF6Qix5QkFBeUIsY0FGeEIsTUFBTTs7NEZBRVAseUJBQXlCO2tCQUhyQyxVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEludGVsbGlUb29seEhlbHBlciB9IGZyb20gJy4uL2hlbHBlcnMvaW50ZWxsaXRvb2x4LmhlbHBlcic7XG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2wgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBGb3JtQ2hhbmdlc1RyYWNrZXJTZXJ2aWNlIHtcbiAgcHJpdmF0ZSB0cmFja2VkRm9ybXMgPSBuZXcgTWFwPFxuICAgIEFic3RyYWN0Q29udHJvbCxcbiAgICB7XG4gICAgICBpbml0aWFsVmFsdWU6IGFueTtcbiAgICB9XG4gID4oKTtcblxuICByZWdpc3Rlcihmb3JtOiBBYnN0cmFjdENvbnRyb2wpIHtcbiAgICBjb25zdCBjdXJyZW50UmF3VmFsdWUgPSAoZm9ybSBhcyBhbnkpLmdldFJhd1ZhbHVlPy4oKSA/PyBmb3JtLnZhbHVlO1xuXG4gICAgdGhpcy50cmFja2VkRm9ybXMuc2V0KGZvcm0sIHtcbiAgICAgIGluaXRpYWxWYWx1ZTogSW50ZWxsaVRvb2x4SGVscGVyLmNsb25lKGN1cnJlbnRSYXdWYWx1ZSksXG4gICAgfSk7XG5cbiAgICBmb3JtLm1hcmtBc1ByaXN0aW5lKCk7XG4gIH1cblxuICByZWdpc3RlckZvcm1zKGZvcm1zOiBBYnN0cmFjdENvbnRyb2xbXSkge1xuICAgIGZvcm1zLmZvckVhY2goKGZvcm0pID0+IHRoaXMucmVnaXN0ZXIoZm9ybSkpO1xuICB9XG5cbiAgaGFzQ2hhbmdlcygpOiBib29sZWFuIHtcbiAgICAvLyBXZSBpdGVyYXRlIG92ZXIgZW50cmllcyBbZm9ybSwgbWV0YWRhdGFdXG4gICAgZm9yIChjb25zdCBbZm9ybSwgeyBpbml0aWFsVmFsdWUgfV0gb2YgdGhpcy50cmFja2VkRm9ybXMuZW50cmllcygpKSB7XG4gICAgICBpZiAoSW50ZWxsaVRvb2x4SGVscGVyLmZvcm1IYXNDaGFuZ2VzKGluaXRpYWxWYWx1ZSwgZm9ybSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHVucmVnaXN0ZXIoZm9ybTogQWJzdHJhY3RDb250cm9sKSB7XG4gICAgdGhpcy50cmFja2VkRm9ybXMuZGVsZXRlKGZvcm0pO1xuICB9XG5cbiAgdW5yZWdpc3RlckZvcm1zKGZvcm1zOiBBYnN0cmFjdENvbnRyb2xbXSkge1xuICAgIGZvcm1zLmZvckVhY2goKGZvcm0pID0+IHRoaXMudW5yZWdpc3Rlcihmb3JtKSk7XG4gIH1cblxuICByZXNldChmb3JtOiBBYnN0cmFjdENvbnRyb2wpIHtcbiAgICBjb25zdCBlbnRyeSA9IHRoaXMudHJhY2tlZEZvcm1zLmdldChmb3JtKTtcbiAgICBpZiAoIWVudHJ5KSB7XG4gICAgICB0aGlzLnJlZ2lzdGVyKGZvcm0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGN1cnJlbnRSYXdWYWx1ZSA9IChmb3JtIGFzIGFueSkuZ2V0UmF3VmFsdWU/LigpID8/IGZvcm0udmFsdWU7XG4gICAgZW50cnkuaW5pdGlhbFZhbHVlID0gSW50ZWxsaVRvb2x4SGVscGVyLmNsb25lKGN1cnJlbnRSYXdWYWx1ZSk7XG5cbiAgICBmb3JtLm1hcmtBc1ByaXN0aW5lKCk7XG4gIH1cblxuICByZXNldEZvcm1zKGZvcm1zOiBBYnN0cmFjdENvbnRyb2xbXSkge1xuICAgIGZvcm1zLmZvckVhY2goKGZvcm0pID0+IHRoaXMucmVzZXQoZm9ybSkpO1xuICB9XG5cbiAgY2xlYXJBbGwoKSB7XG4gICAgdGhpcy50cmFja2VkRm9ybXMuY2xlYXIoKTtcbiAgfVxufVxuIl19
|
|
@@ -171,6 +171,9 @@ class FormChangesTrackerService {
|
|
|
171
171
|
});
|
|
172
172
|
form.markAsPristine();
|
|
173
173
|
}
|
|
174
|
+
registerForms(forms) {
|
|
175
|
+
forms.forEach((form) => this.register(form));
|
|
176
|
+
}
|
|
174
177
|
hasChanges() {
|
|
175
178
|
// We iterate over entries [form, metadata]
|
|
176
179
|
for (const [form, { initialValue }] of this.trackedForms.entries()) {
|
|
@@ -183,14 +186,22 @@ class FormChangesTrackerService {
|
|
|
183
186
|
unregister(form) {
|
|
184
187
|
this.trackedForms.delete(form);
|
|
185
188
|
}
|
|
189
|
+
unregisterForms(forms) {
|
|
190
|
+
forms.forEach((form) => this.unregister(form));
|
|
191
|
+
}
|
|
186
192
|
reset(form) {
|
|
187
193
|
const entry = this.trackedForms.get(form);
|
|
188
|
-
if (!entry)
|
|
194
|
+
if (!entry) {
|
|
195
|
+
this.register(form);
|
|
189
196
|
return;
|
|
197
|
+
}
|
|
190
198
|
const currentRawValue = form.getRawValue?.() ?? form.value;
|
|
191
199
|
entry.initialValue = IntelliToolxHelper.clone(currentRawValue);
|
|
192
200
|
form.markAsPristine();
|
|
193
201
|
}
|
|
202
|
+
resetForms(forms) {
|
|
203
|
+
forms.forEach((form) => this.reset(form));
|
|
204
|
+
}
|
|
194
205
|
clearAll() {
|
|
195
206
|
this.trackedForms.clear();
|
|
196
207
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fagon-ngx-intellitoolx.mjs","sources":["../../src/lib/helpers/intellitoolx.helper.ts","../../src/lib/form-changes/form-changes-tracker.service.ts","../../src/lib/form-changes/form-update-message.component.ts","../../src/lib/form-changes/unsaved-changes.guard.ts","../../src/lib/form-errors/form-errors.component.ts","../../src/lib/directives/required-marker/required-marker.token.ts","../../src/lib/directives/required-marker/required-marker.defaults.ts","../../src/lib/directives/required-marker/required-marker.directive.ts","../../src/lib/pipes/json-parse.pipe.ts","../../src/lib/ngx-intellitoolx.component.ts","../../src/lib/form-validators/max-amount.validator.ts","../../src/lib/form-validators/max-words.validator.ts","../../src/lib/form-validators/min-amount.validator.ts","../../src/lib/form-validators/password-mismatch.validator.ts","../../src/lib/form-validators/unique-email.validators.ts","../../src/lib/regex/regex.utils.ts","../../src/lib/ngx-intellitoolx.module.ts","../../src/public-api.ts","../../src/fagon-ngx-intellitoolx.ts"],"sourcesContent":["import {\n AbstractControl,\n FormArray,\n FormControl,\n FormGroup,\n} from '@angular/forms';\nimport { ConfirmHandler } from '../form-changes/confirm-handler.type';\n\nexport class IntelliToolxHelper {\n static captureInitialFormValue(form: AbstractControl): any {\n const initialValue = (form as any).getRawValue?.() ?? form.value;\n form.markAsPristine();\n return this.clone(initialValue);\n }\n\n static trimFormGroup(control: AbstractControl): void {\n if (control instanceof FormGroup) {\n Object.keys(control.controls).forEach((key) =>\n this.trimFormGroup(control.controls[key]),\n );\n return;\n }\n\n if (control instanceof FormArray) {\n control.controls.forEach((ctrl) => this.trimFormGroup(ctrl));\n return;\n }\n\n if (control instanceof FormControl) {\n const value = control.value;\n if (typeof value === 'string') {\n control.setValue(value.trim(), { emitEvent: false });\n }\n }\n }\n\n static deepEqual(obj1: any, obj2: any): boolean {\n // treat null, undefined, and empty string as equal\n if (this.isEmpty(obj1) && this.isEmpty(obj2)) {\n return true;\n }\n\n // normalize numeric values\n if (typeof obj1 === 'number' && typeof obj2 === 'number') {\n return Number(obj1) === Number(obj2);\n }\n\n // strict equality shortcut\n if (obj1 === obj2) return true;\n\n // File comparison\n if (obj1 instanceof File && obj2 instanceof File) {\n return (\n obj1.name === obj2.name &&\n obj1.size === obj2.size &&\n obj1.type === obj2.type &&\n obj1.lastModified === obj2.lastModified\n );\n }\n\n // if not objects → not equal\n if (\n typeof obj1 !== 'object' ||\n typeof obj2 !== 'object' ||\n obj1 === null ||\n obj2 === null\n ) {\n return false;\n }\n\n // arrays\n if (Array.isArray(obj1) && Array.isArray(obj2)) {\n if (obj1.length !== obj2.length) return false;\n return obj1.every((v, i) => this.deepEqual(v, obj2[i]));\n }\n\n const keys1 = Object.keys(obj1);\n const keys2 = Object.keys(obj2);\n\n if (keys1.length !== keys2.length) return false;\n\n for (const key of keys1) {\n if (!keys2.includes(key)) return false;\n if (!this.deepEqual(obj1[key], obj2[key])) return false;\n }\n\n return true;\n }\n\n static isEmpty(value: any): boolean {\n return (\n value === null ||\n value === undefined ||\n (typeof value === 'string' && value.trim() === '')\n );\n }\n\n static clone(value: any): any {\n return structuredClone(value); // Angular 14+ safe\n }\n\n static formHasChanges(initialValue: any, form: AbstractControl): boolean {\n if (!form) return false;\n\n const current = form.getRawValue();\n return !this.deepEqual(initialValue, current);\n }\n\n static async confirmIfChanged(\n hasChanges: boolean,\n confirmHandler?: ConfirmHandler,\n ): Promise<boolean> {\n if (!hasChanges) return true;\n\n if (confirmHandler) {\n const result = confirmHandler();\n return typeof result === 'boolean' ? result : await result;\n }\n\n return confirm('You have unsaved changes. Continue?');\n }\n\n static registerBeforeUnload(shouldBlock: () => boolean, message?: string) {\n const handler = (event: BeforeUnloadEvent) => {\n if (!shouldBlock()) return;\n event.preventDefault();\n event.returnValue = message ?? '';\n };\n\n window.addEventListener('beforeunload', handler);\n return () => window.removeEventListener('beforeunload', handler);\n }\n\n static getFormControl<T = any>(\n form: AbstractControl,\n path: string,\n ): FormControl<T> | null {\n if (!form || !path) return null;\n\n const segments = path.split('.');\n let current: AbstractControl | null = form;\n\n for (const segment of segments) {\n if (!current) return null;\n\n // Treat numeric segment as FormArray index\n const index = Number(segment);\n if (!isNaN(index) && current instanceof FormArray) {\n current = current.at(index);\n } else if (current instanceof FormGroup) {\n current = current.get(segment);\n } else {\n return null;\n }\n }\n\n return current instanceof FormControl ? (current as FormControl<T>) : null;\n }\n\n static convertImageToBase64(file: File): Promise<string> {\n return new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n\n reader.readAsDataURL(file);\n\n reader.onload = () => {\n const base64String = reader.result as string;\n const base64StringArray = base64String.split(',');\n resolve(base64StringArray[1]);\n };\n\n reader.onerror = (error) => {\n reject(error);\n };\n });\n }\n\n static replaceCharacter(\n text: any,\n replaceChar: string,\n replaceWithChar: string,\n ): string {\n return text?.replaceAll(replaceChar, replaceWithChar) || '';\n }\n\n static convertJsonStringToJson<T = any>(\n value: T | string | null | undefined,\n ): T | null {\n if (!value) {\n return null;\n }\n\n if (typeof value === 'string') {\n try {\n return JSON.parse(value) as T;\n } catch {\n return null;\n }\n }\n\n return value as T;\n }\n}\n","import { Injectable } from '@angular/core';\nimport { IntelliToolxHelper } from '../helpers/intellitoolx.helper';\nimport { AbstractControl } from '@angular/forms';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class FormChangesTrackerService {\n private trackedForms = new Map<\n AbstractControl,\n {\n initialValue: any;\n }\n >();\n\n register(form: AbstractControl) {\n const currentRawValue = (form as any).getRawValue?.() ?? form.value;\n\n this.trackedForms.set(form, {\n initialValue: IntelliToolxHelper.clone(currentRawValue),\n });\n\n form.markAsPristine();\n }\n\n hasChanges(): boolean {\n // We iterate over entries [form, metadata]\n for (const [form, { initialValue }] of this.trackedForms.entries()) {\n if (IntelliToolxHelper.formHasChanges(initialValue, form)) {\n return true;\n }\n }\n return false;\n }\n\n unregister(form: AbstractControl) {\n this.trackedForms.delete(form);\n }\n\n reset(form: AbstractControl) {\n const entry = this.trackedForms.get(form);\n if (!entry) return;\n\n const currentRawValue = (form as any).getRawValue?.() ?? form.value;\n entry.initialValue = IntelliToolxHelper.clone(currentRawValue);\n\n form.markAsPristine();\n }\n\n clearAll() {\n this.trackedForms.clear();\n }\n}\n","import { Component, Input } from '@angular/core';\nimport { IntellitoolxFormUpdateMessageConfig } from './form-update-message-config.interface';\nimport { CommonModule } from '@angular/common';\n\n@Component({\n selector: 'itx-form-update-message',\n standalone: true,\n imports: [CommonModule],\n styleUrls: ['./form-update-message.component.css'],\n template: `\n <div class=\"form-update-message\" role=\"alert\" [ngStyle]=\"containerStyles\">\n <span class=\"form-update-icon\" aria-hidden=\"true\" [ngStyle]=\"iconStyles\"\n >⚠</span\n >\n <span>\n {{ itxFormUpdateMessageConfig?.message || defaultMessage }}\n </span>\n </div>\n `,\n})\nexport class IntellitoolxFormUpdateMessage {\n @Input() itxFormUpdateMessageConfig?: IntellitoolxFormUpdateMessageConfig;\n defaultMessage =\n 'There are no changes to save. Please modify a field to continue.';\n\n get containerStyles(): { [key: string]: string } {\n return {\n padding: this.itxFormUpdateMessageConfig?.padding || '1rem',\n gap: this.itxFormUpdateMessageConfig?.iconAndMessageGap || '0.5rem',\n color: this.itxFormUpdateMessageConfig?.textColor || '#963C00',\n border:\n '1px solid ' +\n (this.itxFormUpdateMessageConfig?.borderColor || '#f3cd5a'),\n 'background-color':\n this.itxFormUpdateMessageConfig?.backgroundColor || '#fff3cd',\n 'font-weight': String(this.itxFormUpdateMessageConfig?.fontWeight || 400),\n 'border-radius':\n this.itxFormUpdateMessageConfig?.borderRadius || '0.5rem',\n };\n }\n\n get iconStyles(): { [key: string]: string } {\n return {\n 'font-size': this.itxFormUpdateMessageConfig?.iconSize || '1rem',\n };\n }\n}\n","import { Injectable } from '@angular/core';\nimport { CanDeactivate } from '@angular/router';\nimport { CanComponentDeactivate } from './can-component-deactivate.interface';\nimport { FormChangesTrackerService } from './form-changes-tracker.service';\n\n@Injectable({ providedIn: 'root' })\nexport class UnsavedChangesGuard implements CanDeactivate<CanComponentDeactivate> {\n constructor(private tracker: FormChangesTrackerService) {}\n\n async canDeactivate(component: CanComponentDeactivate): Promise<boolean> {\n if (!this.tracker.hasChanges()) {\n return true;\n }\n // Component provides its own confirmation (modal)\n if (component.confirmUnsavedChanges) {\n const result = component.confirmUnsavedChanges();\n return typeof result === 'boolean' ? result : await result;\n }\n\n const message =\n component.getUnsavedMessage?.() ||\n 'You have unsaved changes. Leave without saving?';\n // Fallback browser confirm\n return confirm(message);\n }\n}\n","import { CommonModule } from '@angular/common';\nimport { Component, Input } from '@angular/core';\nimport {\n AbstractControl,\n FormControl,\n UntypedFormControl,\n} from '@angular/forms';\n\nexport interface ErrorMessages {\n [key: string]: string;\n required: string;\n email: string;\n minlength: string;\n maxlength: string;\n pattern: string;\n passwordMismatch: string;\n futureDate: string;\n exceededAllowedDateDifference: string;\n startDateAfterEndDate: string;\n duplicateEmail: string;\n maxWords: string;\n maxMonthYear: string;\n minMonthYear: string;\n}\n\n@Component({\n selector: 'itx-form-errors',\n standalone: true,\n imports: [CommonModule],\n template: `\n <ng-container *ngIf=\"control?.touched && control?.invalid\">\n <ng-container *ngFor=\"let error of control?.errors | keyvalue\">\n {{ getErrorMessage(error?.key ?? '', error?.value) }}\n </ng-container>\n </ng-container>\n `,\n})\nexport class IntellitoolxFormErrors {\n @Input() control: FormControl | UntypedFormControl | AbstractControl | null =\n null;\n @Input() componentValidation: Record<string, { message: string }> = {};\n @Input() controlLabel: string | null = null;\n\n errorMessages: ErrorMessages = {\n required: 'This field is required',\n email: 'The email entered is invalid',\n minlength: 'You must enter at least {length} characters',\n maxlength: 'You must not enter more than {length} characters',\n pattern: 'Your entry must match the required pattern',\n passwordMismatch: 'Password and confirm password do not match.',\n futureDate: 'Future date is not allowed.',\n exceededAllowedDateDifference: 'Date difference can only be one month.',\n startDateAfterEndDate: 'Start date cannot be greater than end date',\n duplicateEmail: 'Each email must be unique.',\n maxWords: 'Exceeded maximum number of words.',\n maxMonthYear: 'Date is later than allowed.',\n minMonthYear: 'Date is earlier than allowed.',\n };\n\n getErrorMessage(key: string, value: any): string {\n if (!this.control) return '';\n\n const customMessage = this.componentValidation?.[key]?.message;\n\n if (typeof value === 'boolean') {\n return customMessage || this.errorMessages[key] || '';\n }\n\n if (typeof value === 'string') {\n return customMessage || value;\n }\n\n if (typeof value === 'object') {\n switch (key) {\n case 'pattern':\n return (\n customMessage ||\n `Please provide a valid ${this.controlLabel || 'data'}.`\n );\n case 'min':\n return customMessage\n ? customMessage\n : this.controlLabel\n ? `${this.controlLabel} cannot be less than ${value.min}.`\n : `Number cannot be less than ${value.min}`;\n case 'max':\n return customMessage\n ? customMessage\n : this.controlLabel\n ? `${this.controlLabel} cannot be greater than ${value.max}.`\n : `Number cannot be greater than ${value.max}`;\n case 'minlength':\n return (\n customMessage ||\n this.errorMessages.minlength.replace(\n '{length}',\n value?.requiredLength || '',\n )\n );\n case 'maxlength':\n return (\n customMessage ||\n this.errorMessages.maxlength.replace(\n '{length}',\n value?.requiredLength || '',\n )\n );\n case 'customMinValue':\n case 'customMaxValue':\n return customMessage || value?.message || '';\n case 'ngbDate':\n return (\n customMessage ||\n (this.control.value ? 'Invalid date format provided' : '')\n );\n case 'passwordMismatch':\n case 'futureDate':\n case 'duplicateEmail':\n case 'maxWords':\n case 'maxMonthYear':\n case 'minMonthYear':\n case 'exceededAllowedDateDifference':\n case 'startDateAfterEndDate':\n return customMessage || this.errorMessages[key];\n default:\n return customMessage || '';\n }\n }\n\n return '';\n }\n}\n","import { InjectionToken } from '@angular/core';\nimport { RequiredMarkerConfig } from './required-marker.config';\n\nexport const REQUIRED_MARKER_GLOBAL_CONFIG =\n new InjectionToken<RequiredMarkerConfig>('Required Marker Global Config');\n","import { ResolvedRequiredMarkerConfig } from './required-marker.config';\n\nexport const DEFAULT_REQUIRED_MARKER_CONFIG: ResolvedRequiredMarkerConfig = {\n sign: '*',\n color: 'red',\n position: 'after',\n spacing: '2px',\n className: '',\n showIfOptional: false,\n};\n","import {\n Directive,\n ElementRef,\n Renderer2,\n AfterViewInit,\n OnDestroy,\n inject,\n} from '@angular/core';\nimport {\n FormGroupDirective,\n AbstractControl,\n Validators,\n} from '@angular/forms';\nimport { merge, Subscription } from 'rxjs';\n\nimport { ResolvedRequiredMarkerConfig } from './required-marker.config';\nimport { REQUIRED_MARKER_GLOBAL_CONFIG } from './required-marker.token';\nimport { DEFAULT_REQUIRED_MARKER_CONFIG } from './required-marker.defaults';\n\n@Directive({\n selector: 'label[itxRequired]',\n standalone: true,\n})\nexport class RequiredMarkerDirective implements AfterViewInit, OnDestroy {\n private subscription?: Subscription;\n\n private globalConfig = inject(REQUIRED_MARKER_GLOBAL_CONFIG, {\n optional: true,\n });\n\n constructor(\n private el: ElementRef<HTMLLabelElement>,\n private renderer: Renderer2,\n private parentForm: FormGroupDirective,\n ) {}\n\n private resolveConfig(): ResolvedRequiredMarkerConfig {\n return {\n ...DEFAULT_REQUIRED_MARKER_CONFIG,\n ...this.globalConfig,\n };\n }\n\n ngAfterViewInit() {\n const label = this.el.nativeElement;\n const controlId = label.getAttribute('for');\n if (!controlId) return;\n\n const control = this.parentForm.form.get(controlId);\n if (!control) return;\n\n this.updateLabel(label, control);\n\n this.subscription = merge(\n control.valueChanges,\n control.statusChanges,\n ).subscribe(() => this.updateLabel(label, control));\n }\n\n private updateLabel(label: HTMLLabelElement, control: AbstractControl) {\n const config = this.resolveConfig();\n const isRequired = control.hasValidator?.(Validators.required);\n\n const original =\n label.getAttribute('data-original') || label.textContent || '';\n\n if (!label.getAttribute('data-original')) {\n label.setAttribute('data-original', original.trim());\n }\n\n const match = original.match(/^([^\\(]+)(.*)$/);\n const mainText = match ? match[1].trim() : original;\n const extraText = match ? match[2] : '';\n\n this.renderer.setProperty(label, 'textContent', '');\n\n const main = this.renderer.createText(mainText);\n\n const marker = this.renderer.createElement('span');\n this.renderer.setStyle(marker, 'color', config.color);\n this.renderer.setStyle(marker, 'margin-left', config.spacing);\n\n this.renderer.appendChild(marker, this.renderer.createText(config.sign));\n\n if (isRequired) {\n if (config.position === 'before') {\n this.renderer.appendChild(label, marker);\n this.renderer.appendChild(label, main);\n } else {\n this.renderer.appendChild(label, main);\n this.renderer.appendChild(label, marker);\n }\n } else {\n this.renderer.appendChild(label, main);\n }\n\n const extra = this.renderer.createText(extraText);\n this.renderer.appendChild(label, extra);\n }\n\n ngOnDestroy() {\n this.subscription?.unsubscribe();\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { IntelliToolxHelper } from '../helpers/intellitoolx.helper';\n\n@Pipe({\n name: 'jsonParse',\n standalone: true,\n})\nexport class JsonParsePipe implements PipeTransform {\n transform<T = any>(value: T | string | null | undefined): T | null {\n return IntelliToolxHelper.convertJsonStringToJson(value);\n }\n}\n","import { Component } from '@angular/core';\n\n@Component({\n selector: 'lib-ngx-intellitoolx',\n standalone: true,\n template: ` <p>ngx-intellitoolx works!</p> `,\n styles: [],\n})\nexport class NgxIntellitoolxComponent {}\n","import { ValidatorFn, AbstractControl, ValidationErrors } from \"@angular/forms\";\n\nexport function customMaxAmountValidator(maxValue: number): ValidatorFn {\n return (control: AbstractControl): ValidationErrors | null => {\n if (control.value !== null && control.value > maxValue) {\n control.setErrors({ exceededMaximumValue: true });\n const maxValueToFloat = maxValue.toFixed(2);\n return {\n customMaxValue: {\n requiredMin: maxValue,\n actual: control.value,\n message: `The value must not exceed ${maxValueToFloat}`,\n },\n };\n }\n\n control.setErrors(null);\n return null;\n };\n}\n","import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';\n\nexport function maxWordsValidator(maxWords: number): ValidatorFn {\n return (control: AbstractControl): ValidationErrors | null => {\n if (!control.value) return null;\n\n const wordCount = control.value.trim().split(/\\s+/).length;\n return wordCount > maxWords\n ? { maxWords: { actual: wordCount, max: maxWords } }\n : null;\n };\n}\n","import { ValidatorFn, AbstractControl, ValidationErrors } from \"@angular/forms\";\n\nexport function customMinAmountValidator(minValue: number): ValidatorFn {\n return (control: AbstractControl): ValidationErrors | null => {\n if (control.value !== null && control.value < minValue) {\n control.setErrors({ exceededMinimumValue: true });\n const minValueToFloat = minValue.toFixed(2);\n return {\n customMinValue: {\n requiredMin: minValue,\n actual: control.value,\n message: `The value must be at least ${minValueToFloat}`,\n },\n };\n }\n\n control.setErrors(null);\n return null;\n };\n}\n","import { UntypedFormGroup } from '@angular/forms';\n\nexport function passwordMismatchValidator(\n controlName: string,\n matchingControlName: string,\n) {\n return (formGroup: UntypedFormGroup) => {\n const control = formGroup.controls[controlName];\n const matchingControl = formGroup.controls[matchingControlName];\n if (matchingControl.errors && !matchingControl.errors['passwordMismatch']) {\n return;\n }\n if (control.value !== matchingControl.value) {\n matchingControl.setErrors({ passwordMismatch: true });\n } else {\n matchingControl.setErrors(null);\n }\n };\n}\n","import {\n AbstractControl,\n ValidationErrors,\n ValidatorFn,\n FormArray,\n FormGroup,\n} from '@angular/forms';\n\nexport function uniqueEmailsValidator(): ValidatorFn {\n return (formArray: AbstractControl): ValidationErrors | null => {\n if (!(formArray instanceof FormArray)) {\n return null;\n }\n\n const controls = formArray.controls as FormGroup[];\n\n // Collect all email values safely\n const emails = controls.map((control: FormGroup) => {\n const value = control.get('email')?.value;\n return typeof value === 'string' ? value.toLowerCase().trim() : '';\n });\n\n // Count occurrences\n const emailCounts: Record<string, number> = {};\n emails.forEach((email: string) => {\n if (email) {\n emailCounts[email] = (emailCounts[email] || 0) + 1;\n }\n });\n\n // Update each control's errors\n controls.forEach((control: FormGroup) => {\n const emailControl = control.get('email');\n const email = emailControl?.value?.toLowerCase()?.trim();\n\n if (emailControl) {\n const currentErrors = emailControl.errors || {};\n\n if (email && emailCounts[email] > 1) {\n emailControl.setErrors({ ...currentErrors, duplicateEmail: true });\n } else if (currentErrors?.['duplicateEmail']) {\n delete currentErrors['duplicateEmail'];\n const hasOtherErrors = Object.keys(currentErrors)?.length > 0;\n emailControl.setErrors(hasOtherErrors ? currentErrors : null);\n }\n }\n });\n\n const hasDuplicates = Object.values(emailCounts)?.some(\n (count) => count > 1,\n );\n return hasDuplicates ? { duplicateEmails: true } : null;\n };\n}\n","export const IntellitoolxRegExps = {\n EMAIL_REGEX: /^(?=.{1,50}$)[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[A-Za-z]{2,}$/,\n NUMBER_REGEX: /^\\d+$/,\n AMOUNT_REGEX: /^\\d+(\\.\\d{1,2})?$/,\n DOMAIN_REGEX:\n /^(?=.{1,255}$)(https?|ftp):\\/\\/([\\w.-]+)\\.([a-z\\.]{2,6})(:[0-9]{1,5})?(\\/\\S*)?$/,\n};\n","import { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\n\n@NgModule({\n declarations: [],\n imports: [CommonModule],\n exports: [],\n})\nexport class NgxIntellitoolxModule {}\n","/*\n * Public API Surface of ngx-intellitoolx\n */\n\n// Form Changes\nexport * from './lib/form-changes/form-changes-tracker.service';\nexport * from './lib/form-changes/form-update-message.component';\nexport * from './lib/form-changes/unsaved-changes.guard';\nexport * from './lib/form-changes/can-component-deactivate.interface';\nexport * from './lib/form-changes/form-update-message-config.interface';\n\n// Form validation\nexport * from './lib/form-errors/form-errors.component';\nexport * from './lib/directives/required-marker/required-marker.directive';\nexport * from './lib/directives/required-marker/required-marker.config';\nexport * from './lib/directives/required-marker/required-marker.token';\nexport * from './lib/directives/required-marker/required-marker.defaults';\n\n// Helpers\nexport * from './lib/helpers/intellitoolx.helper';\n\n// Pipes\nexport * from './lib/pipes/json-parse.pipe';\n\n// Components\nexport * from './lib/ngx-intellitoolx.component';\n\n// Validators\nexport * from './lib/form-validators';\n\n// Regular expressions\nexport * from './lib/regex/regex.utils';\n\n// Moddules\nexport * from './lib/ngx-intellitoolx.module';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.FormChangesTrackerService","i1"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"fagon-ngx-intellitoolx.mjs","sources":["../../src/lib/helpers/intellitoolx.helper.ts","../../src/lib/form-changes/form-changes-tracker.service.ts","../../src/lib/form-changes/form-update-message.component.ts","../../src/lib/form-changes/unsaved-changes.guard.ts","../../src/lib/form-errors/form-errors.component.ts","../../src/lib/directives/required-marker/required-marker.token.ts","../../src/lib/directives/required-marker/required-marker.defaults.ts","../../src/lib/directives/required-marker/required-marker.directive.ts","../../src/lib/pipes/json-parse.pipe.ts","../../src/lib/ngx-intellitoolx.component.ts","../../src/lib/form-validators/max-amount.validator.ts","../../src/lib/form-validators/max-words.validator.ts","../../src/lib/form-validators/min-amount.validator.ts","../../src/lib/form-validators/password-mismatch.validator.ts","../../src/lib/form-validators/unique-email.validators.ts","../../src/lib/regex/regex.utils.ts","../../src/lib/ngx-intellitoolx.module.ts","../../src/public-api.ts","../../src/fagon-ngx-intellitoolx.ts"],"sourcesContent":["import {\n AbstractControl,\n FormArray,\n FormControl,\n FormGroup,\n} from '@angular/forms';\nimport { ConfirmHandler } from '../form-changes/confirm-handler.type';\n\nexport class IntelliToolxHelper {\n static captureInitialFormValue(form: AbstractControl): any {\n const initialValue = (form as any).getRawValue?.() ?? form.value;\n form.markAsPristine();\n return this.clone(initialValue);\n }\n\n static trimFormGroup(control: AbstractControl): void {\n if (control instanceof FormGroup) {\n Object.keys(control.controls).forEach((key) =>\n this.trimFormGroup(control.controls[key]),\n );\n return;\n }\n\n if (control instanceof FormArray) {\n control.controls.forEach((ctrl) => this.trimFormGroup(ctrl));\n return;\n }\n\n if (control instanceof FormControl) {\n const value = control.value;\n if (typeof value === 'string') {\n control.setValue(value.trim(), { emitEvent: false });\n }\n }\n }\n\n static deepEqual(obj1: any, obj2: any): boolean {\n // treat null, undefined, and empty string as equal\n if (this.isEmpty(obj1) && this.isEmpty(obj2)) {\n return true;\n }\n\n // normalize numeric values\n if (typeof obj1 === 'number' && typeof obj2 === 'number') {\n return Number(obj1) === Number(obj2);\n }\n\n // strict equality shortcut\n if (obj1 === obj2) return true;\n\n // File comparison\n if (obj1 instanceof File && obj2 instanceof File) {\n return (\n obj1.name === obj2.name &&\n obj1.size === obj2.size &&\n obj1.type === obj2.type &&\n obj1.lastModified === obj2.lastModified\n );\n }\n\n // if not objects → not equal\n if (\n typeof obj1 !== 'object' ||\n typeof obj2 !== 'object' ||\n obj1 === null ||\n obj2 === null\n ) {\n return false;\n }\n\n // arrays\n if (Array.isArray(obj1) && Array.isArray(obj2)) {\n if (obj1.length !== obj2.length) return false;\n return obj1.every((v, i) => this.deepEqual(v, obj2[i]));\n }\n\n const keys1 = Object.keys(obj1);\n const keys2 = Object.keys(obj2);\n\n if (keys1.length !== keys2.length) return false;\n\n for (const key of keys1) {\n if (!keys2.includes(key)) return false;\n if (!this.deepEqual(obj1[key], obj2[key])) return false;\n }\n\n return true;\n }\n\n static isEmpty(value: any): boolean {\n return (\n value === null ||\n value === undefined ||\n (typeof value === 'string' && value.trim() === '')\n );\n }\n\n static clone(value: any): any {\n return structuredClone(value); // Angular 14+ safe\n }\n\n static formHasChanges(initialValue: any, form: AbstractControl): boolean {\n if (!form) return false;\n\n const current = form.getRawValue();\n return !this.deepEqual(initialValue, current);\n }\n\n static async confirmIfChanged(\n hasChanges: boolean,\n confirmHandler?: ConfirmHandler,\n ): Promise<boolean> {\n if (!hasChanges) return true;\n\n if (confirmHandler) {\n const result = confirmHandler();\n return typeof result === 'boolean' ? result : await result;\n }\n\n return confirm('You have unsaved changes. Continue?');\n }\n\n static registerBeforeUnload(shouldBlock: () => boolean, message?: string) {\n const handler = (event: BeforeUnloadEvent) => {\n if (!shouldBlock()) return;\n event.preventDefault();\n event.returnValue = message ?? '';\n };\n\n window.addEventListener('beforeunload', handler);\n return () => window.removeEventListener('beforeunload', handler);\n }\n\n static getFormControl<T = any>(\n form: AbstractControl,\n path: string,\n ): FormControl<T> | null {\n if (!form || !path) return null;\n\n const segments = path.split('.');\n let current: AbstractControl | null = form;\n\n for (const segment of segments) {\n if (!current) return null;\n\n // Treat numeric segment as FormArray index\n const index = Number(segment);\n if (!isNaN(index) && current instanceof FormArray) {\n current = current.at(index);\n } else if (current instanceof FormGroup) {\n current = current.get(segment);\n } else {\n return null;\n }\n }\n\n return current instanceof FormControl ? (current as FormControl<T>) : null;\n }\n\n static convertImageToBase64(file: File): Promise<string> {\n return new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n\n reader.readAsDataURL(file);\n\n reader.onload = () => {\n const base64String = reader.result as string;\n const base64StringArray = base64String.split(',');\n resolve(base64StringArray[1]);\n };\n\n reader.onerror = (error) => {\n reject(error);\n };\n });\n }\n\n static replaceCharacter(\n text: any,\n replaceChar: string,\n replaceWithChar: string,\n ): string {\n return text?.replaceAll(replaceChar, replaceWithChar) || '';\n }\n\n static convertJsonStringToJson<T = any>(\n value: T | string | null | undefined,\n ): T | null {\n if (!value) {\n return null;\n }\n\n if (typeof value === 'string') {\n try {\n return JSON.parse(value) as T;\n } catch {\n return null;\n }\n }\n\n return value as T;\n }\n}\n","import { Injectable } from '@angular/core';\nimport { IntelliToolxHelper } from '../helpers/intellitoolx.helper';\nimport { AbstractControl } from '@angular/forms';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class FormChangesTrackerService {\n private trackedForms = new Map<\n AbstractControl,\n {\n initialValue: any;\n }\n >();\n\n register(form: AbstractControl) {\n const currentRawValue = (form as any).getRawValue?.() ?? form.value;\n\n this.trackedForms.set(form, {\n initialValue: IntelliToolxHelper.clone(currentRawValue),\n });\n\n form.markAsPristine();\n }\n\n registerForms(forms: AbstractControl[]) {\n forms.forEach((form) => this.register(form));\n }\n\n hasChanges(): boolean {\n // We iterate over entries [form, metadata]\n for (const [form, { initialValue }] of this.trackedForms.entries()) {\n if (IntelliToolxHelper.formHasChanges(initialValue, form)) {\n return true;\n }\n }\n return false;\n }\n\n unregister(form: AbstractControl) {\n this.trackedForms.delete(form);\n }\n\n unregisterForms(forms: AbstractControl[]) {\n forms.forEach((form) => this.unregister(form));\n }\n\n reset(form: AbstractControl) {\n const entry = this.trackedForms.get(form);\n if (!entry) {\n this.register(form);\n return;\n }\n\n const currentRawValue = (form as any).getRawValue?.() ?? form.value;\n entry.initialValue = IntelliToolxHelper.clone(currentRawValue);\n\n form.markAsPristine();\n }\n\n resetForms(forms: AbstractControl[]) {\n forms.forEach((form) => this.reset(form));\n }\n\n clearAll() {\n this.trackedForms.clear();\n }\n}\n","import { Component, Input } from '@angular/core';\nimport { IntellitoolxFormUpdateMessageConfig } from './form-update-message-config.interface';\nimport { CommonModule } from '@angular/common';\n\n@Component({\n selector: 'itx-form-update-message',\n standalone: true,\n imports: [CommonModule],\n styleUrls: ['./form-update-message.component.css'],\n template: `\n <div class=\"form-update-message\" role=\"alert\" [ngStyle]=\"containerStyles\">\n <span class=\"form-update-icon\" aria-hidden=\"true\" [ngStyle]=\"iconStyles\"\n >⚠</span\n >\n <span>\n {{ itxFormUpdateMessageConfig?.message || defaultMessage }}\n </span>\n </div>\n `,\n})\nexport class IntellitoolxFormUpdateMessage {\n @Input() itxFormUpdateMessageConfig?: IntellitoolxFormUpdateMessageConfig;\n defaultMessage =\n 'There are no changes to save. Please modify a field to continue.';\n\n get containerStyles(): { [key: string]: string } {\n return {\n padding: this.itxFormUpdateMessageConfig?.padding || '1rem',\n gap: this.itxFormUpdateMessageConfig?.iconAndMessageGap || '0.5rem',\n color: this.itxFormUpdateMessageConfig?.textColor || '#963C00',\n border:\n '1px solid ' +\n (this.itxFormUpdateMessageConfig?.borderColor || '#f3cd5a'),\n 'background-color':\n this.itxFormUpdateMessageConfig?.backgroundColor || '#fff3cd',\n 'font-weight': String(this.itxFormUpdateMessageConfig?.fontWeight || 400),\n 'border-radius':\n this.itxFormUpdateMessageConfig?.borderRadius || '0.5rem',\n };\n }\n\n get iconStyles(): { [key: string]: string } {\n return {\n 'font-size': this.itxFormUpdateMessageConfig?.iconSize || '1rem',\n };\n }\n}\n","import { Injectable } from '@angular/core';\nimport { CanDeactivate } from '@angular/router';\nimport { CanComponentDeactivate } from './can-component-deactivate.interface';\nimport { FormChangesTrackerService } from './form-changes-tracker.service';\n\n@Injectable({ providedIn: 'root' })\nexport class UnsavedChangesGuard implements CanDeactivate<CanComponentDeactivate> {\n constructor(private tracker: FormChangesTrackerService) {}\n\n async canDeactivate(component: CanComponentDeactivate): Promise<boolean> {\n if (!this.tracker.hasChanges()) {\n return true;\n }\n // Component provides its own confirmation (modal)\n if (component.confirmUnsavedChanges) {\n const result = component.confirmUnsavedChanges();\n return typeof result === 'boolean' ? result : await result;\n }\n\n const message =\n component.getUnsavedMessage?.() ||\n 'You have unsaved changes. Leave without saving?';\n // Fallback browser confirm\n return confirm(message);\n }\n}\n","import { CommonModule } from '@angular/common';\nimport { Component, Input } from '@angular/core';\nimport {\n AbstractControl,\n FormControl,\n UntypedFormControl,\n} from '@angular/forms';\n\nexport interface ErrorMessages {\n [key: string]: string;\n required: string;\n email: string;\n minlength: string;\n maxlength: string;\n pattern: string;\n passwordMismatch: string;\n futureDate: string;\n exceededAllowedDateDifference: string;\n startDateAfterEndDate: string;\n duplicateEmail: string;\n maxWords: string;\n maxMonthYear: string;\n minMonthYear: string;\n}\n\n@Component({\n selector: 'itx-form-errors',\n standalone: true,\n imports: [CommonModule],\n template: `\n <ng-container *ngIf=\"control?.touched && control?.invalid\">\n <ng-container *ngFor=\"let error of control?.errors | keyvalue\">\n {{ getErrorMessage(error?.key ?? '', error?.value) }}\n </ng-container>\n </ng-container>\n `,\n})\nexport class IntellitoolxFormErrors {\n @Input() control: FormControl | UntypedFormControl | AbstractControl | null =\n null;\n @Input() componentValidation: Record<string, { message: string }> = {};\n @Input() controlLabel: string | null = null;\n\n errorMessages: ErrorMessages = {\n required: 'This field is required',\n email: 'The email entered is invalid',\n minlength: 'You must enter at least {length} characters',\n maxlength: 'You must not enter more than {length} characters',\n pattern: 'Your entry must match the required pattern',\n passwordMismatch: 'Password and confirm password do not match.',\n futureDate: 'Future date is not allowed.',\n exceededAllowedDateDifference: 'Date difference can only be one month.',\n startDateAfterEndDate: 'Start date cannot be greater than end date',\n duplicateEmail: 'Each email must be unique.',\n maxWords: 'Exceeded maximum number of words.',\n maxMonthYear: 'Date is later than allowed.',\n minMonthYear: 'Date is earlier than allowed.',\n };\n\n getErrorMessage(key: string, value: any): string {\n if (!this.control) return '';\n\n const customMessage = this.componentValidation?.[key]?.message;\n\n if (typeof value === 'boolean') {\n return customMessage || this.errorMessages[key] || '';\n }\n\n if (typeof value === 'string') {\n return customMessage || value;\n }\n\n if (typeof value === 'object') {\n switch (key) {\n case 'pattern':\n return (\n customMessage ||\n `Please provide a valid ${this.controlLabel || 'data'}.`\n );\n case 'min':\n return customMessage\n ? customMessage\n : this.controlLabel\n ? `${this.controlLabel} cannot be less than ${value.min}.`\n : `Number cannot be less than ${value.min}`;\n case 'max':\n return customMessage\n ? customMessage\n : this.controlLabel\n ? `${this.controlLabel} cannot be greater than ${value.max}.`\n : `Number cannot be greater than ${value.max}`;\n case 'minlength':\n return (\n customMessage ||\n this.errorMessages.minlength.replace(\n '{length}',\n value?.requiredLength || '',\n )\n );\n case 'maxlength':\n return (\n customMessage ||\n this.errorMessages.maxlength.replace(\n '{length}',\n value?.requiredLength || '',\n )\n );\n case 'customMinValue':\n case 'customMaxValue':\n return customMessage || value?.message || '';\n case 'ngbDate':\n return (\n customMessage ||\n (this.control.value ? 'Invalid date format provided' : '')\n );\n case 'passwordMismatch':\n case 'futureDate':\n case 'duplicateEmail':\n case 'maxWords':\n case 'maxMonthYear':\n case 'minMonthYear':\n case 'exceededAllowedDateDifference':\n case 'startDateAfterEndDate':\n return customMessage || this.errorMessages[key];\n default:\n return customMessage || '';\n }\n }\n\n return '';\n }\n}\n","import { InjectionToken } from '@angular/core';\nimport { RequiredMarkerConfig } from './required-marker.config';\n\nexport const REQUIRED_MARKER_GLOBAL_CONFIG =\n new InjectionToken<RequiredMarkerConfig>('Required Marker Global Config');\n","import { ResolvedRequiredMarkerConfig } from './required-marker.config';\n\nexport const DEFAULT_REQUIRED_MARKER_CONFIG: ResolvedRequiredMarkerConfig = {\n sign: '*',\n color: 'red',\n position: 'after',\n spacing: '2px',\n className: '',\n showIfOptional: false,\n};\n","import {\n Directive,\n ElementRef,\n Renderer2,\n AfterViewInit,\n OnDestroy,\n inject,\n} from '@angular/core';\nimport {\n FormGroupDirective,\n AbstractControl,\n Validators,\n} from '@angular/forms';\nimport { merge, Subscription } from 'rxjs';\n\nimport { ResolvedRequiredMarkerConfig } from './required-marker.config';\nimport { REQUIRED_MARKER_GLOBAL_CONFIG } from './required-marker.token';\nimport { DEFAULT_REQUIRED_MARKER_CONFIG } from './required-marker.defaults';\n\n@Directive({\n selector: 'label[itxRequired]',\n standalone: true,\n})\nexport class RequiredMarkerDirective implements AfterViewInit, OnDestroy {\n private subscription?: Subscription;\n\n private globalConfig = inject(REQUIRED_MARKER_GLOBAL_CONFIG, {\n optional: true,\n });\n\n constructor(\n private el: ElementRef<HTMLLabelElement>,\n private renderer: Renderer2,\n private parentForm: FormGroupDirective,\n ) {}\n\n private resolveConfig(): ResolvedRequiredMarkerConfig {\n return {\n ...DEFAULT_REQUIRED_MARKER_CONFIG,\n ...this.globalConfig,\n };\n }\n\n ngAfterViewInit() {\n const label = this.el.nativeElement;\n const controlId = label.getAttribute('for');\n if (!controlId) return;\n\n const control = this.parentForm.form.get(controlId);\n if (!control) return;\n\n this.updateLabel(label, control);\n\n this.subscription = merge(\n control.valueChanges,\n control.statusChanges,\n ).subscribe(() => this.updateLabel(label, control));\n }\n\n private updateLabel(label: HTMLLabelElement, control: AbstractControl) {\n const config = this.resolveConfig();\n const isRequired = control.hasValidator?.(Validators.required);\n\n const original =\n label.getAttribute('data-original') || label.textContent || '';\n\n if (!label.getAttribute('data-original')) {\n label.setAttribute('data-original', original.trim());\n }\n\n const match = original.match(/^([^\\(]+)(.*)$/);\n const mainText = match ? match[1].trim() : original;\n const extraText = match ? match[2] : '';\n\n this.renderer.setProperty(label, 'textContent', '');\n\n const main = this.renderer.createText(mainText);\n\n const marker = this.renderer.createElement('span');\n this.renderer.setStyle(marker, 'color', config.color);\n this.renderer.setStyle(marker, 'margin-left', config.spacing);\n\n this.renderer.appendChild(marker, this.renderer.createText(config.sign));\n\n if (isRequired) {\n if (config.position === 'before') {\n this.renderer.appendChild(label, marker);\n this.renderer.appendChild(label, main);\n } else {\n this.renderer.appendChild(label, main);\n this.renderer.appendChild(label, marker);\n }\n } else {\n this.renderer.appendChild(label, main);\n }\n\n const extra = this.renderer.createText(extraText);\n this.renderer.appendChild(label, extra);\n }\n\n ngOnDestroy() {\n this.subscription?.unsubscribe();\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { IntelliToolxHelper } from '../helpers/intellitoolx.helper';\n\n@Pipe({\n name: 'jsonParse',\n standalone: true,\n})\nexport class JsonParsePipe implements PipeTransform {\n transform<T = any>(value: T | string | null | undefined): T | null {\n return IntelliToolxHelper.convertJsonStringToJson(value);\n }\n}\n","import { Component } from '@angular/core';\n\n@Component({\n selector: 'lib-ngx-intellitoolx',\n standalone: true,\n template: ` <p>ngx-intellitoolx works!</p> `,\n styles: [],\n})\nexport class NgxIntellitoolxComponent {}\n","import { ValidatorFn, AbstractControl, ValidationErrors } from \"@angular/forms\";\n\nexport function customMaxAmountValidator(maxValue: number): ValidatorFn {\n return (control: AbstractControl): ValidationErrors | null => {\n if (control.value !== null && control.value > maxValue) {\n control.setErrors({ exceededMaximumValue: true });\n const maxValueToFloat = maxValue.toFixed(2);\n return {\n customMaxValue: {\n requiredMin: maxValue,\n actual: control.value,\n message: `The value must not exceed ${maxValueToFloat}`,\n },\n };\n }\n\n control.setErrors(null);\n return null;\n };\n}\n","import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';\n\nexport function maxWordsValidator(maxWords: number): ValidatorFn {\n return (control: AbstractControl): ValidationErrors | null => {\n if (!control.value) return null;\n\n const wordCount = control.value.trim().split(/\\s+/).length;\n return wordCount > maxWords\n ? { maxWords: { actual: wordCount, max: maxWords } }\n : null;\n };\n}\n","import { ValidatorFn, AbstractControl, ValidationErrors } from \"@angular/forms\";\n\nexport function customMinAmountValidator(minValue: number): ValidatorFn {\n return (control: AbstractControl): ValidationErrors | null => {\n if (control.value !== null && control.value < minValue) {\n control.setErrors({ exceededMinimumValue: true });\n const minValueToFloat = minValue.toFixed(2);\n return {\n customMinValue: {\n requiredMin: minValue,\n actual: control.value,\n message: `The value must be at least ${minValueToFloat}`,\n },\n };\n }\n\n control.setErrors(null);\n return null;\n };\n}\n","import { UntypedFormGroup } from '@angular/forms';\n\nexport function passwordMismatchValidator(\n controlName: string,\n matchingControlName: string,\n) {\n return (formGroup: UntypedFormGroup) => {\n const control = formGroup.controls[controlName];\n const matchingControl = formGroup.controls[matchingControlName];\n if (matchingControl.errors && !matchingControl.errors['passwordMismatch']) {\n return;\n }\n if (control.value !== matchingControl.value) {\n matchingControl.setErrors({ passwordMismatch: true });\n } else {\n matchingControl.setErrors(null);\n }\n };\n}\n","import {\n AbstractControl,\n ValidationErrors,\n ValidatorFn,\n FormArray,\n FormGroup,\n} from '@angular/forms';\n\nexport function uniqueEmailsValidator(): ValidatorFn {\n return (formArray: AbstractControl): ValidationErrors | null => {\n if (!(formArray instanceof FormArray)) {\n return null;\n }\n\n const controls = formArray.controls as FormGroup[];\n\n // Collect all email values safely\n const emails = controls.map((control: FormGroup) => {\n const value = control.get('email')?.value;\n return typeof value === 'string' ? value.toLowerCase().trim() : '';\n });\n\n // Count occurrences\n const emailCounts: Record<string, number> = {};\n emails.forEach((email: string) => {\n if (email) {\n emailCounts[email] = (emailCounts[email] || 0) + 1;\n }\n });\n\n // Update each control's errors\n controls.forEach((control: FormGroup) => {\n const emailControl = control.get('email');\n const email = emailControl?.value?.toLowerCase()?.trim();\n\n if (emailControl) {\n const currentErrors = emailControl.errors || {};\n\n if (email && emailCounts[email] > 1) {\n emailControl.setErrors({ ...currentErrors, duplicateEmail: true });\n } else if (currentErrors?.['duplicateEmail']) {\n delete currentErrors['duplicateEmail'];\n const hasOtherErrors = Object.keys(currentErrors)?.length > 0;\n emailControl.setErrors(hasOtherErrors ? currentErrors : null);\n }\n }\n });\n\n const hasDuplicates = Object.values(emailCounts)?.some(\n (count) => count > 1,\n );\n return hasDuplicates ? { duplicateEmails: true } : null;\n };\n}\n","export const IntellitoolxRegExps = {\n EMAIL_REGEX: /^(?=.{1,50}$)[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[A-Za-z]{2,}$/,\n NUMBER_REGEX: /^\\d+$/,\n AMOUNT_REGEX: /^\\d+(\\.\\d{1,2})?$/,\n DOMAIN_REGEX:\n /^(?=.{1,255}$)(https?|ftp):\\/\\/([\\w.-]+)\\.([a-z\\.]{2,6})(:[0-9]{1,5})?(\\/\\S*)?$/,\n};\n","import { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\n\n@NgModule({\n declarations: [],\n imports: [CommonModule],\n exports: [],\n})\nexport class NgxIntellitoolxModule {}\n","/*\n * Public API Surface of ngx-intellitoolx\n */\n\n// Form Changes\nexport * from './lib/form-changes/form-changes-tracker.service';\nexport * from './lib/form-changes/form-update-message.component';\nexport * from './lib/form-changes/unsaved-changes.guard';\nexport * from './lib/form-changes/can-component-deactivate.interface';\nexport * from './lib/form-changes/form-update-message-config.interface';\n\n// Form validation\nexport * from './lib/form-errors/form-errors.component';\nexport * from './lib/directives/required-marker/required-marker.directive';\nexport * from './lib/directives/required-marker/required-marker.config';\nexport * from './lib/directives/required-marker/required-marker.token';\nexport * from './lib/directives/required-marker/required-marker.defaults';\n\n// Helpers\nexport * from './lib/helpers/intellitoolx.helper';\n\n// Pipes\nexport * from './lib/pipes/json-parse.pipe';\n\n// Components\nexport * from './lib/ngx-intellitoolx.component';\n\n// Validators\nexport * from './lib/form-validators';\n\n// Regular expressions\nexport * from './lib/regex/regex.utils';\n\n// Moddules\nexport * from './lib/ngx-intellitoolx.module';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.FormChangesTrackerService","i1"],"mappings":"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"}
|
|
@@ -3,9 +3,12 @@ import * as i0 from "@angular/core";
|
|
|
3
3
|
export declare class FormChangesTrackerService {
|
|
4
4
|
private trackedForms;
|
|
5
5
|
register(form: AbstractControl): void;
|
|
6
|
+
registerForms(forms: AbstractControl[]): void;
|
|
6
7
|
hasChanges(): boolean;
|
|
7
8
|
unregister(form: AbstractControl): void;
|
|
9
|
+
unregisterForms(forms: AbstractControl[]): void;
|
|
8
10
|
reset(form: AbstractControl): void;
|
|
11
|
+
resetForms(forms: AbstractControl[]): void;
|
|
9
12
|
clearAll(): void;
|
|
10
13
|
static ɵfac: i0.ɵɵFactoryDeclaration<FormChangesTrackerService, never>;
|
|
11
14
|
static ɵprov: i0.ɵɵInjectableDeclaration<FormChangesTrackerService>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fagon/ngx-intellitoolx",
|
|
3
|
-
"version": "16.0.
|
|
3
|
+
"version": "16.0.6",
|
|
4
4
|
"description": "A comprehensive Angular utility library for reactive forms, validation, form state management, UX messaging, and reusable business-rule validators.",
|
|
5
5
|
"author": "Kingsley Darko Asomaning",
|
|
6
6
|
"license": "MIT",
|