I’m having trouble adding checkboxes to rows using this react-table package https://react-table.js.org/#/story/readme
I’m trying to add a checkbox to each row in my table. I tried adding “checkbox” to the “Cell” value seen in the columns area, however, it seems that it doesn’t work well with the pagination. Once I click next page and then back it forgets all of the previously checked products. How do I maintain their state?
I added a key, and it prevents the element from being checked on all pages, however, it doesn’t remember it when I change back and forth on the pages. So I just need to store its “on state” now.
Cell: rowInfo => (<Checkbox key={rowInfo.index} onChange={this.handleChange} />)
Here’s the full code:
import React from 'react'
import ReactDOM from 'react-dom'
import ReactTable from 'react-table'
import PropTypes from 'prop-types'
import { Checkbox } from '@shopify/polaris';
export default class ProductIndexTable extends React.Component {
constructor(props) {
super(props);
this.state = {
rowInfo: ''
}
this.handleChange = this.handleChange.bind(this)
}
handleChange(event) {
}
render() {
function CreateItem(product) {
return {
title: <a href={'/products/' + product.id} >{product.title}</a>,
price_test_status: product.has_active_price_test,
price_test_completion_percentage: product.price_test_completion_percentage
}
}
return (<ReactTable
data={this.props.products.map(CreateItem)}
getTdProps={(state, rowInfo, column, instance) => {
return {
onClick: (e, handleOriginal) => {
// console.log('A Td Element was clicked!')
// console.log('it produced this event:', e)
// console.log('It was in this column:', column)
// console.log('It was in this row:', rowInfo)
// console.log('It was in this table instance:', instance)
this.setState({
rowInfo: rowInfo.index
})
// IMPORTANT! React-Table uses onClick internally to trigger
// events like expanding SubComponents and pivots.
// By default a custom 'onClick' handler will override this functionality.
// If you want to fire the original onClick handler, call the
// 'handleOriginal' function.
if (handleOriginal) {
handleOriginal()
}
}
}
}}
columns={[
{
Header: "Base",
columns: [
{
Header: <Checkbox />,
maxWidth: 50,
Cell: (<Checkbox onChange={this.handleChange} />)
}, {
Header: "Product Title",
accessor: "title",
maxWidth: 400
}, {
Header: "Price Test Status",
accessor: "price_test_status",
maxWidth: 200
}, {
Header: "Price Test Completion Percentage",
accessor: "price_test_completion_percentage",
Cell: row => (
<div
style={{
width: '100%',
height: '100%',
backgroundColor: '#dadada',
borderRadius: '2px'
}}
>
<div
style={{
width: `${row.value}%`,
height: '100%',
backgroundColor: row.value > 66 ? '#85cc00'
: row.value > 33 ? '#ffbf00'
: '#ff2e00',
borderRadius: '2px',
transition: 'all .2s ease-out'
}}
/>
</div>
)
}
]
}
]}
defaultPageSize={10}
className="-striped -highlight"
/>
);}
}
2
Answers
I ended up storing the titles into a hash when clicked and that gave me my final solution. It checks the hash state to see if the value is true and should remain checked. See code below. Hope it helps others! Also check the codepen example I used to help me.
https://codepen.io/aaronschwartz/pen/WOOPRw?editors=0010
To solve the problem of checking the items in all the pages, just add the
key
prop on the<Checkbox />
components.Now, with the problem of storing the state, how many checkboxes are we talking about? You should have an array in your state, with all the checkboxes, and once a checkbox is checked you could send the ID (
key
props, which could be the counter on the.map()
) and set that position of the array as true or false (checked or unchecked)