optimajet / formengine

Drag & Drop Form Builder Library for React.
https://formengine.io
39 stars 8 forks source link

Support for Table components #48

Open danhnguyeen opened 1 week ago

danhnguyeen commented 1 week ago

Hi there,

Do you have any plans for Table components? I tried implementing it with a custom component as bellow, but it still didn’t work as expected.

image
import React from 'react';
import { define, number, boolean, node } from '@react-form-builder/core';

export const customTable = define(
  ({
    rows,
    columns,
    hasBorder,
    cellPadding,
    ...props
  }: {
    rows: number;
    columns: number;
    hasBorder: boolean;
    cellPadding: number;
    [key: string]: React.ReactNode;
  }) => {
    const tableStyle = {
      width: '100%',
      borderCollapse: 'collapse' as const,
      border: hasBorder ? '1px solid #ddd' : 'none',
    };

    const cellStyle = {
      border: hasBorder ? '1px solid #ddd' : 'none',
      padding: `${cellPadding}px`,
    };

    return (
      <table style={tableStyle} {...props}>
        <tbody>
          {Array.from({ length: rows }).map((_, rowIndex) => (
            <tr key={rowIndex}>
              {Array.from({ length: columns }).map((_, colIndex) => (
                <td key={colIndex} style={cellStyle}>
                  {props[`cell${rowIndex}${colIndex}`]}
                </td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
    );
  },
  'CustomTable'
)
  .name('Custom Table')
  .props({
    rows: number.named('Number of Rows').default(3),
    columns: number.named('Number of Columns').default(3),
    hasBorder: boolean.named('Show Borders').default(true),
    cellPadding: number.named('Cell Padding').default(8),
    ...Object.fromEntries(
      Array.from({ length: 3 }).flatMap((_, rowIndex) =>
        Array.from({ length: 3 }).map((_, colIndex) => [
          `cell${rowIndex}${colIndex}`,
          node.named(`Cell ${rowIndex},${colIndex}`),
        ])
      )
    ),
  });

The issue in my code is that the number of cell${rowIndex}${colIndex} elements is fixed. I’m not sure how to dynamically render nodes based on flexible column/row inputs.

I’m considering allowing users to input the number of columns and rows before rendering the table. However, I haven’t been able to make it work yet

image
optimajet commented 6 days ago

Hi @danhnguyeen,

Do you want something like an editable table or just a component to display data in a table?

danhnguyeen commented 5 days ago

Hi @danhnguyeen,

Do you want something like an editable table or just a component to display data in a table?

Hi @optimajet,
Thanks for your reply. For now, I just need a simple table that allows users to define the number of columns and rows. Each table cell should be a node so users can drag and drop any existing components into it. Is it possible? Thank you

optimajet commented 4 days ago

Basically, we have something similar to what you need to create such a component. If you look at the Wizard component, you will see that there is a labels property inside the Wizard component. When new items are added, new steps are added to the Wizard. Each step is a separate child component that has a node inside it for adding components.

And you can dynamically change the number of rows and columns based on changing the component properties.

There are some important points:

If you want to try this approach - we can share the code of the Wizard component.

We also have plans to add a similar component based on the Repeater component. Only the number of rows in the table will be adjusted dynamically based on the Repeater component data.

danhnguyeen commented 4 days ago

Hi @optimajet, Yes, the Wizard component seems quite similar to the concept of my Table component. Since my Table has fixed data, I may not need the Repeater component. If possible, could you please share the code for the Wizard component? That would be really helpful. Thank you

optimajet commented 3 days ago

@danhnguyeen Here is a part of the source code of @react-form-builder/components-rsuite package.

RsWizard.zip

danhnguyeen commented 23 hours ago

@optimajet Thank you. I will take a look at it