-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[data grid] Is there any way to copy paste programmatically? #15114
Comments
Hey @KaralyosBela ... this might be possible when using the paste operation events. import * as React from 'react';
import { DataGridPremium, DataGridPremiumProps, useGridApiRef } from '@mui/x-data-grid-premium';
import { randomEmail, randomId, randomUserName } from '@mui/x-data-grid-generator';
const columns = [
{
field: 'name',
headerName: 'Name',
width: 250,
editable: true,
},
{
field: 'email',
headerName: 'Email',
width: 350,
editable: true,
},
];
const generateRandomRows = (count: number) => {
const rows = [];
for (let i = 0; i < count; i += 1) {
rows.push({
id: randomId(),
name: randomUserName(),
email: randomEmail(),
});
}
return rows;
};
const initialRows = generateRandomRows(100);
console.log(initialRows);
const parseDataIntoRows = (data: string[][]) => {
return data.map((row) => {
const [name, email] = row;
return { id: randomId(), name, email };
});
};
export default function ClipboardPaste() {
const apiRef = useGridApiRef();
const handleBeforeClipboardPaste: DataGridPremiumProps['onBeforeClipboardPasteStart'] = ({
data,
}) => {
console.log(data.length);
if (data.length === 0) {
console.log('no data to paste');
return Promise.reject();
}
// you need to have a function that will take the data from the clipboard and create a row object
const newRows = parseDataIntoRows(data);
apiRef.current.updateRows(newRows);
// we need to reject, because otherwise we will also override the selected rows with the values in the clipboard
return Promise.reject();
};
return (
<div style={{ height: 500, width: '100%' }}>
<DataGridPremium
rows={initialRows}
columns={columns}
apiRef={apiRef}
ignoreValueFormatterDuringExport
onBeforeClipboardPasteStart={handleBeforeClipboardPaste}
/>
</div>
);
} This way you will be able to add new rows instead |
Thanks for your solution, it works. The only problem with this, that if we want to use the default copy paste with the checkboxes to copy paste entire rows, or copy paste one or multiple cells, then this new solution applies only. So my question is: is there any way that we can use this new solution of yours with a button, for example: check 3 rows, press a button -> adds 3 rows with the copied data, and if we don't use the button, use the default copy paste. |
After thinking a bit, this could be achieved by watching the row selection model, and get the values with the apiRef.current.getSelectedRows(), then add that many rows with the values. This way we do not need to change the copy paste. |
@KaralyosBela that's even easier. Look at that example: import * as React from 'react';
import { DataGridPremium, useGridApiRef } from '@mui/x-data-grid-premium';
import { randomEmail, randomId, randomUserName } from '@mui/x-data-grid-generator';
import { Button, Stack } from '@mui/material';
const columns = [
{
field: 'name',
headerName: 'Name',
width: 250,
editable: true,
},
{
field: 'email',
headerName: 'Email',
width: 350,
editable: true,
},
];
const generateRandomRows = (count: number) => {
const rows = [];
for (let i = 0; i < count; i += 1) {
rows.push({
id: randomId(),
name: randomUserName(),
email: randomEmail(),
});
}
return rows;
};
const initialRows = generateRandomRows(5);
const parseTextToData = (text: string) => {
return text.split('\n').map((row) => row.split('\t'));
};
const parseDataIntoRows = (data: string[][]) => {
return data.map((row) => {
const [name, email] = row;
return { id: randomId(), name, email };
});
};
export default function ClipboardPaste() {
const apiRef = useGridApiRef();
const [clipboardData, setClipboardData] = React.useState<string[][]>([]);
const handleClipboardCopy = (text: string) => {
const data = parseTextToData(text);
setClipboardData(data);
};
const handleAddClipboardTextAsRows = () => {
const newRows = parseDataIntoRows(clipboardData);
apiRef.current.updateRows(newRows);
};
return (
<div style={{ height: 500, width: '100%' }}>
<Stack direction="row" gap={1} mb={1} flexWrap="wrap">
<Button
onClick={handleAddClipboardTextAsRows}
variant="outlined"
disabled={!clipboardData.length}
>
{!!clipboardData.length ? `Add ${clipboardData.length} rows` : 'No data to paste'}
</Button>
</Stack>
<DataGridPremium
rows={initialRows}
columns={columns}
apiRef={apiRef}
ignoreValueFormatterDuringExport
onClipboardCopy={handleClipboardCopy}
/>
</div>
);
} @mui/xgrid should we maybe add this example as a recipe? |
Thanks, this way I managed to do what I wanted! |
The problem in depth
Hey!
We are using the copy paste very often in our app.
A question has arisen as to whether it would be possible to copy paste at the press of a button. Pressing the copy button would save the values just like pressing ctrl + c. Then pressing the paste button would create as many lines as were copied and paste the copied values. Is it possible to do this or is it currently not possible in datagrid?
I tried selecting a few lines, ctrl + c, then ctrl + v and then using the onClipboardPasteStart function to create as many lines as I copied, but then I have to update the selectionModel to make the paste available, but I got stuck.
Your environment
`npx @mui/envinfo`
Search keywords: Copy paste
Order ID: 86461
The text was updated successfully, but these errors were encountered: