Project

General

Profile

Form CRUD - Customers » History » Version 2

Lê Sĩ Quý, 08/29/2025 06:43 PM

1 1 Lê Sĩ Quý
# Form CRUD - Customers
2
3
{{TOC}}
4
5
## JSON Schema
6
7
``` javascript
8
{
9
    "display": "form",
10
    "components": [
11
        {
12
            "title": "<strong>New Customer</strong>",
13
            "collapsible": false,
14
            "key": "NewCustomer",
15
            "type": "panel",
16
            "label": "Panel",
17
            "input": false,
18
            "tableView": false,
19
            "components": [
20
                {
21
                    "label": "Company Name",
22
                    "applyMaskOn": "change",
23
                    "tableView": true,
24
                    "validate": {
25
                        "required": true
26
                    },
27
                    "validateWhenHidden": false,
28
                    "key": "CompanyName",
29
                    "type": "textfield",
30
                    "input": true
31
                },
32
                {
33
                    "label": "Customer ID",
34
                    "applyMaskOn": "change",
35
                    "tableView": true,
36
                    "protected": true,
37
                    "validate": {
38
                        "required": true
39
                    },
40
                    "validateWhenHidden": false,
41
                    "key": "CustomerID",
42
                    "type": "textfield",
43
                    "input": true
44
                },
45
                {
46
                    "label": "Contact Name",
47
                    "applyMaskOn": "change",
48
                    "tableView": true,
49
                    "validateWhenHidden": false,
50
                    "key": "ContactName",
51
                    "type": "textfield",
52
                    "input": true
53
                },
54
                {
55
                    "label": "Contact Title",
56
                    "widget": "choicesjs",
57
                    "tableView": true,
58
                    "data": {
59
                        "values": [
60
                            {
61
                                "label": "Sales Manager",
62
                                "value": "Sales Manager"
63
                            },
64
                            {
65
                                "label": "Inside Sales Coordinator",
66
                                "value": "Inside Sales Coordinator"
67
                            },
68
                            {
69
                                "label": "Sales Representative",
70
                                "value": "Sales Representative"
71
                            },
72
                            {
73
                                "label": "Vice President, Sales",
74
                                "value": "Vice President, Sales"
75
                            }
76
                        ]
77
                    },
78
                    "validateWhenHidden": false,
79
                    "key": "ContactTitle",
80
                    "type": "select",
81
                    "input": true
82
                },
83
                {
84
                    "label": "Address",
85
                    "applyMaskOn": "change",
86
                    "tableView": true,
87
                    "validateWhenHidden": false,
88
                    "key": "Address",
89
                    "type": "textfield",
90
                    "input": true
91
                },
92
                {
93
                    "label": "City",
94
                    "applyMaskOn": "change",
95
                    "tableView": true,
96
                    "validateWhenHidden": false,
97
                    "key": "City",
98
                    "type": "textfield",
99
                    "input": true
100
                },
101
                {
102
                    "label": "Region",
103
                    "applyMaskOn": "change",
104
                    "tableView": true,
105
                    "validateWhenHidden": false,
106
                    "key": "Region",
107
                    "type": "textfield",
108
                    "input": true
109
                },
110
                {
111
                    "label": "Postal Code",
112
                    "applyMaskOn": "change",
113
                    "tableView": true,
114
                    "validateWhenHidden": false,
115
                    "key": "PostalCode",
116
                    "type": "textfield",
117
                    "input": true
118
                },
119
                {
120
                    "label": "Country",
121
                    "widget": "choicesjs",
122
                    "tableView": true,
123
                    "dataSrc": "json",
124
                    "data": {
125
                        "json": [
126
                            {
127
                                "name": "Afghanistan",
128
                                "code": "AF"
129
                            },
130
                            {
131
                                "name": "Åland Islands",
132
                                "code": "AX"
133
                            },
134
                            {
135
                                "name": "Albania",
136
                                "code": "AL"
137
                            },
138
                            {
139
                                "name": "Algeria",
140
                                "code": "DZ"
141
                            },
142
                            {
143
                                "name": "American Samoa",
144
                                "code": "AS"
145
                            },
146
                            {
147
                                "name": "AndorrA",
148
                                "code": "AD"
149
                            },
150
                            {
151
                                "name": "Angola",
152
                                "code": "AO"
153
                            },
154
                            {
155
                                "name": "Anguilla",
156
                                "code": "AI"
157
                            },
158
                            {
159
                                "name": "Antarctica",
160
                                "code": "AQ"
161
                            },
162
                            {
163
                                "name": "Antigua and Barbuda",
164
                                "code": "AG"
165
                            },
166
                            {
167
                                "name": "Argentina",
168
                                "code": "AR"
169
                            },
170
                            {
171
                                "name": "Armenia",
172
                                "code": "AM"
173
                            },
174
                            {
175
                                "name": "Aruba",
176
                                "code": "AW"
177
                            },
178
                            {
179
                                "name": "Australia",
180
                                "code": "AU"
181
                            },
182
                            {
183
                                "name": "Austria",
184
                                "code": "AT"
185
                            },
186
                            {
187
                                "name": "Azerbaijan",
188
                                "code": "AZ"
189
                            },
190
                            {
191
                                "name": "Bahamas",
192
                                "code": "BS"
193
                            },
194
                            {
195
                                "name": "Bahrain",
196
                                "code": "BH"
197
                            },
198
                            {
199
                                "name": "Bangladesh",
200
                                "code": "BD"
201
                            },
202
                            {
203
                                "name": "Barbados",
204
                                "code": "BB"
205
                            },
206
                            {
207
                                "name": "Belarus",
208
                                "code": "BY"
209
                            },
210
                            {
211
                                "name": "Belgium",
212
                                "code": "BE"
213
                            },
214
                            {
215
                                "name": "Belize",
216
                                "code": "BZ"
217
                            },
218
                            {
219
                                "name": "Benin",
220
                                "code": "BJ"
221
                            },
222
                            {
223
                                "name": "Bermuda",
224
                                "code": "BM"
225
                            },
226
                            {
227
                                "name": "Bhutan",
228
                                "code": "BT"
229
                            },
230
                            {
231
                                "name": "Bolivia",
232
                                "code": "BO"
233
                            },
234
                            {
235
                                "name": "Bosnia and Herzegovina",
236
                                "code": "BA"
237
                            },
238
                            {
239
                                "name": "Botswana",
240
                                "code": "BW"
241
                            },
242
                            {
243
                                "name": "Bouvet Island",
244
                                "code": "BV"
245
                            },
246
                            {
247
                                "name": "Brazil",
248
                                "code": "BR"
249
                            },
250
                            {
251
                                "name": "British Indian Ocean Territory",
252
                                "code": "IO"
253
                            },
254
                            {
255
                                "name": "Brunei Darussalam",
256
                                "code": "BN"
257
                            },
258
                            {
259
                                "name": "Bulgaria",
260
                                "code": "BG"
261
                            },
262
                            {
263
                                "name": "Burkina Faso",
264
                                "code": "BF"
265
                            },
266
                            {
267
                                "name": "Burundi",
268
                                "code": "BI"
269
                            },
270
                            {
271
                                "name": "Cambodia",
272
                                "code": "KH"
273
                            },
274
                            {
275
                                "name": "Cameroon",
276
                                "code": "CM"
277
                            },
278
                            {
279
                                "name": "Canada",
280
                                "code": "CA"
281
                            },
282
                            {
283
                                "name": "Cape Verde",
284
                                "code": "CV"
285
                            },
286
                            {
287
                                "name": "Cayman Islands",
288
                                "code": "KY"
289
                            },
290
                            {
291
                                "name": "Central African Republic",
292
                                "code": "CF"
293
                            },
294
                            {
295
                                "name": "Chad",
296
                                "code": "TD"
297
                            },
298
                            {
299
                                "name": "Chile",
300
                                "code": "CL"
301
                            },
302
                            {
303
                                "name": "China",
304
                                "code": "CN"
305
                            },
306
                            {
307
                                "name": "Christmas Island",
308
                                "code": "CX"
309
                            },
310
                            {
311
                                "name": "Cocos (Keeling) Islands",
312
                                "code": "CC"
313
                            },
314
                            {
315
                                "name": "Colombia",
316
                                "code": "CO"
317
                            },
318
                            {
319
                                "name": "Comoros",
320
                                "code": "KM"
321
                            },
322
                            {
323
                                "name": "Congo",
324
                                "code": "CG"
325
                            },
326
                            {
327
                                "name": "Congo, The Democratic Republic of the",
328
                                "code": "CD"
329
                            },
330
                            {
331
                                "name": "Cook Islands",
332
                                "code": "CK"
333
                            },
334
                            {
335
                                "name": "Costa Rica",
336
                                "code": "CR"
337
                            },
338
                            {
339
                                "name": "Cote D\"Ivoire",
340
                                "code": "CI"
341
                            },
342
                            {
343
                                "name": "Croatia",
344
                                "code": "HR"
345
                            },
346
                            {
347
                                "name": "Cuba",
348
                                "code": "CU"
349
                            },
350
                            {
351
                                "name": "Cyprus",
352
                                "code": "CY"
353
                            },
354
                            {
355
                                "name": "Czech Republic",
356
                                "code": "CZ"
357
                            },
358
                            {
359
                                "name": "Denmark",
360
                                "code": "DK"
361
                            },
362
                            {
363
                                "name": "Djibouti",
364
                                "code": "DJ"
365
                            },
366
                            {
367
                                "name": "Dominica",
368
                                "code": "DM"
369
                            },
370
                            {
371
                                "name": "Dominican Republic",
372
                                "code": "DO"
373
                            },
374
                            {
375
                                "name": "Ecuador",
376
                                "code": "EC"
377
                            },
378
                            {
379
                                "name": "Egypt",
380
                                "code": "EG"
381
                            },
382
                            {
383
                                "name": "El Salvador",
384
                                "code": "SV"
385
                            },
386
                            {
387
                                "name": "Equatorial Guinea",
388
                                "code": "GQ"
389
                            },
390
                            {
391
                                "name": "Eritrea",
392
                                "code": "ER"
393
                            },
394
                            {
395
                                "name": "Estonia",
396
                                "code": "EE"
397
                            },
398
                            {
399
                                "name": "Ethiopia",
400
                                "code": "ET"
401
                            },
402
                            {
403
                                "name": "Falkland Islands (Malvinas)",
404
                                "code": "FK"
405
                            },
406
                            {
407
                                "name": "Faroe Islands",
408
                                "code": "FO"
409
                            },
410
                            {
411
                                "name": "Fiji",
412
                                "code": "FJ"
413
                            },
414
                            {
415
                                "name": "Finland",
416
                                "code": "FI"
417
                            },
418
                            {
419
                                "name": "France",
420
                                "code": "FR"
421
                            },
422
                            {
423
                                "name": "French Guiana",
424
                                "code": "GF"
425
                            },
426
                            {
427
                                "name": "French Polynesia",
428
                                "code": "PF"
429
                            },
430
                            {
431
                                "name": "French Southern Territories",
432
                                "code": "TF"
433
                            },
434
                            {
435
                                "name": "Gabon",
436
                                "code": "GA"
437
                            },
438
                            {
439
                                "name": "Gambia",
440
                                "code": "GM"
441
                            },
442
                            {
443
                                "name": "Georgia",
444
                                "code": "GE"
445
                            },
446
                            {
447
                                "name": "Germany",
448
                                "code": "DE"
449
                            },
450
                            {
451
                                "name": "Ghana",
452
                                "code": "GH"
453
                            },
454
                            {
455
                                "name": "Gibraltar",
456
                                "code": "GI"
457
                            },
458
                            {
459
                                "name": "Greece",
460
                                "code": "GR"
461
                            },
462
                            {
463
                                "name": "Greenland",
464
                                "code": "GL"
465
                            },
466
                            {
467
                                "name": "Grenada",
468
                                "code": "GD"
469
                            },
470
                            {
471
                                "name": "Guadeloupe",
472
                                "code": "GP"
473
                            },
474
                            {
475
                                "name": "Guam",
476
                                "code": "GU"
477
                            },
478
                            {
479
                                "name": "Guatemala",
480
                                "code": "GT"
481
                            },
482
                            {
483
                                "name": "Guernsey",
484
                                "code": "GG"
485
                            },
486
                            {
487
                                "name": "Guinea",
488
                                "code": "GN"
489
                            },
490
                            {
491
                                "name": "Guinea-Bissau",
492
                                "code": "GW"
493
                            },
494
                            {
495
                                "name": "Guyana",
496
                                "code": "GY"
497
                            },
498
                            {
499
                                "name": "Haiti",
500
                                "code": "HT"
501
                            },
502
                            {
503
                                "name": "Heard Island and Mcdonald Islands",
504
                                "code": "HM"
505
                            },
506
                            {
507
                                "name": "Holy See (Vatican City State)",
508
                                "code": "VA"
509
                            },
510
                            {
511
                                "name": "Honduras",
512
                                "code": "HN"
513
                            },
514
                            {
515
                                "name": "Hong Kong",
516
                                "code": "HK"
517
                            },
518
                            {
519
                                "name": "Hungary",
520
                                "code": "HU"
521
                            },
522
                            {
523
                                "name": "Iceland",
524
                                "code": "IS"
525
                            },
526
                            {
527
                                "name": "India",
528
                                "code": "IN"
529
                            },
530
                            {
531
                                "name": "Indonesia",
532
                                "code": "ID"
533
                            },
534
                            {
535
                                "name": "Iran, Islamic Republic Of",
536
                                "code": "IR"
537
                            },
538
                            {
539
                                "name": "Iraq",
540
                                "code": "IQ"
541
                            },
542
                            {
543
                                "name": "Ireland",
544
                                "code": "IE"
545
                            },
546
                            {
547
                                "name": "Isle of Man",
548
                                "code": "IM"
549
                            },
550
                            {
551
                                "name": "Israel",
552
                                "code": "IL"
553
                            },
554
                            {
555
                                "name": "Italy",
556
                                "code": "IT"
557
                            },
558
                            {
559
                                "name": "Jamaica",
560
                                "code": "JM"
561
                            },
562
                            {
563
                                "name": "Japan",
564
                                "code": "JP"
565
                            },
566
                            {
567
                                "name": "Jersey",
568
                                "code": "JE"
569
                            },
570
                            {
571
                                "name": "Jordan",
572
                                "code": "JO"
573
                            },
574
                            {
575
                                "name": "Kazakhstan",
576
                                "code": "KZ"
577
                            },
578
                            {
579
                                "name": "Kenya",
580
                                "code": "KE"
581
                            },
582
                            {
583
                                "name": "Kiribati",
584
                                "code": "KI"
585
                            },
586
                            {
587
                                "name": "Korea, Democratic People\"S Republic of",
588
                                "code": "KP"
589
                            },
590
                            {
591
                                "name": "Korea, Republic of",
592
                                "code": "KR"
593
                            },
594
                            {
595
                                "name": "Kuwait",
596
                                "code": "KW"
597
                            },
598
                            {
599
                                "name": "Kyrgyzstan",
600
                                "code": "KG"
601
                            },
602
                            {
603
                                "name": "Lao People\"S Democratic Republic",
604
                                "code": "LA"
605
                            },
606
                            {
607
                                "name": "Latvia",
608
                                "code": "LV"
609
                            },
610
                            {
611
                                "name": "Lebanon",
612
                                "code": "LB"
613
                            },
614
                            {
615
                                "name": "Lesotho",
616
                                "code": "LS"
617
                            },
618
                            {
619
                                "name": "Liberia",
620
                                "code": "LR"
621
                            },
622
                            {
623
                                "name": "Libyan Arab Jamahiriya",
624
                                "code": "LY"
625
                            },
626
                            {
627
                                "name": "Liechtenstein",
628
                                "code": "LI"
629
                            },
630
                            {
631
                                "name": "Lithuania",
632
                                "code": "LT"
633
                            },
634
                            {
635
                                "name": "Luxembourg",
636
                                "code": "LU"
637
                            },
638
                            {
639
                                "name": "Macao",
640
                                "code": "MO"
641
                            },
642
                            {
643
                                "name": "Macedonia, The Former Yugoslav Republic of",
644
                                "code": "MK"
645
                            },
646
                            {
647
                                "name": "Madagascar",
648
                                "code": "MG"
649
                            },
650
                            {
651
                                "name": "Malawi",
652
                                "code": "MW"
653
                            },
654
                            {
655
                                "name": "Malaysia",
656
                                "code": "MY"
657
                            },
658
                            {
659
                                "name": "Maldives",
660
                                "code": "MV"
661
                            },
662
                            {
663
                                "name": "Mali",
664
                                "code": "ML"
665
                            },
666
                            {
667
                                "name": "Malta",
668
                                "code": "MT"
669
                            },
670
                            {
671
                                "name": "Marshall Islands",
672
                                "code": "MH"
673
                            },
674
                            {
675
                                "name": "Martinique",
676
                                "code": "MQ"
677
                            },
678
                            {
679
                                "name": "Mauritania",
680
                                "code": "MR"
681
                            },
682
                            {
683
                                "name": "Mauritius",
684
                                "code": "MU"
685
                            },
686
                            {
687
                                "name": "Mayotte",
688
                                "code": "YT"
689
                            },
690
                            {
691
                                "name": "Mexico",
692
                                "code": "MX"
693
                            },
694
                            {
695
                                "name": "Micronesia, Federated States of",
696
                                "code": "FM"
697
                            },
698
                            {
699
                                "name": "Moldova, Republic of",
700
                                "code": "MD"
701
                            },
702
                            {
703
                                "name": "Monaco",
704
                                "code": "MC"
705
                            },
706
                            {
707
                                "name": "Mongolia",
708
                                "code": "MN"
709
                            },
710
                            {
711
                                "name": "Montserrat",
712
                                "code": "MS"
713
                            },
714
                            {
715
                                "name": "Morocco",
716
                                "code": "MA"
717
                            },
718
                            {
719
                                "name": "Mozambique",
720
                                "code": "MZ"
721
                            },
722
                            {
723
                                "name": "Myanmar",
724
                                "code": "MM"
725
                            },
726
                            {
727
                                "name": "Namibia",
728
                                "code": "NA"
729
                            },
730
                            {
731
                                "name": "Nauru",
732
                                "code": "NR"
733
                            },
734
                            {
735
                                "name": "Nepal",
736
                                "code": "NP"
737
                            },
738
                            {
739
                                "name": "Netherlands",
740
                                "code": "NL"
741
                            },
742
                            {
743
                                "name": "Netherlands Antilles",
744
                                "code": "AN"
745
                            },
746
                            {
747
                                "name": "New Caledonia",
748
                                "code": "NC"
749
                            },
750
                            {
751
                                "name": "New Zealand",
752
                                "code": "NZ"
753
                            },
754
                            {
755
                                "name": "Nicaragua",
756
                                "code": "NI"
757
                            },
758
                            {
759
                                "name": "Niger",
760
                                "code": "NE"
761
                            },
762
                            {
763
                                "name": "Nigeria",
764
                                "code": "NG"
765
                            },
766
                            {
767
                                "name": "Niue",
768
                                "code": "NU"
769
                            },
770
                            {
771
                                "name": "Norfolk Island",
772
                                "code": "NF"
773
                            },
774
                            {
775
                                "name": "Northern Mariana Islands",
776
                                "code": "MP"
777
                            },
778
                            {
779
                                "name": "Norway",
780
                                "code": "NO"
781
                            },
782
                            {
783
                                "name": "Oman",
784
                                "code": "OM"
785
                            },
786
                            {
787
                                "name": "Pakistan",
788
                                "code": "PK"
789
                            },
790
                            {
791
                                "name": "Palau",
792
                                "code": "PW"
793
                            },
794
                            {
795
                                "name": "Palestinian Territory, Occupied",
796
                                "code": "PS"
797
                            },
798
                            {
799
                                "name": "Panama",
800
                                "code": "PA"
801
                            },
802
                            {
803
                                "name": "Papua New Guinea",
804
                                "code": "PG"
805
                            },
806
                            {
807
                                "name": "Paraguay",
808
                                "code": "PY"
809
                            },
810
                            {
811
                                "name": "Peru",
812
                                "code": "PE"
813
                            },
814
                            {
815
                                "name": "Philippines",
816
                                "code": "PH"
817
                            },
818
                            {
819
                                "name": "Pitcairn",
820
                                "code": "PN"
821
                            },
822
                            {
823
                                "name": "Poland",
824
                                "code": "PL"
825
                            },
826
                            {
827
                                "name": "Portugal",
828
                                "code": "PT"
829
                            },
830
                            {
831
                                "name": "Puerto Rico",
832
                                "code": "PR"
833
                            },
834
                            {
835
                                "name": "Qatar",
836
                                "code": "QA"
837
                            },
838
                            {
839
                                "name": "Reunion",
840
                                "code": "RE"
841
                            },
842
                            {
843
                                "name": "Romania",
844
                                "code": "RO"
845
                            },
846
                            {
847
                                "name": "Russian Federation",
848
                                "code": "RU"
849
                            },
850
                            {
851
                                "name": "RWANDA",
852
                                "code": "RW"
853
                            },
854
                            {
855
                                "name": "Saint Helena",
856
                                "code": "SH"
857
                            },
858
                            {
859
                                "name": "Saint Kitts and Nevis",
860
                                "code": "KN"
861
                            },
862
                            {
863
                                "name": "Saint Lucia",
864
                                "code": "LC"
865
                            },
866
                            {
867
                                "name": "Saint Pierre and Miquelon",
868
                                "code": "PM"
869
                            },
870
                            {
871
                                "name": "Saint Vincent and the Grenadines",
872
                                "code": "VC"
873
                            },
874
                            {
875
                                "name": "Samoa",
876
                                "code": "WS"
877
                            },
878
                            {
879
                                "name": "San Marino",
880
                                "code": "SM"
881
                            },
882
                            {
883
                                "name": "Sao Tome and Principe",
884
                                "code": "ST"
885
                            },
886
                            {
887
                                "name": "Saudi Arabia",
888
                                "code": "SA"
889
                            },
890
                            {
891
                                "name": "Senegal",
892
                                "code": "SN"
893
                            },
894
                            {
895
                                "name": "Serbia and Montenegro",
896
                                "code": "CS"
897
                            },
898
                            {
899
                                "name": "Seychelles",
900
                                "code": "SC"
901
                            },
902
                            {
903
                                "name": "Sierra Leone",
904
                                "code": "SL"
905
                            },
906
                            {
907
                                "name": "Singapore",
908
                                "code": "SG"
909
                            },
910
                            {
911
                                "name": "Slovakia",
912
                                "code": "SK"
913
                            },
914
                            {
915
                                "name": "Slovenia",
916
                                "code": "SI"
917
                            },
918
                            {
919
                                "name": "Solomon Islands",
920
                                "code": "SB"
921
                            },
922
                            {
923
                                "name": "Somalia",
924
                                "code": "SO"
925
                            },
926
                            {
927
                                "name": "South Africa",
928
                                "code": "ZA"
929
                            },
930
                            {
931
                                "name": "South Georgia and the South Sandwich Islands",
932
                                "code": "GS"
933
                            },
934
                            {
935
                                "name": "Spain",
936
                                "code": "ES"
937
                            },
938
                            {
939
                                "name": "Sri Lanka",
940
                                "code": "LK"
941
                            },
942
                            {
943
                                "name": "Sudan",
944
                                "code": "SD"
945
                            },
946
                            {
947
                                "name": "Suriname",
948
                                "code": "SR"
949
                            },
950
                            {
951
                                "name": "Svalbard and Jan Mayen",
952
                                "code": "SJ"
953
                            },
954
                            {
955
                                "name": "Swaziland",
956
                                "code": "SZ"
957
                            },
958
                            {
959
                                "name": "Sweden",
960
                                "code": "SE"
961
                            },
962
                            {
963
                                "name": "Switzerland",
964
                                "code": "CH"
965
                            },
966
                            {
967
                                "name": "Syrian Arab Republic",
968
                                "code": "SY"
969
                            },
970
                            {
971
                                "name": "Taiwan",
972
                                "code": "TW"
973
                            },
974
                            {
975
                                "name": "Tajikistan",
976
                                "code": "TJ"
977
                            },
978
                            {
979
                                "name": "Tanzania, United Republic of",
980
                                "code": "TZ"
981
                            },
982
                            {
983
                                "name": "Thailand",
984
                                "code": "TH"
985
                            },
986
                            {
987
                                "name": "Timor-Leste",
988
                                "code": "TL"
989
                            },
990
                            {
991
                                "name": "Togo",
992
                                "code": "TG"
993
                            },
994
                            {
995
                                "name": "Tokelau",
996
                                "code": "TK"
997
                            },
998
                            {
999
                                "name": "Tonga",
1000
                                "code": "TO"
1001
                            },
1002
                            {
1003
                                "name": "Trinidad and Tobago",
1004
                                "code": "TT"
1005
                            },
1006
                            {
1007
                                "name": "Tunisia",
1008
                                "code": "TN"
1009
                            },
1010
                            {
1011
                                "name": "Turkey",
1012
                                "code": "TR"
1013
                            },
1014
                            {
1015
                                "name": "Turkmenistan",
1016
                                "code": "TM"
1017
                            },
1018
                            {
1019
                                "name": "Turks and Caicos Islands",
1020
                                "code": "TC"
1021
                            },
1022
                            {
1023
                                "name": "Tuvalu",
1024
                                "code": "TV"
1025
                            },
1026
                            {
1027
                                "name": "Uganda",
1028
                                "code": "UG"
1029
                            },
1030
                            {
1031
                                "name": "Ukraine",
1032
                                "code": "UA"
1033
                            },
1034
                            {
1035
                                "name": "United Arab Emirates",
1036
                                "code": "AE"
1037
                            },
1038
                            {
1039
                                "name": "United Kingdom",
1040
                                "code": "GB"
1041
                            },
1042
                            {
1043
                                "name": "United States",
1044
                                "code": "US"
1045
                            },
1046
                            {
1047
                                "name": "United States Minor Outlying Islands",
1048
                                "code": "UM"
1049
                            },
1050
                            {
1051
                                "name": "Uruguay",
1052
                                "code": "UY"
1053
                            },
1054
                            {
1055
                                "name": "Uzbekistan",
1056
                                "code": "UZ"
1057
                            },
1058
                            {
1059
                                "name": "Vanuatu",
1060
                                "code": "VU"
1061
                            },
1062
                            {
1063
                                "name": "Venezuela",
1064
                                "code": "VE"
1065
                            },
1066
                            {
1067
                                "name": "Viet Nam",
1068
                                "code": "VN"
1069
                            },
1070
                            {
1071
                                "name": "Virgin Islands, British",
1072
                                "code": "VG"
1073
                            },
1074
                            {
1075
                                "name": "Virgin Islands, U.S.",
1076
                                "code": "VI"
1077
                            },
1078
                            {
1079
                                "name": "Wallis and Futuna",
1080
                                "code": "WF"
1081
                            },
1082
                            {
1083
                                "name": "Western Sahara",
1084
                                "code": "EH"
1085
                            },
1086
                            {
1087
                                "name": "Yemen",
1088
                                "code": "YE"
1089
                            },
1090
                            {
1091
                                "name": "Zambia",
1092
                                "code": "ZM"
1093
                            },
1094
                            {
1095
                                "name": "Zimbabwe",
1096
                                "code": "ZW"
1097
                            }
1098
                        ]
1099
                    },
1100
                    "valueProperty": "name",
1101
                    "template": "<span>{{ item.name }}</span>",
1102
                    "validateWhenHidden": false,
1103
                    "key": "Country",
1104
                    "type": "select",
1105
                    "input": true
1106
                },
1107
                {
1108
                    "label": "Phone",
1109
                    "applyMaskOn": "change",
1110
                    "tableView": true,
1111
                    "validateWhenHidden": false,
1112
                    "key": "Phone",
1113
                    "type": "phoneNumber",
1114
                    "input": true
1115
                },
1116
                {
1117
                    "label": "Fax",
1118
                    "applyMaskOn": "change",
1119
                    "tableView": true,
1120
                    "validateWhenHidden": false,
1121
                    "key": "Fax",
1122
                    "type": "phoneNumber",
1123
                    "input": true
1124
                }
1125
            ]
1126
        },
1127
        {
1128
            "label": "Save",
1129
            "showValidations": false,
1130
            "disableOnInvalid": true,
1131
            "tableView": false,
1132
            "key": "submit",
1133
            "type": "button",
1134
            "saveOnEnter": false,
1135
            "input": true
1136
        }
1137
    ]
1138
}
1139
```
1140
1141
## HTML Template
1142
1143
``` html
1144
<!DOCTYPE html>
1145
<html lang="en">
1146
1147
<head>
1148
    <meta name="viewport"
1149
        content="user-scalable=no, initial-scale=1.0001, maximum-scale=1.0001, width=device-width, minimal-ui shrink-to-fit=no">
1150
    <meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1.0" />
1151
    <title>Northwind</title>
1152
1153
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
1154
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css">
1155
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap/dist/css/bootstrap.min.css">
1156
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/awesome-notifications/3.1.0/style.min.css">
1157
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/w2ui@2.0.0/w2ui-2.0.min.css">
1158
    <script src="https://cdnjs.cloudflare.com/ajax/libs/awesome-notifications/3.1.0/modern.var.min.js"></script>
1159
    <script src="https://cdn.jsdelivr.net/npm/localstorage-slim"></script>
1160
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
1161
    <script src="https://cdn.form.io/js/formio.embed.js"></script>
1162 2 Lê Sĩ Quý
    <script src="https://cdn.jsdelivr.net/npm/w2ui@2.0.0/w2ui-2.0.min.js"></script>
1163 1 Lê Sĩ Quý
</head>
1164
1165
<body>
1166
    <style>
1167
        button[type="submit"] {
1168
            background-color: #007bff;
1169
            color: white;
1170
            padding: 10px 15px;
1171
            border: none;
1172
            border-radius: 4px;
1173
            cursor: pointer;
1174
            font-size: 1em;
1175
            width: 100%;
1176
        }
1177
    </style>
1178
    <div id="toolbar"></div>
1179
    <div id="formio"></div>
1180 2 Lê Sĩ Quý
    <script lang="javascript">
1181 1 Lê Sĩ Quý
        var $ds = {};
1182
        var email = ls.get("email");
1183
        var notifier = new AWN({ option: "top-right" });
1184
        var sid = ls.get("sid");
1185
1186
        $(function () {
1187
            if (sid) {
1188
                google.script.run
1189
                    .withSuccessHandler(onCheckSidSuccess)
1190
                    .withFailureHandler(onInvalidSid)
1191
                    .checkSid(sid);
1192
            }
1193
            else {
1194
                onInvalidSid();
1195
            }
1196
        });
1197
1198
        function onInvalidSid(err) {
1199
            if (err) {
1200
                notifier.warning(err.message);
1201
            }
1202
            else {
1203
                let url = "<?!= base ?>?url=/form/login&callback=<?!= url ?>";
1204
                notifier.modal(`<b>You need to login to access this page.</b><br><a href="${url}">👉 <b>Login</b></a>`)
1205
            }
1206
        }
1207
1208
        function onCheckSidSuccess(valid) {
1209
            new w2toolbar({
1210
                box: "#toolbar",
1211
                name: "toolbar",
1212
                items: [
1213
                    {
1214
                        type: "menu", id: "sales", icon: "w2ui-icon-info", text: "Sales",
1215
                        items: [
1216
                            { id: "customers", text: "Customers", icon: "fa fa-user" },
1217
                            { id: "orders", text: "Orders", icon: "fa fa-file-text" },
1218
                        ]
1219
                    },
1220
                    { type: "break" },
1221
                    {
1222
                        type: "menu", id: "operations", icon: "w2ui-icon-settings", text: "Operations",
1223
                        items: [
1224
                            { id: "employees", text: "Employees", icon: "fa fa-address-card" },
1225
                            { id: "products", text: "Products", icon: "fa fa-archive" },
1226
                            { id: "categories", text: "Product Categories", icon: "fa fa-sitemap" },
1227
                            { id: "suppliers", text: "Suppliers", icon: "fa fa-user" },
1228
                            { id: "shippers", text: "Shippers", icon: "fa fa-shopping-cart" }
1229
                        ]
1230
                    },
1231
                    { type: "spacer" },
1232
                    {
1233
                        type: "menu", id: "auth", text: email,
1234
                        items: [
1235
                            { text: "Logout", id: "logout", icon: "fa fa-sign-out" }
1236
                        ]
1237
                    }
1238
                ],
1239
                onClick(event) {
1240
                    switch (event.target) {
1241
                        case "sales:customers": {
1242
                            window.open("<?= base ?>?url=/form/customers", "_top");
1243
                            break;
1244
                        }
1245
                        case "sales:orders": {
1246
                            window.open("<?= base ?>?url=/form/orders", "_top");
1247
                            break;
1248
                        }
1249
                        case "operations:employees": {
1250
                            window.open("<?= base ?>?url=/form/employees", "_top");
1251
                            break;
1252
                        }
1253
                        case "operations:products": {
1254
                            window.open("<?= base ?>?url=/form/products", "_top");
1255
                            break;
1256
                        }
1257
                        case "operations:categories": {
1258
                            window.open("<?= base ?>?url=/form/categories", "_top");
1259
                            break;
1260
                        }
1261
                        case "operations:suppliers": {
1262
                            window.open("<?= base ?>?url=/form/suppliers", "_top");
1263
                            break;
1264
                        }
1265
                        case "operations:shippers": {
1266
                            window.open("<?= base ?>?url=/form/shippers", "_top");
1267
                            break;
1268
                        }
1269
                        case "auth:logout": {
1270
                            ls.remove("sid");
1271
                            ls.remove("email");
1272
                            window.open("<?= base ?>?url=/form/login&callback=<?!= url ?>", "_top");
1273
                            break;
1274
                        }
1275
                    }
1276
                }
1277
            });
1278
1279
            if (valid) {
1280
                google.script.run.withSuccessHandler(showForms)
1281
                    .loadDatasources("<?!= datasource ?>");
1282
            } else {
1283
                onInvalidSid();
1284
            }
1285
        }
1286
1287
        function showForms(ds) {
1288
            $ds = ds;
1289
            let rec = <?!= (data) ?>;
1290
            Formio.createForm(document.getElementById("formio"), <?!= template ?>)
1291
                .then(function (form) {
1292
                    // Prevent the submission from going to the form.io server.
1293
                    form.noAlerts = true;
1294
                    form.nosubmit = true;
1295
                    form.submission = rec.Document ? { data: JSON.parse(rec.Document) } : {};
1296
1297
                    // Triggered when they click the submit button.
1298
                    form.on("submit", function (submission) {
1299
                        google.script.run
1300
                            .withFailureHandler((err) => {
1301
                                notifier.warning("Successfully saved.");
1302
                                form.emit("submitError");
1303
                            })
1304
                            .withSuccessHandler((id) => {
1305
                                if (!id) {
1306
                                    form.emit("submitError");
1307
                                    notifier.warning("An error occurred while saving the entry.");
1308
                                }
1309
                                else {
1310
                                    form.emit("submitDone");
1311
                                    <? if (!id) { ?>
1312
                                    form.submission = {};
1313
                                    form.refresh();
1314
                                    <? } ?>
1315
                                    notifier.success("Successfully saved.");
1316
                                }
1317
                            })
1318
                            <? if (id) { ?>
1319
                        .update("<?!= id ?>", "<?!= form.Id ?>", { Document: JSON.stringify(submission.data) }, null, sid)
1320
                                <? } else { ?>
1321
                        .create("<?!= form.Id ?>", { Document: JSON.stringify(submission.data) }, sid);
1322
                        <? } ?>
1323
                    });
1324
                });
1325
        }
1326
    </script>
1327
</body>
1328
1329
</html>
1330
```
1331
1332
## Giải thích Code
1333
1334
Form List Customers sử dụng cácthư viện sau:
1335
- [jQuery](https://jquery.com/) để khởi tạo grid sau khi page load xong.
1336
- [localstorage-slim](https://github.com/digitalfortress-tech/localstorage-slim) để đọc sid & email để bỏ qua bước login nếu trước đó đã login thành công. Trường hợp login không thành công thì sẽ thông báo và điều hướng đến trang login.
1337
- [Notyf](https://carlosroso.com/notyf/) hiển thị thông báo.
1338
- [w2ui](https://w2ui.com/web/home) cung cấp các thành phần UI cơ bản và nâng cao, ví dụ: toolbar và grid, dialog...
1339
- Các thư viện đều được load từ CDN để tối ưu tốc độ, đơn giản hóa HTML Templated. Các bạn cần có kiến thức trong phần yêu cầu để hiểu logic của code JS + templated nhúng trong page. 
1340
- Trong page này gọi đến
1341
  - Hàm backend **checkSid** sid lưu trữ có khớp với giá trị trên server, nếu đúng thì sẽ sử dụng email trả về, còn sai sẽ điều hướng đến trang login
1342
  - Hàm backend **loadDatasources** để tải các dữ liệu tham chiếu phía client, ví dụ danh sách Products
1343
  - Hàm backend **create** để lưu form submission dưới dạng document trong database NoSQL
1344
  - Hàm backend **update** để cập nhật record đã tồn tại với record id được truyền vào từ url theo định dạng **form-id/record-id**. Trong trường hợp này record-id chính là column Id của document.
1345 2 Lê Sĩ Quý
- Form CRUD Order tham chiếu đến các datasource **Customers**, **Employees**, **Shippers**, **Products** Các datasource sẽ phục làm data các thành phần FormIO UI.
1346
 
1347 1 Lê Sĩ Quý
## Demo
1348
- Link: https://script.google.com/macros/s/AKfycbwIjB-hULVZdfCtsXFPg4Af_8WoKx2AFf85KMVwnsO_WkeAXW3zarT6vZNFVfwccz1_sA/exec?url=/form/crud-customer
1349
- Account: user@northwind.com
1350
- Password: user