vxe-table-select-area
Version:
一个基于 vxe-table 的可区域选中复制、粘贴的组件
500 lines (490 loc) • 17.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _common = require("../../select-area/common");
var _index = require("../../select-area/utils/index");
var _autoResize = require("../../select-area/utils/auto-resize");
var _constant = require("../../select-area/common/constant");
var _focus = require("../../select-area/directives/focus");
var _lodash = require("lodash");
var _methods;
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
var _default = {
name: 'VxeSelectAreaEditor',
directives: {
focus: _focus.focus
},
props: {
parentRendered: {
type: Boolean,
required: true
},
hooks: {
type: Object,
required: true
},
// start input value every time
// inputStartValue: {
// type: [String, Number],
// required: true,
// },
rowKeyFieldName: {
type: String,
"default": null
},
// table data
tableData: {
type: Array,
required: true
},
colgroups: {
type: Array,
required: true
},
// cell selection option
cellSelectionData: {
type: Object,
required: true
},
// editing cell
// editingCell: {
// type: Object,
// required: true,
// },
// is editing cell
// isCellEditing: {
// type: Boolean,
// required: true,
// },
// has horizontal scroll bar
// hasXScrollBar: {
// type: Boolean,
// required: true,
// },
// has vertical scroll bar
// hasYScrollBar: {
// type: Boolean,
// required: true,
// },
// has right fixed column
// hasRightFixedColumn: {
// type: Boolean,
// required: true,
// },
scrollBarWidth: {
type: Number,
required: true
}
},
data: function data() {
return {
textareaInputRef: 'textareaInputRef',
// raw cell value
rawCellValue: '',
// display textarea
displayTextarea: false,
// virtual scroll overflowViewport
overflowViewport: false,
// textarea element rect
textareaRect: {
left: 0,
top: 0
},
// table element
tableEl: null,
// cell element
cellEl: null,
// auto resize
autoResize: null,
// is edit cell focus
isEditCellFocus: false
};
},
computed: {
// current column
currentColumn: function currentColumn() {
var result = null;
var colgroups = this.colgroups,
cellSelectionData = this.cellSelectionData;
var currentCell = cellSelectionData.currentCell;
if (!(0, _index.isEmptyValue)(currentCell.rowKey) && !(0, _index.isEmptyValue)(currentCell.colKey)) {
result = colgroups.find(function (x) {
return x.key === currentCell.colKey;
});
}
return result;
},
// container class
containerClass: function containerClass() {
var _result;
var result = null;
var displayTextarea = this.displayTextarea,
overflowViewport = this.overflowViewport;
// console.log(1300000, this)
result = (_result = {}, _defineProperty(_result, (0, _common.clsName)('edit-input-container'), true), _defineProperty(_result, (0, _common.clsName)('edit-input-container-show'), displayTextarea && !overflowViewport), _result);
return result;
},
// container style
containerStyle: function containerStyle() {
var result = {};
var displayTextarea = this.displayTextarea,
overflowViewport = this.overflowViewport,
textareaRect = this.textareaRect,
column = this.currentColumn;
var top = textareaRect.top,
left = textareaRect.left;
// console.log(152, displayTextarea, overflowViewport, textareaRect)
if (displayTextarea && !overflowViewport) {
result = {
top: top + 'px',
left: left + 'px',
height: null,
// because @ve-fixed-body-cell-index: 10;
'z-index': column.fixed ? 10 : 0,
opacity: 1
};
} else {
result = {
top: top + 'px',
left: left + 'px',
height: '1px',
'z-index': -1,
opacity: 0
};
}
return result;
},
// textarea class
textareaClass: function textareaClass() {
var result = null;
result = _defineProperty({}, (0, _common.clsName)('edit-input'), true);
return result;
}
},
watch: {
parentRendered: {
handler: function handler(val) {
var _this = this;
if (val) {
// fixed #471
this.setTableEl();
// console.log('hook>>>', this.hooks)
// add table container scroll hook
this.hooks.addHook(_constant.HOOKS_NAME.TABLE_CONTAINER_SCROLL, function () {
if (_this.displayTextarea) {
if (!_this.cellEl) {
_this.setCellEl();
}
}
_this.debounceSetCellEl();
_this.setTextareaPosition();
// console.log('1111111111111111111')
_this.debounceSetTextareaPosition();
});
// add table size change hook
this.hooks.addHook(_constant.HOOKS_NAME.TABLE_SIZE_CHANGE, function () {
// console.log('22222222222222222')
_this.setTextareaPosition();
});
}
},
immediate: true
},
// cell selection key data
'cellSelectionData.currentCell': {
handler: function handler(val) {
var _this2 = this;
this.isEditCellFocus = false;
var rowKey = val.rowKey,
colKey = val.colKey;
if (!(0, _index.isEmptyValue)(rowKey) && !(0, _index.isEmptyValue)(colKey)) {
this.setCellEl();
// wait for selection cell rendered
this.$nextTick(function () {
// console.log('333333333333333')
_this2.setTextareaPosition();
setTimeout(function () {
_this2.isEditCellFocus = true;
});
});
}
},
deep: true,
immediate: true
},
// watch normal end cell
'cellSelectionData.normalEndCell': {
handler: function handler(val) {
/*
trigger editor(textarea) element select
解决通过点击的区域选择,无法复制的问题
*/
if (!(0, _index.isEmptyValue)(val.colKey)) {
this[_constant.INSTANCE_METHODS.TEXTAREA_SELECT]();
}
},
deep: true,
immediate: true
}
// is editing cell
// isCellEditing: {
// handler: function (val) {
// if (val) {
// this.showTextarea();
// } else {
// this.hideTextarea();
// }
// },
// deep: true,
// immediate: true,
// },
// inputStartValue: {
// handler: function () {
// this.setRawCellValue();
// },
// immediate: true,
// },
},
mounted: function mounted() {
this.autoResize = (0, _autoResize.autoResize)();
// this.$nextTick(() => {
// var _this = this.$parent.$parent
// // console.log(2755555,_this)
// _this.$on([EMIT_EVENTS.EDIT_INPUT_COPY], (e) => {
// _this.editorCopy(e);
// },)
// })
},
methods: (_methods = {
// set table element
setTableEl: function setTableEl() {
var _this3 = this;
this.$nextTick(function () {
var tableEl = _this3.$parent.$el;
_this3.tableEl = tableEl;
});
},
// set cell element
setCellEl: function setCellEl() {
var cellSelectionData = this.cellSelectionData,
tableEl = this.tableEl;
// console.log(28777777, this)
var _cellSelectionData$cu = cellSelectionData.currentCell,
rowKey = _cellSelectionData$cu.rowKey,
colKey = _cellSelectionData$cu.colKey;
if (tableEl) {
var cellEl = tableEl.querySelector("tbody tr[rowid=\"".concat(rowKey, "\"] td[colid=\"").concat(colKey, "\"]"));
if (cellEl) {
this.cellEl = cellEl;
this.overflowViewport = false;
}
}
},
// set textarea position
setTextareaPosition: function setTextareaPosition() {
var hasXScrollBar = this.hasXScrollBar,
hasYScrollBar = this.hasYScrollBar,
scrollBarWidth = this.scrollBarWidth,
colgroups = this.colgroups,
hasRightFixedColumn = this.hasRightFixedColumn,
column = this.currentColumn,
cellEl = this.cellEl,
tableEl = this.tableEl;
// console.log(31444, cellEl, tableEl)
if (cellEl && tableEl) {
var _tableEl$getBoundingC = tableEl.getBoundingClientRect(),
tableLeft = _tableEl$getBoundingC.left,
tableTop = _tableEl$getBoundingC.top,
tableRight = _tableEl$getBoundingC.right,
tableBottom = _tableEl$getBoundingC.bottom;
var _cellEl$getBoundingCl = cellEl.getBoundingClientRect(),
cellLeft = _cellEl$getBoundingCl.left,
cellTop = _cellEl$getBoundingCl.top,
cellHeight = _cellEl$getBoundingCl.height,
cellWidth = _cellEl$getBoundingCl.width,
cellRight = _cellEl$getBoundingCl.right,
cellBottom = _cellEl$getBoundingCl.bottom;
// console.log('444444444')
if (cellHeight && cellWidth) {
// console.log('55555555', cellHeight, cellWidth)
var maxHeight = cellHeight + tableBottom - cellBottom;
var maxWidth = cellWidth + tableRight - cellRight;
// has horizontal scroll bar
if (hasXScrollBar) {
maxHeight -= scrollBarWidth;
}
// has vertical scroll bar
if (hasYScrollBar) {
maxWidth -= scrollBarWidth;
}
/*
If the right fixed column is included, the max width of the textarea needs to be subtracted from the sum of the right fixed columns
如果包含右固定列,编辑框最大宽度需要去减去右固定列之和的宽度
*/
if (hasRightFixedColumn) {
if (column && !column.fixed) {
var rightFixedTotalWidth = (0, _common.getFixedTotalWidthByColumnKey)({
colgroups: colgroups,
colKey: column.key,
fixed: 'right'
});
if (rightFixedTotalWidth) {
maxWidth -= rightFixedTotalWidth;
}
}
}
this.autoResize.init(this.$refs[this.textareaInputRef], {
minHeight: Math.min(cellHeight, maxHeight),
maxHeight: maxHeight,
// TEXTAREA should never be higher than visible part of the viewport (should not cover the scrollbar)
minWidth: Math.min(cellWidth, maxWidth),
maxWidth: maxWidth // TEXTAREA should never be wider than visible part of the viewport (should not cover the scrollbar)
}, true // observe textarea change\cut\paste etc.
);
this.textareaRect = {
left: cellLeft - tableLeft,
top: cellTop - tableTop
};
} else {
/*
存在以下可能:
1、虚拟滚动超出viewport
2、单元格被删除(通过右键菜单等方式)
*/
// fixed #477
this.textareaRect = {
left: 0,
top: 0
};
this.cellEl = null;
this.overflowViewport = true;
}
}
},
// show textarea
showTextarea: function showTextarea() {
this.setRawCellValue();
this.displayTextarea = true;
},
// hide textarea
hideTextarea: function hideTextarea() {
this.displayTextarea = false;
this.textareaUnObserve();
},
// textarea unObserve
textareaUnObserve: function textareaUnObserve() {
if (this.autoResize) {
this.autoResize.unObserve();
}
},
// set raw cell value
setRawCellValue: function setRawCellValue() {
this.rawCellValue = this.inputStartValue;
},
// textarea value change
textareaValueChange: function textareaValueChange(val) {
this.$emit(_constant.EMIT_EVENTS.EDIT_INPUT_VALUE_CHANGE, val);
}
}, _defineProperty(_methods, _constant.INSTANCE_METHODS.TEXTAREA_SELECT, function () {
var textareaInputEl = this.$refs[this.textareaInputRef];
if (textareaInputEl) {
textareaInputEl.select();
}
}), _defineProperty(_methods, _constant.INSTANCE_METHODS.TEXTAREA_ADD_NEW_LINE, function () {
var isCellEditing = this.isCellEditing,
editingCell = this.editingCell;
if (isCellEditing) {
var textareaInputEl = this.$refs[this.textareaInputRef];
var caretPosition = (0, _common.getCaretPosition)(textareaInputEl);
var value = editingCell.row[editingCell.colKey];
// solve error of number slice method
value += '';
var newValue = "".concat(value.slice(0, caretPosition), "\n").concat(value.slice(caretPosition));
// 直接更新 textarea 值
textareaInputEl.value = newValue;
// 手动赋值不会触发textarea 文本变化事件,需要手动更新 editingCell 值
this.textareaValueChange(newValue);
(0, _common.setCaretPosition)(textareaInputEl, caretPosition + 1);
}
}), _methods),
created: function created() {
var _this4 = this;
// debounce set textarea position
this.debounceSetTextareaPosition = (0, _lodash.debounce)(this.setTextareaPosition, 210);
// debounce set cell el
this.debounceSetCellEl = (0, _lodash.debounce)(function () {
if (_this4.displayTextarea) {
if (!_this4.cellEl) {
_this4.setCellEl();
}
}
}, 200);
},
render: function render(h) {
var _this5 = this;
var _e = this._e;
var containerClass = this.containerClass,
containerStyle = this.containerStyle,
textareaClass = this.textareaClass,
rawCellValue = this.rawCellValue,
isCellEditing = this.isCellEditing,
isEditCellFocus = this.isEditCellFocus;
var containerProps = {
style: containerStyle,
"class": containerClass
};
// console.log(5011111, this, containerProps)
var textareaProps = {
ref: this.textareaInputRef,
"class": textareaClass,
directives: [{
name: 'focus',
value: {
focus: isEditCellFocus
}
}],
domProps: {
value: rawCellValue
},
attrs: {
tabindex: -1
},
on: {
// input: (e) => {
// if (isCellEditing) {
// this.textareaValueChange(e.target.value);
// this.rawCellValue = e.target.value;
// }
// },
// click: () => {
// // console.log(525)
// this.$emit(EMIT_EVENTS.EDIT_INPUT_CLICK);
// },
// copy: function copy(evnt) {
// // console.log(52999999, evnt)
// },
copy: function copy(e) {
// console.log(52999999, e)
_this5.$emit(_constant.EMIT_EVENTS.EDIT_INPUT_COPY, e);
},
paste: function paste(e) {
// console.log(53333)
_this5.$emit(_constant.EMIT_EVENTS.EDIT_INPUT_PASTE, e);
},
cut: function cut(e) {
_this5.$emit(_constant.EMIT_EVENTS.EDIT_INPUT_CUT, e);
}
}
};
// console.log('544textareaProps',textareaProps)
return h('div', containerProps, [h('textarea', _objectSpread({}, textareaProps))]);
}
};
exports["default"] = _default;