I am currently working with Form.io v3.27.1 and I'm in the process of developing a custom layout component, specifically an accordion. I have been referring to the concepts outlined in the CheckMatrix component example as my guide.
Successfully, I have managed to add the accordion component to the toolbox, drag it onto the form, configure it with a custom edit form, and save it. This results in a Bootstrap themed accordion that displays perfectly.
Nevertheless, the issue lies in the fact that the accordion does not enable me to drag and drop other components into the content area, unlike the behavior of other layout components such as Tabs
, Columns
, and Fieldset
.
After reviewing the source code of other layout controls, I believe that I may need to extend NestedComponent
instead of
BaseComponent</code. However, so far, I have been unable to make this adjustment work as intended.</p>
<p>It seems like there might be a small detail that I am overlooking. I just cannot seem to figure out how to create a layout component that will accept other Form.io components as its children.</p>
<p>If anyone has a functional example or any suggestions that I could try to resolve this issue, I would greatly appreciate your help!</p>
<p><a href="https://i.sstatic.net/ZNwVt.png" rel="nofollow noreferrer"></a>
<a href="https://i.sstatic.net/O9VfF.png" rel="nofollow noreferrer"></a></p>
<p><div>
<div>
<pre class="lang-js"><code>import BaseComponent from 'formiojs/components/base/Base';
import NestedComponent from 'formiojs/components/nested/NestedComponent';
import Components from 'formiojs/components/Components';
import * as editForm from './Accordian.form';
export default class AccordionComponent extends BaseComponent {
/**
* Define what the default JSON schema for this component is. We will derive from the BaseComponent
* schema and provide our overrides to that.
* @return {*}
*/
static schema() {
return BaseComponent.schema({
type: 'accordion',
label: 'Sections',
input: false,
key: 'accordion',
persistent: false,
components: [{
label: 'Section 1',
key: 'section1',
components: []
}]
});
}
/**
* Register this component to the Form Builder by providing the "builderInfo" object.
*/
static get builderInfo() {
return {
title: 'Accordion',
group: 'custom',
icon: 'fa fa-tasks',
weight: 70,
schema: AccordionComponent.schema()
};
}
/**
* Tell the renderer how to build this component using DOM manipulation.
*/
build() {
this.element = this.ce('div', {
class: `form-group formio-component formio-component-accordion ${this.className}`
}, [
this.ce('app-formio-accordian', {
components: JSON.stringify(this.component.components)
})
]);
}
elementInfo() {
return super.elementInfo();
}
getValue() {
return super.getValue();
}
setValue(value) {
super.setValue(value);
}
}
// Use the table component edit form.
AccordionComponent.editForm = editForm.default;
// Register the component to the Formio.Components registry.
Components.addComponent('accordion', AccordionComponent);
<div class="accordion" id="formioAccordionPreview" *ngIf="components">
<div class="card" *ngFor="let component of components; first as isFirst">
<div class="card-header" id="heading-{{component.key}}">
<h2 class="mb-0">
<button type="button" class="btn btn-link" data-toggle="collapse" data-target="#collapse-{{component.key}}">{{component.label}}</button>
</h2>
</div>
<div id="collapse-{{component.key}}" class="collapse" [class.show]="isFirst" aria-labelledby="heading-{{component.key}}" data-parent="#formioAccordionPreview">
<div class="card-body">
<p>I should be able to 'Drag and Drop a form component' here.</p>
</div>
</div>
</div>
</div>