Skip to content

Commit

Permalink
formly type: add multicheckbox type
Browse files Browse the repository at this point in the history
This type can be used on an array type of the json schema
to have multiple checkboxes.

Co-Authored-by: Bertrand Zuchuat <bertrand.zuchuat@rero.ch>
  • Loading branch information
Garfield-fr committed Nov 23, 2022
1 parent 7dd3454 commit 098a9b0
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 7 deletions.
47 changes: 46 additions & 1 deletion projects/ng-core-tester/src/app/record/editor/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
"selectMultiple",
"markdown",
"textarea",
"email"
"email",
"array_with_multicheckbox"
],
"required": [
"required"
Expand Down Expand Up @@ -826,6 +827,50 @@
}
}
}
},
"array_with_multicheckbox": {
"title": "Array with multiple checkbox",
"type": "array",
"minItems": 1,
"default": [
"checkbox1",
"checkbox2"
],
"items": {
"type": "string",
"enum": [
"checkbox1",
"checkbox2",
"checkbox3",
"checkbox4"
]
},
"widget": {
"formlyConfig": {
"type": "multicheckbox",
"templateOptions": {
"options": [
{
"label": "Checkbox 1",
"value": "checkbox1",
"disabled": true
},
{
"label": "Checkbox 2",
"value": "checkbox2"
},
{
"label": "Checkbox 3",
"value": "checkbox3"
},
{
"label": "Checkbox 4",
"value": "checkbox4"
}
]
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* RERO angular core
* Copyright (C) 2022 RERO
*
* This program 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, version 3 of the License.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component } from '@angular/core';
import { FieldType, FormlyFieldConfig } from '@ngx-formly/core';

@Component({
selector: 'ng-core-editor-formly-field-multicheckbox',
template: `
<div>
<div
*ngFor="let option of to.options | formlySelectOptions:field | async; let i = index;"
[ngClass]="{
'form-check': to.style === 'stacked',
'form-check-inline': to.style === 'inline'
}"
>
<input
type="checkbox"
class="form-check-input"
[id]="id + '_' + i"
[value]="option.value"
[checked]="isChecked(option)"
[disabled]="formControl.disabled || option.disabled"
(change)="onChange(option.value, $event.target.checked)"
>
<label
class="form-check-label"
[for]="id + '_' + i"
[ngClass]="{
'text-dark': (!formControl.disabled && !option.disabled),
'text-secondary': (formControl.disabled || option.disabled)
}"
>{{ option.label }}</label>
</div>
</div>
`,
})
export class MulticheckboxComponent extends FieldType {
/** Default options */
defaultOptions: Partial<FormlyFieldConfig> = {
templateOptions: {
options: [],
style: 'stacked' // 'stacked' | 'inline'
}
};

/**
* Adds or removes the value of a checkbox in the list of values.
* @param value - checkbox value
* @param checked - True if checked
*/
onChange(value: any, checked: boolean): void {
this.formControl.markAsDirty();
const formValue = (this.formControl.value || []);
if (checked) {
formValue.push(value);
} else {
formValue.splice(formValue.indexOf(value), 1);
}
this.formControl.patchValue(formValue);
this.formControl.markAsTouched();
}

/**
* Activates the checkbox if the value exists in the list.
* @param option - current ckeckbox
* @return True if the current checkbox value exists in the list of values
*/
isChecked(option: any): boolean {
const value = this.formControl.value;

return value.includes(option.value);
}
}
15 changes: 9 additions & 6 deletions projects/rero/ng-core/src/lib/record/record.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* RERO angular core
* Copyright (C) 2020 RERO
* Copyright (C) 2020-2022 RERO
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
Expand Down Expand Up @@ -40,6 +40,7 @@ import { ArrayTypeComponent } from './editor/type/array-type/array-type.componen
import { CustomSelectFieldComponent } from './editor/type/custom-select/custom-select.component';
import { DatepickerTypeComponent } from './editor/type/datepicker-type.component';
import { MarkdownFieldComponent } from './editor/type/markdown/markdown.component';
import { MulticheckboxComponent } from './editor/type/multicheckbox.component';
import { MultiSchemaTypeComponent } from './editor/type/multischema/multischema.component';
import { ObjectTypeComponent } from './editor/type/object-type/object-type.component';
import { RemoteTypeaheadComponent } from './editor/type/remote-typeahead/remote-typeahead.component';
Expand All @@ -55,21 +56,21 @@ import { FormFieldWrapperComponent } from './editor/wrappers/form-field-wrapper/
import { HideWrapperComponent } from './editor/wrappers/hide-wrapper/hide-wrapper.component';
import { HorizontalWrapperComponent } from './editor/wrappers/horizontal-wrapper/horizontal-wrapper.component';
import { ToggleWrapperComponent } from './editor/wrappers/toggle-wrapper/toggle-wrappers.component';
import { ExportButtonComponent } from './export-button/export-button.component';
import { RecordFilesComponent } from './files/files.component';
import { RecordRoutingModule } from './record-routing.module';
import { RecordService } from './record.service';
import { RecordSearchAggregationComponent } from './search/aggregation/aggregation.component';
import { BucketsComponent } from './search/aggregation/buckets/buckets.component';
import { AggregationDateRangeComponent } from './search/aggregation/date-range/date-range.component';
import { ListFiltersComponent } from './search/aggregation/list-filters/list-filters.component';
import { BucketNamePipe } from './search/aggregation/pipe/bucket-name.pipe';
import { AggregationSliderComponent } from './search/aggregation/slider/slider.component';
import { RecordSearchPageComponent } from './search/record-search-page.component';
import { RecordSearchComponent } from './search/record-search.component';
import { JsonComponent } from './search/result/item/json.component';
import { RecordSearchResultComponent } from './search/result/record-search-result.component';
import { RecordSearchResultDirective } from './search/result/record-search-result.directive';
import { ExportButtonComponent } from './export-button/export-button.component';
import { ListFiltersComponent } from './search/aggregation/list-filters/list-filters.component';
import { BucketNamePipe } from './search/aggregation/pipe/bucket-name.pipe';

@NgModule({
declarations: [
Expand Down Expand Up @@ -110,7 +111,8 @@ import { BucketNamePipe } from './search/aggregation/pipe/bucket-name.pipe';
AggregationDateRangeComponent,
ExportButtonComponent,
ListFiltersComponent,
BucketNamePipe
BucketNamePipe,
MulticheckboxComponent
],
imports: [
// NOTE : BrowserAnimationModule **should** be include in application core module.
Expand Down Expand Up @@ -164,7 +166,8 @@ import { BucketNamePipe } from './search/aggregation/pipe/bucket-name.pipe';
{ name: 'remoteTypeahead', component: RemoteTypeaheadComponent },
{ name: 'textarea', component: TextareaFieldComponent },
{ name: 'select', component: CustomSelectFieldComponent },
{ name: 'markdown', component: MarkdownFieldComponent }
{ name: 'markdown', component: MarkdownFieldComponent },
{ name: 'multicheckbox', component: MulticheckboxComponent }
],
wrappers: [
{ name: 'toggle-switch', component: ToggleWrapperComponent },
Expand Down

0 comments on commit 098a9b0

Please sign in to comment.