I've got an application with this stack: ASP.NET Core MVC + React.JS
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?
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!