Skip to content

Commit

Permalink
feat(material/form-builder): add support for range field properties
Browse files Browse the repository at this point in the history
  • Loading branch information
trik committed Mar 10, 2022
1 parent cab93d5 commit e55d51f
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/core/forms/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ export * from './utils/fields/create-field';
export * from './utils/fields/is-custom-field-with-choices';
export * from './utils/fields/is-field-with-choices';
export * from './utils/fields/is-number-field';
export * from './utils/fields/is-range-field';
export * from './utils/fields-instances/create-field-instance';
export * from './utils/fields-instances/create-field-with-choices-instance';
export * from './utils/forms/build-form-string-identifier';
Expand Down
31 changes: 31 additions & 0 deletions src/core/forms/utils/fields/is-range-field.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* @license
* Copyright (C) Gnucoop soc. coop.
*
* This file is part of the Advanced JSON forms (ajf).
*
* Advanced JSON forms (ajf) is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* Advanced JSON forms (ajf) is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
* General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Advanced JSON forms (ajf).
* If not, see http://www.gnu.org/licenses/.
*
*/

import {AjfField} from '../../interface/fields/field';
import {AjfFieldType} from '../../interface/fields/field-type';

/**
* It is true if the field is a range field
*/
export function isRangeField(field: AjfField): boolean {
return field.fieldType === AjfFieldType.Range;
}
1 change: 1 addition & 0 deletions src/dev-app/mat-form-builder/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ export const formSchema: any = {
{parent: 1005, id: 1006, name: 'date input', label: 'A date', nodeType: 0, fieldType: 9},
{parent: 1006, id: 1007, name: 'time', label: 'Time', nodeType: 0, fieldType: 10},
{parent: 1007, id: 1008, name: 'barcode', label: 'Barcode', nodeType: 0, fieldType: 13},
{parent: 1008, id: 1009, name: 'range', label: 'Range', nodeType: 0, fieldType: 17},
],
},
{
Expand Down
9 changes: 9 additions & 0 deletions src/material/form-builder/form-builder-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
AjfNodeGroup,
AjfNodesOperation,
AjfNodeType,
AjfRangeField,
AjfRepeatingContainerNode,
AjfRepeatingSlide,
AjfSlide,
Expand All @@ -47,6 +48,7 @@ import {
isContainerNode,
isField,
isFieldWithChoices,
isRangeField,
isRepeatingContainerNode,
isSlidesNode,
maxDigitsValidation,
Expand Down Expand Up @@ -891,6 +893,13 @@ export class AjfFormBuilderService {
createCondition({condition: t}),
);
}

if (isRangeField(field)) {
const rf = field as AjfRangeField;
rf.start = properties.start;
rf.end = properties.end;
rf.step = properties.step;
}
}

this._editedNodeEntry.next(null);
Expand Down
32 changes: 32 additions & 0 deletions src/material/form-builder/node-properties.html
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,38 @@ <h3>{{'Properties'|transloco}}</h3>
</mat-form-field>
</div>
</ng-template>
<ng-template [ngIf]="isRangeField(ne!.node)">
<div class="ajf-prop">
<mat-form-field>
<input
matInput
type="number"
formControlName="start"
[placeholder]="'Start' | transloco"
/>
</mat-form-field>
</div>
<div class="ajf-prop">
<mat-form-field>
<input
matInput
type="number"
formControlName="end"
[placeholder]="'End' | transloco"
/>
</mat-form-field>
</div>
<div class="ajf-prop">
<mat-form-field>
<input
matInput
type="number"
formControlName="step"
[placeholder]="'Step' | transloco"
/>
</mat-form-field>
</div>
</ng-template>
<div class="ajf-prop">
<div class="ajf-header">
<label>{{ 'Validation' | transloco }}</label>
Expand Down
26 changes: 26 additions & 0 deletions src/material/form-builder/node-properties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ import {
AjfFieldWithChoices,
AjfNode,
AjfNumberField,
AjfRangeField,
AjfRepeatingContainerNode,
isField,
isFieldWithChoices,
isNumberField,
isRangeField,
isRepeatingContainerNode,
} from '@ajf/core/forms';
import {AjfCondition, alwaysCondition, neverCondition} from '@ajf/core/models';
Expand Down Expand Up @@ -85,6 +87,14 @@ function checkDigitsValidity(c: AbstractControl): {[key: string]: any} | null {
return null;
}

function checkRangeValidity(c: AbstractControl): {[key: string]: any} | null {
const {start, end} = c.value;
if (start != null && end != null && start > end) {
return {range: 'End must be greater than start'};
}
return null;
}

export interface ValidationCondition {
condition: string;
errorMessage: string;
Expand Down Expand Up @@ -394,6 +404,10 @@ export class AjfFbNodeProperties implements OnDestroy {
return isField(node) && isFieldWithChoices(node as AjfField);
}

isRangeField(node: AjfNode): boolean {
return isField(node) && isRangeField(node as AjfField);
}

save(): void {
this._saveEvt.emit();
}
Expand Down Expand Up @@ -447,6 +461,7 @@ export class AjfFbNodeProperties implements OnDestroy {
.subscribe(([_, formGroup]) => {
const fg = formGroup as FormGroup;
const val = {...fg.value, conditionalBranches: this._conditionalBranches};
console.log(val);
this._service.saveNodeEntry(val);
});
}
Expand Down Expand Up @@ -573,6 +588,17 @@ export class AjfFbNodeProperties implements OnDestroy {
validators.push(checkDigitsValidity);
}

if (this.isRangeField(n.node)) {
const rangeField = <AjfRangeField>n.node;
const {start, end, step} = rangeField;

controls.start = start;
controls.end = end;
controls.step = step;

validators.push(checkRangeValidity);
}

if (this.isFieldWithChoices(n.node)) {
const fieldWithChoices = <AjfFieldWithChoices<any>>n.node;

Expand Down
3 changes: 3 additions & 0 deletions tools/public_api_guard/core/forms.md
Original file line number Diff line number Diff line change
Expand Up @@ -1385,6 +1385,9 @@ export function isFieldWithChoices(field: AjfField): boolean;
// @public
export function isNumberField(field: AjfField): boolean;

// @public
export function isRangeField(field: AjfField): boolean;

// @public
export function isRepeatingContainerNode(node: AjfNode): boolean;

Expand Down
2 changes: 2 additions & 0 deletions tools/public_api_guard/material/form-builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,8 @@ class AjfFbNodeProperties implements OnDestroy {
// (undocumented)
isNumericField(node: AjfNode): boolean;
// (undocumented)
isRangeField(node: AjfNode): boolean;
// (undocumented)
isRepeatingContainerNode: (nodeEntry: AjfFormBuilderNodeEntry | null) => boolean;
// (undocumented)
get nextSlideCondition(): string;
Expand Down

0 comments on commit e55d51f

Please sign in to comment.