Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DataTable: Unable to use Custom Columns when has Dynamic Columns rendering #6028

Closed
gabrielo91 opened this issue Feb 21, 2024 · 5 comments
Closed
Labels
Resolution: Invalid Issue or pull request is not valid in the latest version

Comments

@gabrielo91
Copy link

Describe the bug

I'm trying to use the DataTable component with dynamic columns, just like the docs explain here, I have used the following code. As you can see I have created a component called SpecialColumn which should render each column, however, I noticed that this component is not being used at all, I noticed that my changes were not applied or even that a throw new Error did not break the app. Is this behavior expected? how can I overwrite the default behavior and use my custom element to render the columns?

import React, { useState, useEffect } from 'react';
import { DataTable } from 'primereact/datatable';
import { Column } from 'primereact/column';
import { ProductService } from './service/ProductService';

function SpecialColumn({ col }) {
  throw new Error('this should break all');
  return (
    <Column key={col.field} field={col.field} header={`custom-${col.header}`} />
  );
}

export default function DynamicColumnsDemo() {
  const [products, setProducts] = useState([]);
  const columns = [
    { field: 'code', header: 'Code' },
    { field: 'name', header: 'Name' },
    { field: 'category', header: 'Category' },
    { field: 'quantity', header: 'Quantity' },
  ];

  useEffect(() => {
    ProductService.getProductsMini().then((data) => setProducts(data));
  }, []);

  return (
    <div className="card">
      <DataTable value={products} tableStyle={{ minWidth: '50rem' }}>
        {columns.map((col, i) => (
          <SpecialColumn key={i} {...col} />
        ))}
      </DataTable>
    </div>
  );
}

The code can be tested and edited in this sandbox

Reproducer

https://stackblitz.com/edit/wapju4?file=src%2FApp.jsx

PrimeReact version

10.5.1

React version

18.x

Language

TypeScript

Build / Runtime

Create React App (CRA)

Browser(s)

No response

Steps to reproduce the behavior

  1. just run the demo, the app should break but it does not do it

Expected behavior

The app should use the SpecialColumn component

@gabrielo91 gabrielo91 added the Status: Needs Triage Issue will be reviewed by Core Team and a relevant label will be added as soon as possible label Feb 21, 2024
@melloware melloware added Resolution: Invalid Issue or pull request is not valid in the latest version and removed Status: Needs Triage Issue will be reviewed by Core Team and a relevant label will be added as soon as possible labels Feb 22, 2024
@melloware
Copy link
Member

melloware commented Feb 22, 2024

@gabrielo91 this is not supported because Columns are not components that render themselves: #2052 (comment)

This has been asked about many times in the past: #2268

@gabrielo91
Copy link
Author

gabrielo91 commented Feb 22, 2024

@melloware Thank you in advance for clarifying my concerns. I'm trying to understand the concept that "Columns are not components that render themselves." After reviewing the issues, I'm still a bit confused about the practical implications of this. Specifically, I have a few questions:

  1. If I use dynamic rendering for columns, will I be unable to control or define how filters are rendered for each column?
  2. In this case, is it correct to assume I cannot pass specific options to each MultiSelect if I'm using dynamic rendering for columns?
  3. Is it possible to use a combination of pre-defined fixed columns and dynamically render standard ones using a map? Something like the example below.

Could you please provide some guidance on these points?

const columns = [
  { field: 'code', header: 'Code' },
  { field: 'name', header: 'Name' },
  { field: 'category', header: 'Category' },
  { field: 'quantity', header: 'Quantity' },
];

const getStandardColumns = () => {
  return columns.map((col, i) => {
    // custom operations
    return (
      <Column
        key={col.field}
        field={col.field}
        header={`custom-${col.header}`}
      />
    );
  });
};

export default function DynamicColumnsDemo() {
  const [products, setProducts] = useState([]);

  useEffect(() => {
    ProductService.getProductsMini().then((data) => setProducts(data));
  }, []);

  return (
    <div className="card">
      <DataTable value={products} tableStyle={{ minWidth: '50rem' }}>
        <>
          <Column
            key={col.field}
            field={col.field}
            header={`custom-${col.header}`}
          />
          {getStandardColumns()}
        </>
      </DataTable>
    </div>
  );
}

@melloware
Copy link
Member

isnt the answer right here: https://primereact.org/datatable/#dynamic_columns

You create a JSON object that has all the dynamic column properties including filters. I don't understand what your issue is?

const columns = [
  { field: 'code', header: 'Code', filterElement: <YourFilter /> },

@gabrielo91
Copy link
Author

@melloware Ok, you have solved it, we didn't know that the object you pass to render columns supported the filterElement as well, that's why we tried putting that responsibility into a custom column that would render each type of filter for each column I think we can work with this from now.

Thanks very much for your help

@melloware
Copy link
Member

Yep ANY property on the column can be in your dynamic JSON.

@melloware melloware closed this as not planned Won't fix, can't repro, duplicate, stale Feb 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Invalid Issue or pull request is not valid in the latest version
Projects
None yet
Development

No branches or pull requests

2 participants