dmk99 / react-pdf-table

Storybook Available
https://dmk99.github.io/react-pdf-table
MIT License
152 stars 62 forks source link

How to Add Table Footer? #26

Open deividkamui opened 4 years ago

deividkamui commented 4 years ago

Hi is there a way to add a footer to a table lets say a Total Count? I tried this but does not work:

<Table data={this.state.LstEntities}>
                               <TableHeader>
                                    <TableCell weighting={0.6}>
                                        Entity
                                    </TableCell>
                                    <TableCell weighting={0.4}>
                                        Count
                                    </TableCell>
                                </TableHeader>
                                <TableBody>
                                    <DataTableCell style={pdfStyles.dataTableRow} weighting={0.6} getContent={(r: ISPColorCodedRecord) => r.Title} />
                                    <DataTableCell style={pdfStyles.dataTableRow} weighting={0.4} getContent={(r: ISPColorCodedRecord) => { return this.GetRecordsByEntity(r.Id).length; }} />
                                </TableBody>
                                <TableRow>
                                    <TableCell weighting={0.6}>
                                        Total
                                    </TableCell>
                                    <TableCell weighting={0.4}>
                                        {this.state.Records.length}
                                    </TableCell>
                                </TableRow>
</Table>
dmk99 commented 4 years ago

Hi,

Unfortunately this is not supported in the current version of the library. One way that you could mimic something similar would be to have the final row in the data array be the "total" row.

You could then have a flag on the data to indicate that it should be rendered as a "total" row. From there you could override what is returned in getContent on the DataTableCell component.

e.g.

<DataTableCell style={pdfStyles.dataTableRow} weighting={0.6} getContent={(r) => {
   if(r.isTotal) {
     return <Text style={{fontWeight: "bold"}}>Total</Text>
   }

   return r.Title;
}}/>

The above code is just for illustrative purposes and may not work out of the box. You MUST return a valid react-pdf component when rendering a DataTableCell. e.g. Text, View etc.

deividkamui commented 4 years ago

Thank you for your reply, I was thinking on implementing a solution similar to the one that you describe.

I also tried to derived a class from TableHeader and Change the Table class for something like this, but I'm not sure if It would work it is just an idea:

export class Table extends React.PureComponent<TableProps> {
    render() {
        let tableHeader: JSX.Element = null;
        let tableBody: JSX.Element = null;
        let tableFooter: JSX.Element = null;

        React.Children.forEach(this.props.children, (c: any) => {
            if (c.type === TableHeader) {
                tableHeader = c;
            } else if (c.type === TableBody) {
                tableBody = React.cloneElement(c, {
                    data: c.props.data ?? this.props.data ?? []
                });
            } else if (c.Type === TableFooter) {
                tableFooter = c;
            }
        });

        return (
            <View
                style={{
                    width: "100%",
                }}
            >
                {tableHeader}
                {tableBody}
                {tableFooter}
            </View>
        );
    }
}
dmk99 commented 4 years ago

I think that definitely is something that can be implemented. It would be similar to TableBody except the data passed through would be all the items in the table.

I will create a task to create the TableFooter. Thank you for your feedback.