Palaniichuk Dmytro
Palaniichuk Dmytro

Reputation: 3173

handleClick on row and checkbox in datatable

Updated I use material ui next, Table component, and Table is stateless component, and also I have constructor component EnhancedTable. Also in Table component when I go map through data, I need to check if selected props(array) has the same item as on data array . How should I check const isSelected = selected.includes(item) when I map through data array. Also when I click I catch error that selected.includes is not a function

unselectSelected={() => onSelect(selected =>{
                        debugger
                        console.log(selected)})}

Table component

    let defaultCellRenderer = ({item, key}) =>
    item[key]

const Table = props => {
    const {data, columns, children, selectable, order, selected, onSelect, onDelete, onSearch, onDuplicate, onSort, search, onUnselectAll} = props

    return (
        <div>
            {selectable &&
                <EnhancedTableToolbar
                    numSelected={selected.length}
                    handleSearch={() => onSearch(data)}
                    value={search}
                    // unselectSelected={() => onUnselectAll(selected)}
                    unselectSelected={() => onSelect(selected =>{
                        debugger
                        console.log(selected)})}
                    deleteSelected={() => onDelete(selected)}
                    duplicateSelected={() => onDuplicate(selected)}
                /> }
            <MuiTable >
                {selectable
                    ? <EnhancedTableHead
                        columns={columns}
                        numSelected={selected.length}
                        order={order}
                        // onSelectAllClick={() => onSelect(Object.keys(new Array(selected.length).fill(0)))}

                        onSelectAllClick={() => onSelect(
                            console.log('click')
                        )}
                        onRequestSort={property => event => onSort(event, property)}
                    />
                    : <TableHead>
                        <TableRow >
                            {columns.map(({label}) =>
                                <TableCell>
                                    {label}
                                </TableCell>)}
                        </TableRow>
                    </TableHead>
                }
                <TableBody>
                    {data.map((item, index) => {
                        // debugger
                        const isSelected = selected.includes(item)
                        debugger
                        return (
                            selectable
                                ? <TableRow
                                    hover
                                    onClick={() => onSelect(isSelected
                                        ? selected.filter(x => x != item)
                                        : [...selected, item])}
                                    role="checkbox"
                                    aria-checked={isSelected}
                                    tabIndex="-1"
                                    key={index}
                                    selected={isSelected}
                                >
                                    <TableCell checkbox>
                                        <Checkbox checked={isSelected}/>
                                    </TableCell>
                                    {columns.map(({key, cellRenderer, numeric}) =>
                                        <TableCell key={key} numeric={numeric}>
                                            {(cellRenderer || defaultCellRenderer)({item, key})}
                                        </TableCell>)}
                                </TableRow>
                                : <TableRow hover>
                                    {columns.map(({key, cellRenderer, numeric}) =>
                                        <TableCell numeric={numeric}>
                                            {(cellRenderer || defaultCellRenderer)({item, key})}
                                        </TableCell>)}
                                </TableRow> )
                    })}
                </TableBody>
            </MuiTable>
        </div>
    )
}

EnchancedTable

    class EnhancedTable extends Component {
    state = {
        selected: [],
        data,
        order: {
            direction: 'asc',
            by: 'deviceID',
        },
        search: '',
    }


    handleRequestSort = (event, property) => {
        const orderBy = property
        let order = 'desc'

        if (this.state.order.by === property && this.state.order.direction === 'desc') {
            order = 'asc'
        }

        const data = this.state.data.sort(
            (a, b) => order === 'desc' ? b[orderBy] > a[orderBy] : a[orderBy] > b[orderBy],
        )

        this.setState({ data, order })
    }

    deleteSelected = () => {
        const {data, selected} = this.state

        this.setState({data: data.filter(item => !selected.includes(item)), selected: []})
    }


    handleSearch = event => {
        const {data} = this.state
        let filteredDatas = []
        filteredDatas = data.filter(e => {
            let mathedItems = Object.values(e)
            let returnedItems
            mathedItems.forEach(e => {
                const regex = new RegExp(event.target.value, 'gi')
                if (typeof e == 'string')
                    returnedItems = e.match(regex)
            })
            return returnedItems
        })
        this.setState({filterData: filteredDatas, search: event.target.value})
    }

     unselectSelected = () => {
         this.setState({selected: []})
     }

    duplicate = () => {
        const {data, selected} = this.state

        this.setState({
            // data: data.filter((item, index) => selected.includes(index)).reduce((p, c) => [...p, {...data[index]}], data),
            data : [...data, ...selected],
            selected: [],
        })

    }

handleSelectChange = selected => {
    this.setState({selected})
}

    render = () => {

        const {selected, data, search, order} = this.state

        return (
            <Paper>
                <Table
                    data={data}
                    selectable
                    columns={columns}
                    order={order}
                    search={search}
                    selected={selected}
                    onSelect={this.handleSelectChange}
                    onDelete= {this.deleteSelected}
                    onSort={this.handleRequestSort}
                    onDuplicate={this.duplicate}
                    onSearch={this.handleSearch}
                    // test unselect
                    onUnselectAll = {this.unselectSelected}
                />
            </Paper>)
    }
}

Upvotes: 0

Views: 1349

Answers (1)

CaseyC
CaseyC

Reputation: 1482

It seems to me that you've got several things wrong ( and a few things that are maybe just strange) here. Because I don't know the structure of data in your example I can't tell you if your check here for const isSelected = selected.includes(item) is working properly or not. If an item in your data array is a single value this will work. For example if you had:

const data = [ 1,2,3,4 ]

And

const selected = [1,2]

You could do the check the way you are currently doing and it would work. const isSelected = selected.includes(item)

But if your data is for example an object array like:

const data = [ {id: 1},{id: 2},{id: 3} ]

And

const selected = [{id:1}]

Then you would need to check the id value like this:

const isSelected = selected.some((i) => i.id === item.id )

And also it looks like you are not setting selected to a new value when you filter it in your onClick method which is probably why you're getting the selected.includes is not a function error. You should be doing this instead.

onClick={() => onSelect(isSelected ? selected = selected.filter(x => x != item) : [...selected, item])}

I'm not sure why you don't just have a your onSelect method handle both the select and unselect of a row. Something like:

onClick={() => this.onSelect()}

And then outside your render method:

onSelect() {
    isSelected ? selected = selected.filter(x => x != item) : [...selected, item]
}

Hope that helps.

Upvotes: 1

Related Questions