copy to clipboard event

This commit is contained in:
Jan Prochazka
2020-03-29 20:32:53 +02:00
parent c3deb55779
commit 42e2dbbd48
2 changed files with 97 additions and 1 deletions

View File

@@ -37,6 +37,7 @@ import {
} from '@dbgate/datalib';
import { scriptToSql } from '@dbgate/sqltree';
import { sleep } from '../utility/common';
import { copyTextToClipboard } from '../utility/clipboard';
const GridContainer = styled.div`
position: absolute;
@@ -324,6 +325,34 @@ export default function DataGridCore(props) {
}
}
function handleCopy(event) {
if (event && event.target.localName == 'input') return;
if (event) event.preventDefault();
copyToClipboard();
}
// function handlePaste(event) {
// console.log('PASTE', event);
// }
function copyToClipboard() {
const rowIndexes = _.uniq(selectedCells.map(x => x[0])).sort();
const lines = rowIndexes.map(rowIndex => {
const colIndexes = selectedCells
.filter(x => x[0] == rowIndex)
.map(x => x[1])
.sort();
const rowData = loadedAndInsertedRows[rowIndex];
const line = colIndexes
.map(columnUniqueName)
.map(col => (rowData[col] == null ? '' : rowData[col]))
.join('\t');
return line;
});
const text = lines.join('\r\n');
copyTextToClipboard(text);
}
function handleGridMouseMove(event) {
if (autofillDragStartCell) {
const cell = cellFromEvent(event);
@@ -339,6 +368,10 @@ export default function DataGridCore(props) {
}
}
function columnUniqueName(columnIndex) {
return columns[columnSizes.realToModel(columnIndex)].uniqueName;
}
function handleGridMouseUp(event) {
if (dragStartCell) {
const cell = cellFromEvent(event);
@@ -351,7 +384,7 @@ export default function DataGridCore(props) {
if (_.isNumber(currentRowNumber)) {
const rowIndexes = _.uniq((autofillSelectedCells || []).map(x => x[0])).filter(x => x != currentRowNumber);
// @ts-ignore
const colNames = selectedCells.map(cell => columns[columnSizes.realToModel(cell[1])].uniqueName);
const colNames = selectedCells.map(cell => columnUniqueName(cell[1]));
const changeObject = _.pick(loadedAndInsertedRows[currentRowNumber], colNames);
setChangeSet(
batchUpdateChangeSet(
@@ -465,6 +498,11 @@ export default function DataGridCore(props) {
revertRowChanges();
}
if (event.keyCode == keycodes.c && event.ctrlKey) {
event.preventDefault();
copyToClipboard();
}
if (event.keyCode == keycodes.delete && event.ctrlKey) {
event.preventDefault();
deleteCurrentRow();
@@ -668,6 +706,8 @@ export default function DataGridCore(props) {
onMouseUp={handleGridMouseUp}
onKeyDown={handleGridKeyDown}
onWheel={handleGridWheel}
onCopy={handleCopy}
// onPasteCapture={handlePaste}
// table can be focused
tabIndex={-1}
ref={tableRef}

View File

@@ -0,0 +1,56 @@
export function copyTextToClipboard(text) {
const textArea = document.createElement('textarea');
//
// *** This styling is an extra step which is likely not required. ***
//
// Why is it here? To ensure:
// 1. the element is able to have focus and selection.
// 2. if element was to flash render it has minimal visual impact.
// 3. less flakyness with selection and copying which **might** occur if
// the textarea element is not visible.
//
// The likelihood is the element won't even render, not even a flash,
// so some of these are just precautions. However in IE the element
// is visible whilst the popup box asking the user for permission for
// the web page to copy to the clipboard.
//
// Place in top-left corner of screen regardless of scroll position.
textArea.style.position = 'fixed';
textArea.style.top = '0';
textArea.style.left = '0';
// Ensure it has a small width and height. Setting to 1px / 1em
// doesn't work as this gives a negative w/h on some browsers.
textArea.style.width = '2em';
textArea.style.height = '2em';
// We don't need padding, reducing the size if it does flash render.
textArea.style.padding = '0';
// Clean up any borders.
textArea.style.border = 'none';
textArea.style.outline = 'none';
textArea.style.boxShadow = 'none';
// Avoid flash of white box if rendered for any reason.
textArea.style.background = 'transparent';
textArea.value = text;
document.body.appendChild(textArea);
textArea.select();
try {
let successful = document.execCommand('copy');
if (!successful) {
console.log('Failed copy to clipboard');
}
} catch (err) {
console.log('Failed copy to clipboard: ' + err);
}
document.body.removeChild(textArea);
}