formio / formio.js

JavaScript powered Forms with JSON Form Builder
https://formio.github.io/formio.js
MIT License
1.88k stars 1.06k forks source link

[Question] How can I extend the default components in an angular project? #2124

Closed gfPedro closed 8 months ago

gfPedro commented 4 years ago

Hello,

I'm trying to extend the functionality of data grid component. I want to have a data grid and I would also like to be able to insert data from uploaded files.

I tried with this code and It gives errors because super is NestedComponent instead of DataGridComponent (error below).

How can I extend datagrid?

datagridComonent.ts:

import * as _ from "lodash";
import { Components } from "formiojs";

const DatagridComponent = Components.components.datagrid;

export default class CustomDatagridComponent extends DatagridComponent {

    static editForm() {
        return Components.components.datagrid.editForm();
    }

    static schema() {
        return DatagridComponent.schema({
            type: 'customDatagrid',
        });
    }

    static get builderInfo() {
        return {
            title: 'Custom DataGrid',
            group: 'basic',
            icon: 'fa fa-table',
            weight: 70,
            schema: CustomDatagridComponent.schema(),
        };
    }

    init() {
        super.init();
    }

    render() {
        const columns = super.getColumns();
        return super.renderTemplate('customDatagrid', {
            rows: super.getRows(),
            columns: columns,
            groups: super.hasRowGroups() ? super.getGroups() : [],
            visibleColumns: super.visibleColumns,
            hasToggle: _.get(this, 'component.groupToggle', false),
            hasHeader: super.hasHeader(),
            hasExtraColumn: super.hasExtraColumn(),
            hasAddButton: super.hasAddButton(),
            hasRemoveButtons: super.hasRemoveButtons(),
            hasTopSubmit: super.hasTopSubmit(),
            hasBottomSubmit: super.hasBottomSubmit(),
            hasGroups: super.hasRowGroups(),
            numColumns: columns.length + (super.hasExtraColumn() ? 1 : 0),
            datagridKey: super.datagridKey,
            allowReorder: super.allowReorder,
            builder: super.builderMode,
            canAddColumn: super.canAddColumn,
            placeholder: super.renderTemplate('builderPlaceholder', {
                position: super.componentComponents.length,
            }),
        });
    }
}

customDatagrid:

export function getTemplateDatagrid() {
    return '<table class="table datagrid-table table-bordered
    {{ ctx.component.striped ? 'table-striped' : ''}}
    {{ ctx.component.hover ? 'table-hover' : ''}}
    {{ ctx.component.condensed ? 'table-sm' : ''}}
    " {% if (ctx.component.layoutFixed) { %}style="table-layout: fixed;"{% } %}>
  {% if (ctx.hasHeader) { %}
  <thead>
    <tr>
      {% if (ctx.component.reorder) { %}<th></th>{% } %}
      {% ctx.columns.forEach(function(col) { %}
        <th class="{{col.validate && col.validate.required ? 'field-required' : ''}}">
          {{ col.hideLabel ? '' : ctx.t(col.label || col.title) }}
          {% if (col.tooltip) { %} <i ref="tooltip" class="{{ctx.iconClass('question-sign')}} text-muted"></i>{% } %}
        </th>
      {% }) %}
      {% if (ctx.hasExtraColumn) { %}
      <th>
        {% if (!ctx.builder && ctx.hasAddButton && ctx.hasTopSubmit) { %}
        <button class="btn btn-primary formio-button-add-row" ref="{{ctx.datagridKey}}-addRow">
          <i class="{{ctx.iconClass('plus')}}"></i>{{ctx.t('Add Another')}}
        </button>
        {% } %}
      </th>
      {% } %}
    </tr>
  </thead>
  {% } %}
  <tbody ref="{{ctx.datagridKey}}-tbody">
    {% ctx.rows.forEach(function(row, index) { %}
    {% if (ctx.hasGroups && ctx.groups[index]) { %}
    <tr ref="{{ctx.datagridKey}}-group-header" class="datagrid-group-header{{ctx.hasToggle ? ' clickable' : ''}}">
      <td
        ref="{{ctx.datagridKey}}-group-label"
        colspan="{{ctx.numColumns}}"
        class="datagrid-group-label">{{ctx.groups[index].label}}</td>
    </tr>
    {% } %}
    <tr ref="{{ctx.datagridKey}}-row">
      {% if (ctx.component.reorder) { %}
        <td>
          <button type="button" class="formio-drag-button btn btn-default fa fa-bars"></button>
        </td>
      {% } %}
      {% ctx.columns.forEach(function(col) { %}
        <td ref="{{ctx.datagridKey}}">
          {{row[col.key]}}
        </td>
      {% }) %}
      {% if (ctx.hasExtraColumn) { %}
        {% if (!ctx.builder && ctx.hasRemoveButtons) { %}
        <td>
          <button type="button" class="btn btn-secondary formio-button-remove-row" ref="{{ctx.datagridKey}}-removeRow">
            <i class="{{ctx.iconClass('remove-circle')}}"></i>
          </button>
        </td>
        {% } %}
        {% if (ctx.canAddColumn) { %}
        <td ref="{{ctx.key}}-container">
          {{ctx.placeholder}}
        </td>
        {% } %}
      {% } %}
    </tr>
    {% }) %}
  </tbody>
  {% if (!ctx.builder && ctx.hasAddButton && ctx.hasBottomSubmit) { %}
  <tfoot>
    <tr>
      <td colspan="{{ctx.numColumns + 1}}">
        <button class="btn btn-primary formio-button-add-row" ref="{{ctx.datagridKey}}-addRow">
          <i class="{{ctx.iconClass('plus')}}"></i> {{ctx.t(ctx.component.addAnother || 'Add Another')}}
        </button>
      </td>
    </tr>
  </tfoot>
  {% } %}
</table>';
}

Error:

ERROR in src/app/pages/formio/formulario/CustomDatagrid.ts(34,31): error TS2339: Property 'getColumns' does not exist on type 'NestedComponent'.
    src/app/pages/formio/formulario/CustomDatagrid.ts(36,25): error TS2339: Property 'getRows' does not exist on type 'NestedComponent'.
    src/app/pages/formio/formulario/CustomDatagrid.ts(38,27): error TS2339: Property 'hasRowGroups' does not exist on type 'NestedComponent'.
    src/app/pages/formio/formulario/CustomDatagrid.ts(38,50): error TS2339: Property 'getGroups' does not exist on type 'NestedComponent'.
    src/app/pages/formio/formulario/CustomDatagrid.ts(39,35): error TS2339: Property 'visibleColumns' does not exist on type 'NestedComponent'.
    src/app/pages/formio/formulario/CustomDatagrid.ts(41,30): error TS2339: Property 'hasHeader' does not exist on type 'NestedComponent'.
    src/app/pages/formio/formulario/CustomDatagrid.ts(42,35): error TS2339: Property 'hasExtraColumn' does not exist on type 'NestedComponent'.
    src/app/pages/formio/formulario/CustomDatagrid.ts(43,33): error TS2339: Property 'hasAddButton' does not exist on type 'NestedComponent'.
    src/app/pages/formio/formulario/CustomDatagrid.ts(44,37): error TS2339: Property 'hasRemoveButtons' does not exist on type 'NestedComponent'.
    src/app/pages/formio/formulario/CustomDatagrid.ts(45,33): error TS2339: Property 'hasTopSubmit' does not exist on type 'NestedComponent'.
    src/app/pages/formio/formulario/CustomDatagrid.ts(46,36): error TS2339: Property 'hasBottomSubmit' does not exist on type 'NestedComponent'.
    src/app/pages/formio/formulario/CustomDatagrid.ts(47,30): error TS2339: Property 'hasRowGroups' does not exist on type 'NestedComponent'.
    src/app/pages/formio/formulario/CustomDatagrid.ts(48,49): error TS2339: Property 'hasExtraColumn' does not exist on type 'NestedComponent'.
    src/app/pages/formio/formulario/CustomDatagrid.ts(49,32): error TS2339: Property 'datagridKey' does not exist on type 'NestedComponent'.
    src/app/pages/formio/formulario/CustomDatagrid.ts(50,33): error TS2339: Property 'allowReorder' does not exist on type 'NestedComponent'.
    src/app/pages/formio/formulario/CustomDatagrid.ts(52,33): error TS2339: Property 'canAddColumn' does not exist on type 'NestedComponent'.

I also tried importing this Components class:

import Components from 'formiojs/components/Components';

This way it compiles and I get to see my component but it doesn't have any functionality and it doesn't show the options to change configuration os delete the component from the form.

I get to have those options available if I cmomment out the render method in my class with any of the two imports but still it doesn't show any funtionality from datagrid. i cannot drag and drop any other component into my custom component.

travist commented 4 years ago

I would do all of this within a Module. See https://github.com/formio/formio.js/wiki/Modules.

With this, you can include the templates along with the extended class and it will register correctly.

VikkiAlenn commented 8 months ago

We're currently addressing a backlog of GitHub issues, and as part of this effort, some inactive issues may be marked as closed. This isn't a dismissal, but a step toward more efficient tracking.

Closing this thread as it is outdated. Please re-open if it is still relevant. Thank you for your contribution!