Search code examples
reactjsasp.net-coreasp.net-core-mvc

How to get selected grid rows?


I've got an application with this stack: ASP.NET Core MVC + React.JS

Client view

There is an issue I've been faced with. I've got a file Patients.js which return to the router some HTML code.

Patients.js:

import * as React from 'react';
import {
    Grid,
    Table,
    TableHeaderRow,
    TableSelection,
    TableColumnResizing
  } from '@devexpress/dx-react-grid-material-ui';
import {
    SortingState,
    IntegratedSorting,
    SelectionState,
    IntegratedSelection
  } from '@devexpress/dx-react-grid';
import { useEffect, useState } from "react";
import BaseToolbar from '../Base/BaseToolbar.js'

import '../styles/patients.css';

const URL = '/api/patients';

const columns = [
    { name: 'id', title: 'ID' },
    { name: 'lastName', title: 'Last name' },
    { name: 'firstName', title: 'First name' },
    { name: 'middleName', title: 'Middle name' },
    { name: 'age', title: 'Age' }
];

const defaultColumnWidths = [
    { columnName: 'id', width: 100 },
    { columnName: 'lastName', width: 200 },
    { columnName: 'firstName', width: 200 },
    { columnName: 'middleName', width: 200 },
    { columnName: 'age', width: 100 }
];

let rows = [];
const Patients = () => {
    const [allPatients, setPatients] = useState([]);

    const getPatients = async () => {
        let params = {
            method: 'GET',
            headers: new Headers()
        };
        const result = await fetch(URL, params);

        if (result.ok) {
            const patients =  await result.json();
            setPatients(patients);
            rows = patients;
            return patients;
        }

        return [];
    };

    useEffect(() => {
        getPatients();
    }, []);

    const AddHandler = () => { alert("add"); };
    const EditHandler = () => { alert("edit"); };
    const RemoveHandler = () => { alert("remove"); };

    return (
        <div style={{width:'100%'}}>
            <div>
                <BaseToolbar
                    onAdd={AddHandler}
                    onEdit={EditHandler}
                    onRemove={RemoveHandler}
                ></BaseToolbar>
            </div>
            <div style={{border: '1px LightGrey solid'}}>
                <Grid
                    rows={rows}
                    columns={columns}
                >
                    <SelectionState
                        selection={allPatients}
                        onSelectionChange={setPatients}
                    />
                    <SortingState
                        defaultSorting={[{ columnName: 'id', direction: 'asc' }]}
                        columnExtensions={[{ columnName: 'age', sortingEnabled: false}]}
                    /> 
                    <IntegratedSorting />
                    <IntegratedSelection />
                    <Table />
                    <TableColumnResizing defaultColumnWidths={defaultColumnWidths} />
                    <TableHeaderRow showSortingControls />
                    <TableSelection showSelectAll />
                </Grid>
            </div>
            
        </div>
    );
}

export default Patients;

As you see there are some handlers. I wanna do some logic there, but how can I get the selected rows?

allPatients variable returns me ugly data. If I select the first row it returns me smth like that:

0: {id: 1, firstName: 'firstPatientFirstName', middleName: 'firstPatientMiddleName', lastName: 'firstPatientLastName', age: 22}
1: {id: 5, firstName: 'secondPatientFirstName', middleName: 'secondPatientMiddleName', lastName: 'secondPatientLastName', age: 22}
2: 0

I think the third item is the index of the selected row in this array. But this method is ugh. Are there any more beautiful methods?

How can I use this at all?


Solution

  • I've a solution. If anyone still needed it. I've edited my Patients.js:

    import * as React from 'react';
    import {
        Grid,
        Table,
        TableHeaderRow,
        TableSelection,
        TableColumnResizing
      } from '@devexpress/dx-react-grid-material-ui';
    import {
        SortingState,
        IntegratedSorting,
        SelectionState,
        IntegratedSelection
      } from '@devexpress/dx-react-grid';
    import BaseToolbar from '../Base/BaseToolbar.js'
    
    import '../styles/patients.css';
    
    
    class Patients extends React.Component {
        patients = [];
        baseApiUrl = '/api/patients';
    
        constructor(props) {
            super(props);
    
            this.state = {
                grid: {
                    selection: [],
                    rows: [],
                    columns: this.getColumns(),
                    defaultColumnWidths: this.getColumnsWidth()
                }
            };
    
            this.getPatients();
        }
        
    
        getColumnsWidth() {
            return [
                { columnName: 'id', width: 100 },
                { columnName: 'lastName', width: 200 },
                { columnName: 'firstName', width: 200 },
                { columnName: 'middleName', width: 200 },
                { columnName: 'age', width: 100 }
            ];
        }
    
        getColumns() {
            return [
                { name: 'id', title: 'ID' },
                { name: 'lastName', title: 'Last name' },
                { name: 'firstName', title: 'First name' },
                { name: 'middleName', title: 'Middle name' },
                { name: 'age', title: 'Age' }
            ];
        }
    
        async getPatients() {
            let params = {
                method: 'GET',
                headers: new Headers()
            };
            const result = await fetch(this.baseApiUrl, params);
    
            if (result.ok) {
                
                const patients = await result.json();
    
                this.setState(prevState => {
                    let grid = Object.assign({}, prevState.grid);
                    grid.rows = patients;
    
                    return {grid};
                });
    
                return patients;
            }
    
            return [];
        }
    
        onToolbarAdd() {
    
        }
    
        onToolbarEdit() {
    
        }
    
        onToolbarRemove() {
    
        }
    
        onGridSelectionChange(me, selectedRowIds) {
            me.setState(prevState => {
                let grid = Object.assign({}, prevState.grid);
                grid.selection = selectedRowIds;
    
                return {grid};
            });
        }
    
        render() {
            return (
                <div style={{width:'100%'}}>
                    <button onClick={function() {
                        console.log("A");
                    }}>asdf</button>
                    <div>
                        <BaseToolbar
                            onAdd={this.onToolbarAdd}
                            onEdit={this.onToolbarEdit}
                            onRemove={this.onToolbarRemove}
                        ></BaseToolbar>
                    </div>
                    <div style={{border: '1px LightGrey solid'}}>
                        <Grid
                            rows={this.state.grid.rows}
                            columns={this.state.grid.columns}
                        >
                            <SelectionState
                                selection={this.state.grid.selection}
                                onSelectionChange={(selectedRowIds) => this.onGridSelectionChange(this, selectedRowIds) }
                            />
                            <SortingState
                                defaultSorting={[{ columnName: 'id', direction: 'asc' }]}
                                columnExtensions={[{ columnName: 'age', sortingEnabled: false }]}
                            /> 
                            <IntegratedSorting />
                            <IntegratedSelection />
                            <Table />
                            <TableColumnResizing defaultColumnWidths={this.state.grid.defaultColumnWidths} />
                            <TableHeaderRow showSortingControls />
                            <TableSelection />
                        </Grid>
                    </div>
                </div>
            );
        }
    };
    

    As you can see it was refactored by me. Function is gone to class and the main part is in <onSelectionChange> tag. I've passed selectedRowIds there and used onGridSelectionChange method, where class state changing. Enjoy!