I'm using prime react table to render dynamic data in react. I built my component with the help of the datatable docs.
When I click the add row button, I would like that the new added row to be instantly editable to the user (preferably with keyboard focus that I'll add later) without them using the edit button to edit the empty new row. Is that possible?
import { DataTable } from "primereact/datatable";
import { Column } from "primereact/column";
import { data } from "../data";
import { useState } from "react";
import { InputText } from "primereact/inputtext";
export const Table = () => {
const [users, setUsers] = useState(data);
const handleAddRow = (): void => {
const newRow: any = {
firstName: "",
lastName: "",
email: "",
phone: "",
freeTextField: "",
};
setUsers((prevList: any) => [newRow, ...prevList]);
};
const onRowEditComplete = (e: any) => {
const _users = [...users];
const { newData, index } = e;
_users[index] = newData;
setUsers(_users);
};
const textEditor = (options: any) => {
return (
<InputText
type="text"
value={options.value}
onChange={(e) => options.editorCallback(e.target.value)}
/>
);
};
return (
<div className="table-wrapper">
<h2 className="table-name">PrimeReact data table</h2>
<button onClick={handleAddRow}>add row</button>
<DataTable
value={users}
tableStyle={{ minWidth: "50rem" }}
editMode="row"
onRowEditComplete={onRowEditComplete}
>
<Column
field="firstName"
header="firstName"
editor={(options) => textEditor(options)}
></Column>
<Column
field="lastName"
header="lastName"
editor={(options) => textEditor(options)}
></Column>
<Column
field="email"
header="email"
editor={(options) => textEditor(options)}
></Column>
<Column
field="phone"
header="phone"
editor={(options) => textEditor(options)}
></Column>
<Column style={{ maxWidth: "15%" }} rowEditor>
edit
</Column>
</DataTable>
</div>
);
};
This is possible with some tweaks on the above code.
dataKey
on DataTable
, this should be something unique to your data and something that you can add to the data on creation of the row, I used id
for demo purpose.onRowEditChange
so that the table can handle the programmatic activation.editingRows
, which you will pass in a state that will indicate which row is in editing mode. This is handled internally by the table by utilising the dataKey
prop mentioned in step 1.See the below code that will help to further understand the points above.
* I have used some hardcoded values for the users
state so that the code can work. Don't forget to change the value to your data
export const Table = () => {
const [users, setUsers] = useState([
{ id: 'john1', firstName: "John1", lastName: "Doe1", email: "john1@example.com", phone: "1234567890", freeTextField: "Random1" },
{ id: '2', firstName: "John2", lastName: "Doe2", email: "john2@example.com", phone: "2345678901", freeTextField: "Random2" },
{ id: '3', firstName: "John3", lastName: "Doe3", email: "john3@example.com", phone: "3456789012", freeTextField: "Random3" },
{ id: '4', firstName: "John4", lastName: "Doe4", email: "john4@example.com", phone: "4567890123", freeTextField: "Random4" },
{ id: '5', firstName: "John5", lastName: "Doe5", email: "john5@example.com", phone: "5678901234", freeTextField: "Random5" },
]);
const [editingRows, setEditingRows] = useState({});
const handleAddRow = (): void => {
const newRow: any = {
id: users.length + 1,
firstName: "",
lastName: "",
email: "",
phone: "",
freeTextField: "",
};
setUsers((prevList: any) => [newRow, ...prevList]);
const val = {...{ [`${users.length + 1}`]: true } }
setEditingRows(val);
};
const onRowEditComplete = (e: any) => {
const _users = [...users];
const { newData, index } = e;
_users[index] = newData;
setUsers(_users);
};
const textEditor = (options: any) => {
return (
<InputText
type="text"
value={options.value}
onChange={(e) => options.editorCallback(e.target.value)}
/>
);
};
const onRowEditChange = (e:any) => {
setEditingRows(e.data);
}
return (
<div className="table-wrapper">
<h2 className="table-name">PrimeReact data table</h2>
<button onClick={handleAddRow}>add row</button>
<DataTable
value={users}
tableStyle={{ minWidth: "50rem" }}
editMode="row"
editingRows={editingRows}
dataKey="id"
onRowEditChange={onRowEditChange}
onRowEditComplete={onRowEditComplete}
>
<Column
field="firstName"
header="firstName"
editor={(options) => textEditor(options)}
></Column>
<Column
field="lastName"
header="lastName"
editor={(options) => textEditor(options)}
></Column>
<Column
field="email"
header="email"
editor={(options) => textEditor(options)}
></Column>
<Column
field="phone"
header="phone"
editor={(options) => textEditor(options)}
></Column>
<Column style={{ maxWidth: "15%" }} rowEditor>
edit
</Column>
</DataTable>
</div>
);
};