react-native-table-component icon indicating copy to clipboard operation
react-native-table-component copied to clipboard

widthArr or flexArr for cells

Open NishilE opened this issue 5 years ago • 6 comments

How to set different width sizes for each cells ?

NishilE avatar Oct 13 '20 09:10 NishilE

having the same issue. Can't set widthArr to cell.

Sanan4li avatar Mar 16 '21 14:03 Sanan4li

I have a working solution. It involves editing the cell.js file and then passing in the width prop. So it is like this: width={widthArr[cellIndex]}

the widthArr is used for the header component of the table (as you know), then I pass it as a prop to the cell after editing the cell.js file like this:

const textDom = React.isValidElement(data) ? ( <Text style={[textStyle, styles.text]} {...props}> {data} </Text> ) : ( <Text style={[textStyle, styles.text]} {...props}> {data} </Text> );

I do have a concern that under certain conditions this will break but I have tested it with the following as the data prop:

// not sure why, but this does work even though to me it looks like it should not. maybe when the prop is destructured? data={example(cellData, index)}

// only cell data data={cellData}

jmsbrett avatar Mar 21 '21 00:03 jmsbrett

This is actually a better solution using a partial:

const textDom = React.isValidElement(data) ? ( <> {data} </> ) : ( <Text style={[textStyle, styles.text]} {...props}> {data} </Text> );

The cell.js file is in the actual npm module. /react-native-table-component/components/cell.js

jmsbrett avatar Mar 21 '21 13:03 jmsbrett

I have a working solution. It involves editing the cell.js file and then passing in the width prop. So it is like this: width={widthArr[cellIndex]}

the widthArr is used for the header component of the table (as you know), then I pass it as a prop to the cell after editing the cell.js file like this:

const textDom = React.isValidElement(data) ? ( <Text style={[textStyle, styles.text]} {...props}> {data} </Text> ) : ( <Text style={[textStyle, styles.text]} {...props}> {data} </Text> );

I do have a concern that under certain conditions this will break but I have tested it with the following as the data prop:

// not sure why, but this does work even though to me it looks like it should not. maybe when the prop is destructured? data={example(cellData, index)}

// only cell data data={cellData}

Can provide example of this implementation? Thank you.

kevin-mcs avatar Jul 01 '22 11:07 kevin-mcs

@KevinMac19

So I will try to walk you through this.

Please read the entire post before changing any code

This was a solution as of the original posting date.

  1. You must make edits to the actual npm module. So under your node-modules folder in you project find react-native-table-components module and then go to this file path:
node-modules/react-native-table-component/components/cell.js
  1. find the variable named textDom in the cell.js file and replace that code with the following
const textDom = React.isValidElement(data) ? ( <> {data} </> ) : ( <Text style={[textStyle, styles.text]} {...props}> {data} </Text> );
  1. After making the above changes then go to the component in your project (not in the node-modules folder) and add a width as a prop to the import Cell component from react-native-table-components (see below code for an example):
                       <Cell
                            key={cellIndex}
                            style={}
                            textStyle={}
                            data={}
                            width={widthArr[cellIndex]} // this
                            height={40}
                            borderStyle={}
                          />

The widthArr variable is an array. For example if you have 3 rows and then within those rows 3 cells then you would pass the widthArr into the row as a prop

I created this widthArr variable within a useEffect so I can dynamically change the widths depending on the data. But for testing I would recommend just making a variable and keeping it simple.

For example

//one row example
const widthArr = [60] // this is pixels I believe
<React.Fragment>
     <Row
        widthArr={widthArr}
     />
          <TableWrapper>
                   {rowData.map((cellData, cellIndex) => (
                         <TouchableOpacity>
                                    <Cell
                                       key={cellIndex}
                                       style={}
                                       textStyle={}
                                       data={}
                                       width={widthArr[cellIndex]} // this 
                                       height={40}
                                       borderStyle={}
                                    />
                         </TouchableOpacity>
                   ))}
          </TableWrapper>
<React.Fragment>

The above code does not include all of the props that are necessary but should give you an idea of how it works. The reason I did not include all of my code is it is quite complex and it is for a production application. Sorry it took a few days to get back to you.

The main thing to understand is that making the change in the node-module component gives react something (a partial in this case) something to apply a width too. Before it was just rendering the data but now with the partial the code has some structure and can add a width to it.

Let me know if you have anymore questions. Also you might have to rebuild your project after making your changes to the node-module before moving ahead with the rest of the code in your own project.

jmsbrett avatar Jul 02 '22 12:07 jmsbrett

@KevinMac19

So I will try to walk you through this.

Please read the entire post before changing any code

This was a solution as of the original posting date.

  1. You must make edits to the actual npm module. So under your node-modules folder in you project find react-native-table-components module and then go to this file path:
node-modules/react-native-table-component/components/cell.js
  1. find the variable named textDom in the cell.js file and replace that code with the following
const textDom = React.isValidElement(data) ? ( <> {data} </> ) : ( <Text style={[textStyle, styles.text]} {...props}> {data} </Text> );
  1. After making the above changes then go to the component in your project (not in the node-modules folder) and add a width as a prop to the import Cell component from react-native-table-components (see below code for an example):
                       <Cell
                            key={cellIndex}
                            style={}
                            textStyle={}
                            data={}
                            width={widthArr[cellIndex]} // this
                            height={40}
                            borderStyle={}
                          />

The widthArr variable is an array. For example if you have 3 rows and then within those rows 3 cells then you would pass the widthArr into the row as a prop

I created this widthArr variable within a useEffect so I can dynamically change the widths depending on the data. But for testing I would recommend just making a variable and keeping it simple.

For example

//one row example
const widthArr = [60] // this is pixels I believe
<React.Fragment>
     <Row
        widthArr={widthArr}
     />
          <TableWrapper>
                   {rowData.map((cellData, cellIndex) => (
                         <TouchableOpacity>
                                    <Cell
                                       key={cellIndex}
                                       style={}
                                       textStyle={}
                                       data={}
                                       width={widthArr[cellIndex]} // this 
                                       height={40}
                                       borderStyle={}
                                    />
                         </TouchableOpacity>
                   ))}
          </TableWrapper>
<React.Fragment>

The above code does not include all of the props that are necessary but should give you an idea of how it works. The reason I did not include all of my code is it is quite complex and it is for a production application. Sorry it took a few days to get back to you.

The main thing to understand is that making the change in the node-module component gives react something (a partial in this case) something to apply a width too. Before it was just rendering the data but now with the partial the code has some structure and can add a width to it.

Let me know if you have anymore questions. Also you might have to rebuild your project after making your changes to the node-module before moving ahead with the rest of the code in your own project.

Thank you for your response @jmsbrett 👍 It helped me and also I have updated the code for my requirement.

Simulator Screen Shot - iPad (9th generation) - 2022-07-14 at 14 35 46

KevMac19 avatar Jul 14 '22 09:07 KevMac19