0

Whenever I select next page I am loosing selected rows of the previous page in Material-table

I am using material-table remote data and using MT default paging. Here is link

https://material-table.com/#/docs/features/remote-data

Please help me in guiding what should I write in onSelectionChange method.

I tried the below solution but still, it’s not working

  1. Selection and Remote Data Pagination on Material Table React

  2. How can I use tableRef.onRowSelected to update the UI via the onRowClick property?

Here is my code:

cimport React from 'react';
import {IconProps} from '@material-ui/core';
import {forwardRef} from 'react';

import AddBox from '@material-ui/icons/AddBox';
import ArrowDownward from '@material-ui/icons/ArrowDownward';
import Check from '@material-ui/icons/Check';
import ChevronLeft from '@material-ui/icons/ChevronLeft';
import ChevronRight from '@material-ui/icons/ChevronRight';
import Clear from '@material-ui/icons/Clear';
import DeleteOutline from '@material-ui/icons/DeleteOutline';
import axios from 'axios';

import '../../node_modules/antd/dist/antd.css';

import Build from '@material-ui/icons/Build';
import FilterList from '@material-ui/icons/FilterList';
import FirstPage from '@material-ui/icons/FirstPage';
import LastPage from '@material-ui/icons/LastPage';
import Remove from '@material-ui/icons/Remove';
import SaveAlt from '@material-ui/icons/SaveAlt';
import Search from '@material-ui/icons/Search';
import ViewColumn from '@material-ui/icons/ViewColumn';
import Cancel from '@material-ui/icons/Cancel';
import Visibility from '@material-ui/icons/Visibility';
import Refresh from '@material-ui/icons/Refresh';


import {
    Form,
    Select,
    InputNumber,
    Input,
    Switch,
    Radio,
    Slider,
    Button,
    Upload,
    Icon,
    Rate,
    Checkbox,
    Row,
    Col,
    Tooltip,
    icon,
    Modal,

    message, Card
} from 'antd';
import MaterialTable from "material-table";

const ReactDomServer = require("react-dom/server")


const tableIcons = {
    Cancel: forwardRef((props, ref) => <Cancel {...props} ref={ref}/>),
    Refresh: forwardRef((props, ref) => <Refresh {...props} ref={ref}/>),
    Add: forwardRef((props, ref) => <AddBox {...props} ref={ref}/>),
    Check: forwardRef((props, ref) => <Check {...props} ref={ref}/>),
    Clear: forwardRef((props, ref) => <Clear {...props} ref={ref}/>),
    Delete: forwardRef((props, ref) => <DeleteOutline {...props} ref={ref}/>),
    DetailPanel: forwardRef((props, ref) => <ChevronRight {...props} ref={ref}/>),
    Build: forwardRef((props, ref) => <Build {...props} ref={ref}/>),
    Export: forwardRef((props, ref) => <SaveAlt {...props} ref={ref}/>),
    Filter: forwardRef((props, ref) => <FilterList {...props} ref={ref}/>),
    FirstPage: forwardRef((props, ref) => <FirstPage {...props} ref={ref}/>),
    LastPage: forwardRef((props, ref) => <LastPage {...props} ref={ref}/>),
    NextPage: forwardRef((props, ref) => <ChevronRight {...props} ref={ref}/>),
    PreviousPage: forwardRef((props, ref) => <ChevronLeft {...props} ref={ref}/>),
    ResetSearch: forwardRef((props, ref) => <Clear {...props} ref={ref}/>),
    Search: forwardRef((props, ref) => <Search {...props} ref={ref}/>),
    SortArrow: forwardRef((props, ref) => <ArrowDownward {...props} ref={ref}/>),
    ThirdStateCheck: forwardRef((props, ref) => <Remove {...props} ref={ref}/>),
    ViewColumn: forwardRef((props, ref) => <ViewColumn {...props} ref={ref}/>),
    Visibility: forwardRef((props, ref) => <Visibility {...props} ref={ref}/>)
};


const {Option} = Select;
var formItems = "";
var items = "";
var value = "";
var certvalue = "";
var inputvalues = [];


export default class ManageRequests extends React.Component {
    //  tableRef = React.createRef()
    constructor(props) {
        super(props);
        var selectedRows=[];
        this.state= {selectedRows: [],setSelectedRows: []}
        this.tableRef = React.createRef();

    }

    handleSelectionChange(rows) {

        const displayedIds = this.tableRef.current.dataManager.data.map(result => result._id)
        console.log(displayedIds)
        const selectedRowsNotDisplayed = this.state.selectedRows.filter(selectedRow => {
            return !displayedIds.includes(selectedRow._id)
        })
        console.log(selectedRowsNotDisplayed)
        var selectedRows =[...selectedRowsNotDisplayed, ...rows]


        this.setState({selectedRows});
        console.log(selectedRows)
        //alert(JSON.stringify(selectedRows))
        //this.tableRef.current.onSelectionChange(selectedRows);

    }


    render() {


        //   this.props.visible = true;

        var {visible, onCancel, onCreate, form} = this.props;



        return <Modal
            destroyOnClose={true}
            visible={visible}
            title="Manage Requests"
            okText="Create"
            onCancel={onCancel}
            onOk={onCreate}
            width="400"
            cancelButtonProps={{style: {display: 'none'}}}
            okButtonProps={{style: {display: 'none'}}}
        >


            <MaterialTable icons={tableIcons}
                           data={this.state.data} icons={tableIcons}

                           tableRef={this.tableRef}
                           title="Your Requests"
                           options={{
                               actionsColumnIndex: -1,
                               grouping: true,
                               showTextRowsSelected: false,


                               //search:false,
                               selection: true,
                               selectionProps: rowData => ({
                                   disabled: rowData.status === "Successful",
                                   color: 'primary',
                                   // showTextRowsSelected: true
                               })
                           }}
                           onSelectionChange={rows => this.handleSelectionChange(rows)}

                           columns={[
                               {
                                   title: 'Request ID',
                                   field: 'requestid',
                               },
                               {title: 'Created Date', field: 'createddate'},
                               {title: 'Created By', field: 'createdby'},
                               {title: 'Devices', field: 'Devices'},
                               {title: 'Domains', field: 'Domains'},
                               {title: 'Status', field: 'status'},

                           ]}
                           data={query =>
                               new Promise((resolve, reject) => {
                                   let url = 'http://localhost:5000/getRequest?'
                                   /*if(query.search)
                                   {
                                       let url = 'http://localhost:5000/getRequest?querysearch'
                                   }*/
                                   url += 'per_page=' + query.pageSize
                                   url += '&page=' + (query.page + 1)

                                   fetch(url)
                                       .then(response => response.json())
                                       .then(result => {
                                           const selectedRows = this.state.selectedRows;
                                           //  console.log(result.data);
                                           console.log(selectedRows)
                                           const selectedData = result.data.map(row => selectedRows.find(selected => "selected._id" === "row._id") ? { ...row, tableData: { checked: true } } : row)
                                           console.log(selectedData)
                                           console.log(result.data)
                                           resolve({
                                               data: result.data.filter(pub=> pub.requestid.includes(query.search)||pub.createdby.includes(query.search)||  pub.Devices.includes(query.search) || pub.status.includes(query.search)),
                                               page:result.page -1,
                                               totalCount: result.total,
                                           })
                                       })
                               })

                           }

                           actions={[

                               {


                                   icon: () => <Build/>,
                                   tooltip: 'Create Rollout',

                                   // eslint-disable-next-line no-restricted-globals
                                   onClick: (evt, data) => {
                                       alert('You want to delete ' + data + 'and length ' + data.length + ' rows')

                                       //    this.tableRef.current.onAllSelected(true)
                                       //rowData.tableData.checked


                                       this.setState({visible: false});
                                   }
                               }


                           ]}


            />
        </Modal>;
    }
}




user1850125
  • 31
  • 2
  • 6

1 Answers1

1

The problem is that material table mutates your data and saves the selection state in your data object. Since you return a new object on each query, the selection state within your objects is lost. This is a known problem, but it would need a lot of work to rewrite the current implementation, so we need to work around it.

This answers your question, but i will help you.

So you need to keep track of the selected item for yourself with onSelectionChange:

  onSelectionChange={rows => {this.handleSelectChange(rows)}}
  // This would work too: onSelectionChange={this.handleSelectChange}

You need to update your constructor:

constructor(props) {
    super(props);
    this.state= {selectedRows: []}
    this.tableRef = React.createRef();
}

Since you are using a class component, you have to safe the selected rows in the state:

handleSelectChange = (selectedRows) => {
     this.setState({selectedRows});
}

Now you always know the currently selected rows and you need to update your server data accordingly:

data={query =>
      new Promise((resolve, reject) => {
        const selectedRows = this.state.selectedRows;
        let url = 'https://reqres.in/api/users?'
        url += 'per_page=' + query.pageSize
        url += '&page=' + (query.page + 1)
        fetch(url)
          .then(response => response.json())
          .then(result => {
            const selectedData = result.data.map(row => selectedRows.find(selected => selected.id === row.id) ? { ...row, tableData: { checked: true } } : row)
            resolve({
              data: selectedData,
              page: result.page - 1,
              totalCount: result.total,
            })
          })
      })
    } 

Keep in mind, for that to work, you need to have an unique id for each row. If that is not the case for your data, you need to figure out, how to identify your data and update the selectedData call to fit your needs.

Domino987
  • 8,475
  • 2
  • 15
  • 38
  • Thanks Domino987, Now i am able to get selected rows but the actual rows are not checked once page is turned. – user1850125 Jan 24 '20 at 16:05
  • 1
    I updated my code with changes so now i can get selected rows in whatever page i change but selected rows are not checked. Remote data is present in Mongo db – user1850125 Jan 24 '20 at 16:32
  • @user1850125 Did you find the solution to your problem? I am in a similar situation without any luck. – Iftikhar Mar 31 '21 at 06:25