gregnb / mui-datatables

Datatables for React using Material-UI
MIT License
2.71k stars 932 forks source link

MUIDataTable onRowSelectionChange does not work with setState #1973

Open perazzo opened 1 year ago

perazzo commented 1 year ago

Im trying to update the state of an object with my selected rows, but it does not work with MUIDataTable. The object is updated and set, but the rows are not marked as selected.

import React, {useState, useEffect, useCallback} from 'react';
import { useSelector } from "react-redux";
import { MuiThemeProvider } from '@material-ui/core/styles';
import MUIDataTable from "mui-datatables";
import NumberFormat from 'react-number-format';
import moment from 'moment';
import { Button } from 'reactstrap';
import NotificationManager from 'react-notifications/lib/NotificationManager';
import Modal from 'react-modal';
import { FormControlLabel, Checkbox } from '@material-ui/core';

import Main from '../Main';
import RctCollapsibleCard from '../Helpers/RctCollapsibleCard/RctCollapsibleCard';
import LinearProgress from '../Util/LinearProgress';
import * as Constants from '../Util/constants';
import * as unitsAPI from '../../Api/units';

const modalStyles = {
    content: {
      top: '50%',
      left: '50%',
      right: 'auto',
      bottom: 'auto',
      marginRight: '-8%',
      transform: 'translate(-50%, -50%)',
      height: 'au'
    },
};

const tdStyle = {
    maxWidth: '100%',
}

const PostVacancies = () => {
    const login = useSelector((state) => state.login);
    const propertyID = login.selectedPropertyID;

    const [loading, setLoading] = useState(false);
    const [units, setUnits] = useState([]);
    const [onlyVacant, setOnlyVacant] = useState(true);
    const [unitsToPost, setUnitsToPost] = useState([]);
    const [openModal, setOpenModal] = useState(false);

    useEffect(() => {
        async function fetchData() {
            setLoading(true);
           // get units from the database
            const units = await unitsAPI.getPostVacanciesUnits(propertyID);
            setUnits(units);
            setLoading(false);
        }
        fetchData();
    }, [propertyID])

    const showUnits = useCallback(() => {
        const arr = [];
        const occupied = onlyVacant ? 0 : 1;    
        for(const u of units) {
            if(occupied === parseInt(u.Occupied)) {
                const today = moment.utc();
                const vacant = moment.utc(u.VacantDate);
                const daysOnMarket = today.diff(vacant, 'days');
                const loss = parseFloat(u.UnitCharge) * (daysOnMarket * 12 / 365);
                arr.push({
                    unit: u.UnitName,
                    unitType: u.UnitType,
                    moveOutDate: moment.utc(u.VacantDate).format("MM/DD/YYYY"),
                    daysOnMarket,
                    marketRent: parseFloat(u.UnitCharge).toFixed(2),
                    lossToVacancy: parseFloat(loss).toFixed(2),
                    unitID: u.UnitID,
                });
            }
        }
        return arr;
    }, [units, onlyVacant])

    const columns = [
        { name: 'unit', label: 'Unit', },
        { name: 'unitType', label: 'Unit Type', },
        { name: 'moveOutDate', label: 'Move Out Date', },
        { name: 'daysOnMarket', label: 'Days on Market', },
        { name: 'marketRent', label: 'Market Rent', 
            options: {
                customBodyRender: (value) => {
                    return <NumberFormat value={value} displayType={'text'} thousandSeparator={true} prefix={'$'} />
                }
            },
        },
        { name: 'lossToVacancy', label: 'Loss to Vacancy', 
            options: {
                customBodyRender: (value) => {
                    return <NumberFormat value={value} displayType={'text'} thousandSeparator={true} prefix={'$'} />
                }
            },
        },
    ];

    const options = {
        filterType: 'dropdown',
        pagination: false,
        onRowSelectionChange: (_, allSelected) => {
            setUnitsToPost([...allSelected]);
        },
    }

    const handlePostVacancies = () => {
        if(unitsToPost.length === 0) {
            NotificationManager.warning("Please, select at least one unit", "Error")
            return;
        }
        setOpenModal(true);
    }

    const renderTitle = () => {
        return (
            <>
            <Button color="link" onClick={() => setOnlyVacant(!onlyVacant)}>
                {onlyVacant ? 'Show all untis' : 'Show only vacant untis'}
            </Button>
            {'   '}
            <Button color="link" onClick={handlePostVacancies}>
                Post
            </Button>
            </>
        )
    }

    const postUnits = async () => {
        setLoading(true);
        const res = await unitsAPI.postVacancies({
            propertyID,
            autoPostVacancies: automaticPostVacant ? 1 : 0,
            autoRemoveNonVacancies: automaticRemoveNonVacant ? 1 : 0,
            unitsUpdated: unitsToPost.length,
            unitsToPost,
        });
        setLoading(false);
        if(res !== 0) {
            NotificationManager.errors(Constants.DEFAULT_ERROR, "Error");
            return;
        }
        NotificationManager.success("Your units have been submitted to the various websites. Actual posting times are dependent upon the individual sites.", "Success");
    }

    const renderModalContent = () => {
        return (
            <div>
                This is a test
            </div>
        )
    }

    if(loading) {
        return (
            <RctCollapsibleCard
                colClasses="col-xs-12 col-sm-12 col-md-12"
                heading={"Loading..."}
            >
                <LinearProgress />
            </RctCollapsibleCard>
        );
    }

    return (
        <>
            <Modal
                isOpen={openModal}
                onRequestClose={() => setOpenModal(false)}
                contentLabel="Units selected"
                style={modalStyles}
            >
                {renderModalContent()}
            </Modal>
            <Main>
                <div className="formelements-wrapper" style={Constants.margins}>
                    <div className="page-title d-flex justify-content-between align-items-center">
                        <div className="page-title-wrap">
                            <h2>
                                <span>Post Vacancies</span>
                            </h2>
                        </div>
                    </div>
                    <div className="row">
                        <div className="col-sm-12 col-md-12 col-xl-12">
                            <MuiThemeProvider theme={Constants.getMuiTheme()}>                                                    
                                <MUIDataTable
                                    title={renderTitle()}
                                    data={showUnits()}
                                    columns={columns}
                                    options={options}
                                />
                            </MuiThemeProvider>
                        </div>
                    </div>
                </div>
            </Main>
        </>
    )
}

export default PostVacancies;
sergiycheban commented 1 year ago

You can use the rowsSelected parameter, with the onRowSelectionChange you call your function in which you can write the data indexs and then feed them to rowsSelected