@ng-formworks/material 15.2.7

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.
Files changed (44) hide show
  1. package/README.md +133 -0
  2. package/assets/material-design-themes.scss +71 -0
  3. package/karma.conf.js +46 -0
  4. package/ng-package.json +13 -0
  5. package/package.json +49 -0
  6. package/src/lib/flexlayout-replacement-styles.scss +95 -0
  7. package/src/lib/material-design-cssframework.ts +20 -0
  8. package/src/lib/material-design-framework.component.html +13 -0
  9. package/src/lib/material-design-framework.component.scss +58 -0
  10. package/src/lib/material-design-framework.component.spec.ts +39 -0
  11. package/src/lib/material-design-framework.component.ts +143 -0
  12. package/src/lib/material-design-framework.module.ts +81 -0
  13. package/src/lib/material-design-themes.scss +71 -0
  14. package/src/lib/material-design.framework.ts +83 -0
  15. package/src/lib/tailwind-output.scss +622 -0
  16. package/src/lib/widgets/flex-layout-root.component.html +4 -0
  17. package/src/lib/widgets/flex-layout-root.component.ts +52 -0
  18. package/src/lib/widgets/flex-layout-section.component.ts +216 -0
  19. package/src/lib/widgets/material-add-reference.component.ts +56 -0
  20. package/src/lib/widgets/material-button-group.component.ts +68 -0
  21. package/src/lib/widgets/material-button.component.ts +66 -0
  22. package/src/lib/widgets/material-checkbox.component.ts +112 -0
  23. package/src/lib/widgets/material-checkboxes.component.ts +108 -0
  24. package/src/lib/widgets/material-chip-list.component.ts +35 -0
  25. package/src/lib/widgets/material-datepicker.component.ts +89 -0
  26. package/src/lib/widgets/material-file.component.ts +35 -0
  27. package/src/lib/widgets/material-input.component.ts +97 -0
  28. package/src/lib/widgets/material-number.component.ts +95 -0
  29. package/src/lib/widgets/material-one-of.component.ts +35 -0
  30. package/src/lib/widgets/material-radios.component.ts +91 -0
  31. package/src/lib/widgets/material-select.component.ts +118 -0
  32. package/src/lib/widgets/material-slider.component.ts +65 -0
  33. package/src/lib/widgets/material-stepper.component.ts +35 -0
  34. package/src/lib/widgets/material-tabs.component.ts +72 -0
  35. package/src/lib/widgets/material-textarea.component.ts +88 -0
  36. package/src/lib/widgets/public_api.ts +54 -0
  37. package/src/public_api.ts +9 -0
  38. package/src/test.ts +17 -0
  39. package/tailwind-input.css +3 -0
  40. package/tailwind.config.js +12 -0
  41. package/tsconfig.lib.json +25 -0
  42. package/tsconfig.lib.prod.json +9 -0
  43. package/tsconfig.spec.json +17 -0
  44. package/tslint.json +11 -0
@@ -0,0 +1,216 @@
1
+ import { Component, Input, OnInit } from '@angular/core';
2
+ import { AbstractControl } from '@angular/forms';
3
+ import { JsonSchemaFormService } from '@ng-formworks/core';
4
+
5
+ @Component({
6
+ // tslint:disable-next-line:component-selector
7
+ selector: 'flex-layout-section-widget',
8
+ template: `
9
+ <div *ngIf="containerType === 'div'"
10
+ [class]="options?.htmlClass || ''"
11
+ [class.expandable]="options?.expandable && !expanded"
12
+ [class.expanded]="options?.expandable && expanded">
13
+ <label *ngIf="sectionTitle"
14
+ [class]="'legend ' + (options?.labelHtmlClass || '')"
15
+ [innerHTML]="sectionTitle"
16
+ (click)="toggleExpanded()"></label>
17
+ <flex-layout-root-widget *ngIf="expanded"
18
+ [layout]="layoutNode.items"
19
+ [dataIndex]="dataIndex"
20
+ [layoutIndex]="layoutIndex"
21
+ [isFlexItem]="getFlexAttribute('is-flex')"
22
+ [class.form-flex-column]="getFlexAttribute('flex-direction') === 'column'"
23
+ [class.form-flex-row]="getFlexAttribute('flex-direction') === 'row'"
24
+ [style.display]="getFlexAttribute('display')"
25
+ [style.flex-direction]="getFlexAttribute('flex-direction')"
26
+ [style.flex-wrap]="getFlexAttribute('flex-wrap')"
27
+ [style.justify-content]="getFlexAttribute('justify-content')"
28
+ [style.align-items]="getFlexAttribute('align-items')"
29
+ [style.align-content]="getFlexAttribute('align-content')"
30
+ [attr.fxLayout]="getFlexAttribute('layout')"
31
+ [attr.fxLayoutGap]="options?.fxLayoutGap"
32
+ [attr.fxLayoutAlign]="options?.fxLayoutAlign"
33
+ [attr.fxFlexFill]="options?.fxLayoutAlign"></flex-layout-root-widget>
34
+ <mat-error *ngIf="options?.showErrors && options?.errorMessage"
35
+ [innerHTML]="options?.errorMessage"></mat-error>
36
+ </div>
37
+
38
+ <fieldset *ngIf="containerType === 'fieldset'"
39
+ [class]="options?.htmlClass || ''"
40
+ [class.expandable]="options?.expandable && !expanded"
41
+ [class.expanded]="options?.expandable && expanded"
42
+ [disabled]="options?.readonly">
43
+ <legend *ngIf="sectionTitle"
44
+ [class]="'legend ' + (options?.labelHtmlClass || '')"
45
+ [innerHTML]="sectionTitle"
46
+ (click)="toggleExpanded()"></legend>
47
+ <flex-layout-root-widget *ngIf="expanded"
48
+ [layout]="layoutNode.items"
49
+ [dataIndex]="dataIndex"
50
+ [layoutIndex]="layoutIndex"
51
+ [isFlexItem]="getFlexAttribute('is-flex')"
52
+ [class.form-flex-column]="getFlexAttribute('flex-direction') === 'column'"
53
+ [class.form-flex-row]="getFlexAttribute('flex-direction') === 'row'"
54
+ [style.display]="getFlexAttribute('display')"
55
+ [style.flex-direction]="getFlexAttribute('flex-direction')"
56
+ [style.flex-wrap]="getFlexAttribute('flex-wrap')"
57
+ [style.justify-content]="getFlexAttribute('justify-content')"
58
+ [style.align-items]="getFlexAttribute('align-items')"
59
+ [style.align-content]="getFlexAttribute('align-content')"
60
+ [attr.fxLayout]="getFlexAttribute('layout')"
61
+ [attr.fxLayoutGap]="options?.fxLayoutGap"
62
+ [attr.fxLayoutAlign]="options?.fxLayoutAlign"
63
+ [attr.attr.fxFlexFill]="options?.fxLayoutAlign"></flex-layout-root-widget>
64
+ <mat-error *ngIf="options?.showErrors && options?.errorMessage"
65
+ [innerHTML]="options?.errorMessage"></mat-error>
66
+ </fieldset>
67
+
68
+ <mat-card appearance="outlined" *ngIf="containerType === 'card'"
69
+ [ngClass]="options?.htmlClass || ''"
70
+ [class.expandable]="options?.expandable && !expanded"
71
+ [class.expanded]="options?.expandable && expanded">
72
+ <mat-card-header *ngIf="sectionTitle">
73
+ <legend
74
+ [class]="'legend ' + (options?.labelHtmlClass || '')"
75
+ [innerHTML]="sectionTitle"
76
+ (click)="toggleExpanded()"></legend>
77
+ </mat-card-header>
78
+ <mat-card-content *ngIf="expanded">
79
+ <fieldset [disabled]="options?.readonly">
80
+ <flex-layout-root-widget *ngIf="expanded"
81
+ [layout]="layoutNode.items"
82
+ [dataIndex]="dataIndex"
83
+ [layoutIndex]="layoutIndex"
84
+ [isFlexItem]="getFlexAttribute('is-flex')"
85
+ [class.form-flex-column]="getFlexAttribute('flex-direction') === 'column'"
86
+ [class.form-flex-row]="getFlexAttribute('flex-direction') === 'row'"
87
+ [style.display]="getFlexAttribute('display')"
88
+ [style.flex-direction]="getFlexAttribute('flex-direction')"
89
+ [style.flex-wrap]="getFlexAttribute('flex-wrap')"
90
+ [style.justify-content]="getFlexAttribute('justify-content')"
91
+ [style.align-items]="getFlexAttribute('align-items')"
92
+ [style.align-content]="getFlexAttribute('align-content')"
93
+ [attr.fxLayout]="getFlexAttribute('layout')"
94
+ [attr.fxLayoutGap]="options?.fxLayoutGap"
95
+ [attr.fxLayoutAlign]="options?.fxLayoutAlign"
96
+ [attr.fxFlexFill]="options?.fxLayoutAlign"></flex-layout-root-widget>
97
+ </fieldset>
98
+ </mat-card-content>
99
+ <mat-card-footer>
100
+ <mat-error *ngIf="options?.showErrors && options?.errorMessage"
101
+ [innerHTML]="options?.errorMessage"></mat-error>
102
+ </mat-card-footer>
103
+ </mat-card>
104
+
105
+ <mat-expansion-panel *ngIf="containerType === 'expansion-panel'"
106
+ [expanded]="expanded"
107
+ [hideToggle]="!options?.expandable">
108
+ <mat-expansion-panel-header>
109
+ <mat-panel-title>
110
+ <legend *ngIf="sectionTitle"
111
+ [class]="options?.labelHtmlClass"
112
+ [innerHTML]="sectionTitle"
113
+ (click)="toggleExpanded()"></legend>
114
+ </mat-panel-title>
115
+ </mat-expansion-panel-header>
116
+ <fieldset [disabled]="options?.readonly">
117
+ <flex-layout-root-widget *ngIf="expanded"
118
+ [layout]="layoutNode.items"
119
+ [dataIndex]="dataIndex"
120
+ [layoutIndex]="layoutIndex"
121
+ [isFlexItem]="getFlexAttribute('is-flex')"
122
+ [class.form-flex-column]="getFlexAttribute('flex-direction') === 'column'"
123
+ [class.form-flex-row]="getFlexAttribute('flex-direction') === 'row'"
124
+ [style.display]="getFlexAttribute('display')"
125
+ [style.flex-direction]="getFlexAttribute('flex-direction')"
126
+ [style.flex-wrap]="getFlexAttribute('flex-wrap')"
127
+ [style.justify-content]="getFlexAttribute('justify-content')"
128
+ [style.align-items]="getFlexAttribute('align-items')"
129
+ [style.align-content]="getFlexAttribute('align-content')"
130
+ [attr.fxLayout]="getFlexAttribute('layout')"
131
+ [attr.fxLayoutGap]="options?.fxLayoutGap"
132
+ [attr.fxLayoutAlign]="options?.fxLayoutAlign"
133
+ [attr.fxFlexFill]="options?.fxLayoutAlign"></flex-layout-root-widget>
134
+ </fieldset>
135
+ <mat-error *ngIf="options?.showErrors && options?.errorMessage"
136
+ [innerHTML]="options?.errorMessage"></mat-error>
137
+ </mat-expansion-panel>`,
138
+ styles: [`
139
+ fieldset { border: 0; margin: 0; padding: 0; }
140
+ .legend { font-weight: bold; }
141
+ .expandable > .legend:before { content: '▶'; padding-right: .3em; }
142
+ .expanded > .legend:before { content: '▼'; padding-right: .2em; }
143
+ `],
144
+ })
145
+ export class FlexLayoutSectionComponent implements OnInit {
146
+ formControl: AbstractControl;
147
+ controlName: string;
148
+ controlValue: any;
149
+ controlDisabled = false;
150
+ boundControl = false;
151
+ options: any;
152
+ expanded = true;
153
+ containerType = 'div';
154
+ @Input() layoutNode: any;
155
+ @Input() layoutIndex: number[];
156
+ @Input() dataIndex: number[];
157
+
158
+ constructor(
159
+ private jsf: JsonSchemaFormService
160
+ ) { }
161
+
162
+ get sectionTitle() {
163
+ return this.options.notitle ? null : this.jsf.setItemTitle(this);
164
+ }
165
+
166
+ ngOnInit() {
167
+ this.jsf.initializeControl(this);
168
+ this.options = this.layoutNode.options || {};
169
+ this.expanded = typeof this.options.expanded === 'boolean' ?
170
+ this.options.expanded : !this.options.expandable;
171
+ switch (this.layoutNode.type) {
172
+ case 'section': case 'array': case 'fieldset': case 'advancedfieldset':
173
+ case 'authfieldset': case 'optionfieldset': case 'selectfieldset':
174
+ this.containerType = 'fieldset';
175
+ break;
176
+ case 'card':
177
+ this.containerType = 'card';
178
+ break;
179
+ case 'expansion-panel':
180
+ this.containerType = 'expansion-panel';
181
+ break;
182
+ default: // 'div', 'flex', 'tab', 'conditional', 'actions'
183
+ this.containerType = 'div';
184
+ }
185
+ }
186
+
187
+ toggleExpanded() {
188
+ if (this.options.expandable) { this.expanded = !this.expanded; }
189
+ }
190
+
191
+ // Set attributes for flexbox container
192
+ // (child attributes are set in flex-layout-root.component)
193
+ getFlexAttribute(attribute: string) {
194
+ const flexActive: boolean =
195
+ this.layoutNode.type === 'flex' ||
196
+ !!this.options.displayFlex ||
197
+ this.options.display === 'flex';
198
+ // if (attribute !== 'flex' && !flexActive) { return null; }
199
+ switch (attribute) {
200
+ case 'is-flex':
201
+ return flexActive;
202
+ case 'display':
203
+ return flexActive ? 'flex' : 'initial';
204
+ case 'flex-direction': case 'flex-wrap':
205
+ const index = ['flex-direction', 'flex-wrap'].indexOf(attribute);
206
+ return (this.options['flex-flow'] || '').split(/\s+/)[index] ||
207
+ this.options[attribute] || ['column', 'nowrap'][index];
208
+ case 'justify-content': case 'align-items': case 'align-content':
209
+ return this.options[attribute];
210
+ case 'layout':
211
+ return (this.options.fxLayout || 'row') +
212
+ this.options.fxLayoutWrap ? ' ' + this.options.fxLayoutWrap : '';
213
+
214
+ }
215
+ }
216
+ }
@@ -0,0 +1,56 @@
1
+ import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
2
+ import { JsonSchemaFormService } from '@ng-formworks/core';
3
+
4
+
5
+ @Component({
6
+ // tslint:disable-next-line:component-selector
7
+ selector: 'material-add-reference-widget',
8
+ template: `
9
+ <section [class]="options?.htmlClass || ''" align="end">
10
+ <button mat-raised-button *ngIf="showAddButton"
11
+ [color]="options?.color || 'accent'"
12
+ [disabled]="options?.readonly"
13
+ (click)="addItem($event)">
14
+ <span *ngIf="options?.icon" [class]="options?.icon"></span>
15
+ <span *ngIf="options?.title" [innerHTML]="buttonText"></span>
16
+ </button>
17
+ </section>`,
18
+ changeDetection: ChangeDetectionStrategy.Default,
19
+ })
20
+ export class MaterialAddReferenceComponent implements OnInit {
21
+ options: any;
22
+ itemCount: number;
23
+ previousLayoutIndex: number[];
24
+ previousDataIndex: number[];
25
+ @Input() layoutNode: any;
26
+ @Input() layoutIndex: number[];
27
+ @Input() dataIndex: number[];
28
+
29
+ constructor(
30
+ private jsf: JsonSchemaFormService
31
+ ) { }
32
+
33
+ ngOnInit() {
34
+ this.options = this.layoutNode.options || {};
35
+ }
36
+
37
+ get showAddButton(): boolean {
38
+ return !this.layoutNode.arrayItem ||
39
+ this.layoutIndex[this.layoutIndex.length - 1] < this.options.maxItems;
40
+ }
41
+
42
+ addItem(event) {
43
+ event.preventDefault();
44
+ this.jsf.addItem(this);
45
+ }
46
+
47
+ get buttonText(): string {
48
+ const parent: any = {
49
+ dataIndex: this.dataIndex.slice(0, -1),
50
+ layoutIndex: this.layoutIndex.slice(0, -1),
51
+ layoutNode: this.jsf.getParentNode(this),
52
+ };
53
+ return parent.layoutNode.add ||
54
+ this.jsf.setArrayItemTitle(parent, this.layoutNode, this.itemCount);
55
+ }
56
+ }
@@ -0,0 +1,68 @@
1
+ import { Component, Input, OnInit } from '@angular/core';
2
+ import { AbstractControl } from '@angular/forms';
3
+ import { JsonSchemaFormService, buildTitleMap } from '@ng-formworks/core';
4
+
5
+
6
+ @Component({
7
+ // tslint:disable-next-line:component-selector
8
+ selector: 'material-button-group-widget',
9
+ template: `
10
+ <div>
11
+ <div *ngIf="options?.title">
12
+ <label
13
+ [attr.for]="'control' + layoutNode?._id"
14
+ [class]="options?.labelHtmlClass || ''"
15
+ [style.display]="options?.notitle ? 'none' : ''"
16
+ [innerHTML]="options?.title"></label>
17
+ </div>
18
+ <mat-button-toggle-group
19
+ [attr.aria-describedby]="'control' + layoutNode?._id + 'Status'"
20
+ [attr.readonly]="options?.readonly ? 'readonly' : null"
21
+ [attr.required]="options?.required"
22
+ [disabled]="controlDisabled || options?.readonly"
23
+ [name]="controlName"
24
+ [value]="controlValue"
25
+ [vertical]="!!options.vertical">
26
+ <mat-button-toggle *ngFor="let radioItem of radiosList"
27
+ [id]="'control' + layoutNode?._id + '/' + radioItem?.name"
28
+ [value]="radioItem?.value"
29
+ (click)="updateValue(radioItem?.value)">
30
+ <span [innerHTML]="radioItem?.name"></span>
31
+ </mat-button-toggle>
32
+ </mat-button-toggle-group>
33
+ <mat-error *ngIf="options?.showErrors && options?.errorMessage"
34
+ [innerHTML]="options?.errorMessage"></mat-error>
35
+ </div>`,
36
+ styles: [` mat-error { font-size: 75%; } `],
37
+ })
38
+ export class MaterialButtonGroupComponent implements OnInit {
39
+ formControl: AbstractControl;
40
+ controlName: string;
41
+ controlValue: any;
42
+ controlDisabled = false;
43
+ boundControl = false;
44
+ options: any;
45
+ radiosList: any[] = [];
46
+ vertical = false;
47
+ @Input() layoutNode: any;
48
+ @Input() layoutIndex: number[];
49
+ @Input() dataIndex: number[];
50
+
51
+ constructor(
52
+ private jsf: JsonSchemaFormService
53
+ ) { }
54
+
55
+ ngOnInit() {
56
+ this.options = this.layoutNode.options || {};
57
+ this.radiosList = buildTitleMap(
58
+ this.options.titleMap || this.options.enumNames,
59
+ this.options.enum, true
60
+ );
61
+ this.jsf.initializeControl(this);
62
+ }
63
+
64
+ updateValue(value) {
65
+ this.options.showErrors = true;
66
+ this.jsf.updateValue(this, value);
67
+ }
68
+ }
@@ -0,0 +1,66 @@
1
+ import { Component, Input, OnDestroy, OnInit } from '@angular/core';
2
+ import { AbstractControl } from '@angular/forms';
3
+ import { JsonSchemaFormService, hasOwn } from '@ng-formworks/core';
4
+ import { Subscription } from 'rxjs';
5
+
6
+ @Component({
7
+ // tslint:disable-next-line:component-selector
8
+ selector: 'material-button-widget',
9
+ template: `
10
+ <div class="button-row" [class]="options?.htmlClass || ''">
11
+ <button mat-raised-button
12
+ [attr.readonly]="options?.readonly ? 'readonly' : null"
13
+ [attr.aria-describedby]="'control' + layoutNode?._id + 'Status'"
14
+ [color]="options?.color || 'primary'"
15
+ [disabled]="controlDisabled || options?.readonly"
16
+ [id]="'control' + layoutNode?._id"
17
+ [name]="controlName"
18
+ [type]="layoutNode?.type"
19
+ [value]="controlValue"
20
+ (click)="updateValue($event)">
21
+ <mat-icon *ngIf="options?.icon" class="mat-24">{{options?.icon}}</mat-icon>
22
+ <span *ngIf="options?.title" [innerHTML]="options?.title"></span>
23
+ </button>
24
+ </div>`,
25
+ styles: [` button { margin-top: 10px; } `],
26
+ })
27
+ export class MaterialButtonComponent implements OnInit,OnDestroy {
28
+ formControl: AbstractControl;
29
+ controlName: string;
30
+ controlValue: any;
31
+ controlDisabled = false;
32
+ boundControl = false;
33
+ options: any;
34
+ @Input() layoutNode: any;
35
+ @Input() layoutIndex: number[];
36
+ @Input() dataIndex: number[];
37
+
38
+ isValidChangesSubs:Subscription;
39
+ constructor(
40
+ private jsf: JsonSchemaFormService
41
+ ) { }
42
+
43
+ ngOnDestroy(): void {
44
+ this.isValidChangesSubs?.unsubscribe();
45
+ this.isValidChangesSubs=null;
46
+ }
47
+
48
+ ngOnInit() {
49
+ this.options = this.layoutNode.options || {};
50
+ this.jsf.initializeControl(this);
51
+ if (hasOwn(this.options, 'disabled')) {
52
+ this.controlDisabled = this.options.disabled;
53
+ } else if (this.jsf.formOptions.disableInvalidSubmit) {
54
+ this.controlDisabled = !this.jsf.isValid;
55
+ this.jsf.isValidChanges.subscribe(isValid => this.controlDisabled = !isValid);
56
+ }
57
+ }
58
+
59
+ updateValue(event) {
60
+ if (typeof this.options.onClick === 'function') {
61
+ this.options.onClick(event);
62
+ } else {
63
+ this.jsf.updateValue(this, event.target.value);
64
+ }
65
+ }
66
+ }
@@ -0,0 +1,112 @@
1
+ import { Component, Input, OnInit } from '@angular/core';
2
+ import { AbstractControl } from '@angular/forms';
3
+ import { JsonSchemaFormService } from '@ng-formworks/core';
4
+
5
+ @Component({
6
+ // tslint:disable-next-line:component-selector
7
+ selector: 'material-checkbox-widget',
8
+ template: `
9
+ <mat-checkbox *ngIf="boundControl && !showSlideToggle"
10
+ [formControl]="formControl"
11
+ align="left"
12
+ [color]="options?.color || 'primary'"
13
+ [id]="'control' + layoutNode?._id"
14
+ labelPosition="after"
15
+ [name]="controlName"
16
+ (blur)="options.showErrors = true">
17
+ <span *ngIf="options?.title"
18
+ class="checkbox-name"
19
+ [style.display]="options?.notitle ? 'none' : ''"
20
+ [innerHTML]="options?.title"></span>
21
+ </mat-checkbox>
22
+ <mat-checkbox *ngIf="!boundControl && !showSlideToggle"
23
+ align="left"
24
+ [color]="options?.color || 'primary'"
25
+ [disabled]="controlDisabled || options?.readonly"
26
+ [id]="'control' + layoutNode?._id"
27
+ labelPosition="after"
28
+ [name]="controlName"
29
+ [checked]="isChecked"
30
+ (blur)="options.showErrors = true"
31
+ (change)="updateValue($event)">
32
+ <span *ngIf="options?.title"
33
+ class="checkbox-name"
34
+ [style.display]="options?.notitle ? 'none' : ''"
35
+ [innerHTML]="options?.title"></span>
36
+ </mat-checkbox>
37
+ <mat-slide-toggle *ngIf="boundControl && showSlideToggle"
38
+ [formControl]="formControl"
39
+ align="left"
40
+ [color]="options?.color || 'primary'"
41
+ [id]="'control' + layoutNode?._id"
42
+ labelPosition="after"
43
+ [name]="controlName"
44
+ (blur)="options.showErrors = true">
45
+ <span *ngIf="options?.title"
46
+ class="checkbox-name"
47
+ [style.display]="options?.notitle ? 'none' : ''"
48
+ [innerHTML]="options?.title"></span>
49
+ </mat-slide-toggle>
50
+ <mat-slide-toggle *ngIf="!boundControl && showSlideToggle"
51
+ align="left"
52
+ [color]="options?.color || 'primary'"
53
+ [disabled]="controlDisabled || options?.readonly"
54
+ [id]="'control' + layoutNode?._id"
55
+ labelPosition="after"
56
+ [name]="controlName"
57
+ [checked]="isChecked"
58
+ (blur)="options.showErrors = true"
59
+ (change)="updateValue($event)">
60
+ <span *ngIf="options?.title"
61
+ class="checkbox-name"
62
+ [style.display]="options?.notitle ? 'none' : ''"
63
+ [innerHTML]="options?.title"></span>
64
+ </mat-slide-toggle>
65
+ <mat-error *ngIf="options?.showErrors && options?.errorMessage"
66
+ [innerHTML]="options?.errorMessage"></mat-error>`,
67
+ styles: [`
68
+ .checkbox-name { white-space: nowrap; }
69
+ mat-error { font-size: 75%; }
70
+ `],
71
+ })
72
+ export class MaterialCheckboxComponent implements OnInit {
73
+ formControl: AbstractControl;
74
+ controlName: string;
75
+ controlValue: any;
76
+ controlDisabled = false;
77
+ boundControl = false;
78
+ options: any;
79
+ trueValue: any = true;
80
+ falseValue: any = false;
81
+ showSlideToggle = false;
82
+ @Input() layoutNode: any;
83
+ @Input() layoutIndex: number[];
84
+ @Input() dataIndex: number[];
85
+
86
+ constructor(
87
+ private jsf: JsonSchemaFormService
88
+ ) { }
89
+
90
+ ngOnInit() {
91
+ this.options = this.layoutNode.options || {};
92
+ this.jsf.initializeControl(this, !this.options.readonly);
93
+ if (this.controlValue === null || this.controlValue === undefined) {
94
+ this.controlValue = false;
95
+ this.jsf.updateValue(this, this.falseValue);
96
+ }
97
+ if (this.layoutNode.type === 'slide-toggle' ||
98
+ this.layoutNode.format === 'slide-toggle'
99
+ ) {
100
+ this.showSlideToggle = true;
101
+ }
102
+ }
103
+
104
+ updateValue(event) {
105
+ this.options.showErrors = true;
106
+ this.jsf.updateValue(this, event.checked ? this.trueValue : this.falseValue);
107
+ }
108
+
109
+ get isChecked() {
110
+ return this.jsf.getFormControlValue(this) === this.trueValue;
111
+ }
112
+ }
@@ -0,0 +1,108 @@
1
+ import { Component, Input, OnInit } from '@angular/core';
2
+ import { AbstractControl } from '@angular/forms';
3
+ import { JsonSchemaFormService, TitleMapItem, buildTitleMap } from '@ng-formworks/core';
4
+
5
+ // TODO: Change this to use a Selection List instead?
6
+ // https://material.angular.io/components/list/overview
7
+
8
+ @Component({
9
+ // tslint:disable-next-line:component-selector
10
+ selector: 'material-checkboxes-widget',
11
+ template: `
12
+ <div>
13
+ <mat-checkbox type="checkbox"
14
+ [checked]="allChecked"
15
+ [color]="options?.color || 'primary'"
16
+ [disabled]="controlDisabled || options?.readonly"
17
+ [indeterminate]="someChecked"
18
+ [name]="options?.name"
19
+ (blur)="options.showErrors = true"
20
+ (change)="updateAllValues($event)">
21
+ <span class="checkbox-name" [innerHTML]="options?.name"></span>
22
+ </mat-checkbox>
23
+ <label *ngIf="options?.title"
24
+ class="title"
25
+ [class]="options?.labelHtmlClass || ''"
26
+ [style.display]="options?.notitle ? 'none' : ''"
27
+ [innerHTML]="options?.title"></label>
28
+ <ul class="checkbox-list" [class.horizontal-list]="horizontalList">
29
+ <li *ngFor="let checkboxItem of checkboxList"
30
+ [class]="options?.htmlClass || ''">
31
+ <mat-checkbox type="checkbox"
32
+ [(ngModel)]="checkboxItem.checked"
33
+ [color]="options?.color || 'primary'"
34
+ [disabled]="controlDisabled || options?.readonly"
35
+ [name]="checkboxItem?.name"
36
+ (blur)="options.showErrors = true"
37
+ (change)="updateValue()">
38
+ <span class="checkbox-name" [innerHTML]="checkboxItem?.name"></span>
39
+ </mat-checkbox>
40
+ </li>
41
+ </ul>
42
+ <mat-error *ngIf="options?.showErrors && options?.errorMessage"
43
+ [innerHTML]="options?.errorMessage"></mat-error>
44
+ </div>`,
45
+ styles: [`
46
+ .title { font-weight: bold; }
47
+ .checkbox-list { list-style-type: none; }
48
+ .horizontal-list > li { display: inline-block; margin-right: 10px; zoom: 1; }
49
+ .checkbox-name { white-space: nowrap; }
50
+ mat-error { font-size: 75%; }
51
+ `],
52
+ })
53
+ export class MaterialCheckboxesComponent implements OnInit {
54
+ formControl: AbstractControl;
55
+ controlName: string;
56
+ controlValue: any;
57
+ controlDisabled = false;
58
+ boundControl = false;
59
+ options: any;
60
+ horizontalList = false;
61
+ formArray: AbstractControl;
62
+ checkboxList: TitleMapItem[] = [];
63
+ @Input() layoutNode: any;
64
+ @Input() layoutIndex: number[];
65
+ @Input() dataIndex: number[];
66
+
67
+ constructor(
68
+ private jsf: JsonSchemaFormService
69
+ ) { }
70
+
71
+ ngOnInit() {
72
+ this.options = this.layoutNode.options || {};
73
+ this.horizontalList = this.layoutNode.type === 'checkboxes-inline' ||
74
+ this.layoutNode.type === 'checkboxbuttons';
75
+ this.jsf.initializeControl(this);
76
+ this.checkboxList = buildTitleMap(
77
+ this.options.titleMap || this.options.enumNames, this.options.enum, true
78
+ );
79
+ if (this.boundControl) {
80
+ const formArray = this.jsf.getFormControl(this);
81
+ for (const checkboxItem of this.checkboxList) {
82
+ checkboxItem.checked = formArray.value.includes(checkboxItem.value);
83
+ }
84
+ }
85
+ }
86
+
87
+ get allChecked(): boolean {
88
+ return this.checkboxList.filter(t => t.checked).length === this.checkboxList.length;
89
+ }
90
+
91
+ get someChecked(): boolean {
92
+ const checkedItems = this.checkboxList.filter(t => t.checked).length;
93
+ return checkedItems > 0 && checkedItems < this.checkboxList.length;
94
+ }
95
+
96
+ updateValue() {
97
+ this.options.showErrors = true;
98
+ if (this.boundControl) {
99
+ this.jsf.updateArrayCheckboxList(this, this.checkboxList);
100
+ }
101
+ }
102
+
103
+ updateAllValues(event: any) {
104
+ this.options.showErrors = true;
105
+ this.checkboxList.forEach(t => t.checked = event.checked);
106
+ this.updateValue();
107
+ }
108
+ }
@@ -0,0 +1,35 @@
1
+ import { Component, Input, OnInit } from '@angular/core';
2
+ import { AbstractControl } from '@angular/forms';
3
+ import { JsonSchemaFormService } from '@ng-formworks/core';
4
+
5
+ // TODO: Add this control
6
+
7
+ @Component({
8
+ // tslint:disable-next-line:component-selector
9
+ selector: 'material-chip-list-widget',
10
+ template: ``,
11
+ })
12
+ export class MaterialChipListComponent implements OnInit {
13
+ formControl: AbstractControl;
14
+ controlName: string;
15
+ controlValue: any;
16
+ controlDisabled = false;
17
+ boundControl = false;
18
+ options: any;
19
+ @Input() layoutNode: any;
20
+ @Input() layoutIndex: number[];
21
+ @Input() dataIndex: number[];
22
+
23
+ constructor(
24
+ private jsf: JsonSchemaFormService
25
+ ) { }
26
+
27
+ ngOnInit() {
28
+ this.options = this.layoutNode.options || {};
29
+ this.jsf.initializeControl(this);
30
+ }
31
+
32
+ updateValue(event) {
33
+ this.jsf.updateValue(this, event.target.value);
34
+ }
35
+ }