区域选择
区域选择是通过插件CellRangeSelector实现的,默认不支持跨冻结列进行选择,修正了选择,支持跨冻结列,代码如下,通过判断选择的起点和终点所落在的冻结范围进行计算,如从左往右进行复制,此时需要判拷贝的列数是否超过了冻结列,如果超过冻结了,此时需要在右侧(canvas)中进行绘制,否则在原canvas中绘制。从右往左逻辑同。
function show(range, cfg) {
var canvas = cfg.canvas;
var start = cfg.start;
var end = cfg.end;
var from = grid.getCellNodeBox(range.fromRow, range.fromCell);
var to = grid.getCellNodeBox(range.toRow, range.toCell);
// range left to right
var directLR = start <= end;
// frozenColumn temp var
var frozenColumn = grid.getOptions().frozenColumn;
var lR = false;
// lR true condition
if (directLR) {
lR = start <= frozenColumn && end > frozenColumn;
} else {
lR = start > frozenColumn && end <= frozenColumn;
}
if (!_elem) {
_elem = $("<div></div>", { css: options.selectionCss })
.addClass(options.selectionCssClass)
.css("position", "absolute")
.appendTo(grid.getActiveCanvasNode());
_borderWidth = _elem.css("border-left-width");
}
// lr ,create new element .
if (lR && !_rElem) {
_rElem = $("<div></div>", { css: options.selectionCss })
.addClass(options.selectionCssClass)
.css("position", "absolute")
.appendTo(canvas);
}
// ! lr ,remove _rElem
if (!lR && _rElem) {
_rElem.remove();
_rElem = null;
}
var temp = lR && directLR ? _rElem : _elem;
var lWidth = lR ? directLR ? canvas.width() : to.right - 2 : (to.right - from.left - 2);
var lLeft = lR && !directLR ? 0 : (from.left - 1);
//console.log("DIRECT_LR:" + directLR + " FROM_L:" + from.left + " TO_L:" + to.left + " FROM_R:" + from.right + " TO_R" + to.right + " START:" + start + " END:" + end + " LWIDTH:" + lWidth)
if (_elem) {
_elem.css("border-right-width", lR ? directLR ? "0px" : _borderWidth : _borderWidth);
_elem.css("border-left-width", lR ? directLR ? _borderWidth : "0px" : _borderWidth);
_elem.css({
top: from.top - 1,
left: lLeft,
height: to.bottom - from.top - 2,
width: lWidth
});
}
if (_rElem) {
var rLeft = directLR ? 0 : from.left;
var rWidth = !directLR ? canvas.width() : (to.right - 2);
//console.log("RWIDTH:" + rWidth + " RLEFT:" + rLeft);
_rElem.css("border-left-width", lR ? directLR ? "0px" : _borderWidth : _borderWidth);
_rElem.css("border-right-width", lR ? directLR ? _borderWidth : "0px" : _borderWidth);
_rElem.css({
top: from.top - 1,
left: rLeft,
height: to.bottom - from.top - 2,
width: rWidth
});
}
return temp;
}
拷贝粘贴的实现:
获取选中的数据,监听ctrl + c 和 ctrl + v 事件进行拦截,是通过CellExternalFullCopyManager插件实现的(支持跨冻结列拷贝、粘贴)。
当监听到ctrl + c 的时候,先拦截事件,并将选中区域的数据转换成数据保存在临时的text中,并且选中text的值,之后将text删除,此时粘贴板上已经有复制的值。
当监听到ctrl + v 的时候,首先判断是否有自定义的拦截,如果有自定义拦截,执行自定义拦截,否则执行默认粘贴方法。
- 默认粘贴支持两种模式,一种是选择了区域,此时粘贴会在选择区域内进行粘贴;
- 另一种模式是仅指定了起点,按照复制的区域,从顶点开始粘贴后续区域。
function _decodeTabularDataExt(_grid, ta) {
var columns = _grid.getColumns();
var clippeds = toRow(_grid, ta);
document.body.removeChild(ta);
var ranges = _grid.getSelectionModel().getSelectedRanges();
if (ranges && ranges[0] && !((ranges[0].fromCell - ranges[0].toCell == 0) && (ranges[0].fromRow - ranges[0].toRow == 0))) {
var to = ranges[0];
var startCell = to.fromCell;
var startRow = to.fromRow;
// to.toRow - to.fromRow
// 通过数据反向操作
for (var y = 0; y < clippeds.length; y++) {
var desty = startRow + y;
if (desty <= to.toRow) {
var dt = _grid.getDataItem(desty);
if (dt) {
for (var x = 0; x < clippeds[y].length; x++) {
var destx = startCell + x;
if (destx < grid.getColumns().length && destx <= to.toCell) {
if (!_grid.onBeforeEditCellReadonly(desty, destx, dt, columns[destx])) {
setDataItemValueForColumn(dt, columns[destx], clippeds[y][x]);
// dt[columns[destx].field] = clippeds[y][x];
}
}
}
}
}
}
} else {
// if startPoint
// else if range
var selectedCell = _grid.getActiveCell();
if (selectedCell) {
var startCell = selectedCell.cell;
var startRow = selectedCell.row;
// 通过数据反向操作
for (var y = 0; y < clippeds.length; y++) {
var desty = startRow + y;
var dt = _grid.getDataItem(desty);
if (dt) {
for (var x = 0; x < clippeds[y].length; x++) {
var destx = startCell + x;
if (destx < grid.getColumns().length) {
if (!_grid.onBeforeEditCellReadonly(desty, destx, dt, columns[destx])) {
setDataItemValueForColumn(dt, columns[destx], clippeds[y][x]);
//dt[columns[destx].field] = clippeds[y][x];
}
}
}
}
}
}
}
_grid.invalidate();
_grid.render();
clearCopySelection();
return;
}
setTimeout(function () {
if (_grid.trigger(_self.onPasteCells, toRow(_grid, ta), e) === true) {
return;
}
_decodeTabularData(_grid, ta);
}, 50);
自定义粘贴示例:
copyExtManager.onPasteCells.subscribe(function (e, args) {
if ($(e.target).hasClass("bom-past")) {
var selectedCell = grid.getActiveCell();
if (selectedCell) {
var startRow = selectedCell.row;
var rowData = grid.getDataItem(startRow);
var children = [];
rowData.___path = "";
var treeViewStack = [rowData];
var bomValidator = {
parentPath: function (row, rows) {
var tempRow = row;
var parentPath = [];
while (tempRow) {
parentPath.push(tempRow.f3000);
if (tempRow.parent) {
tempRow = findItemById(tempRow.parent);
} else {
tempRow = null;
}
}
return parentPath;
},
cycleCheck: function (row, parentPath) {
}
}
var parentPath = bomValidator.parentPath(rowData, getSgAllData());
for (var x = 0; x < args.length; x++) {
var nRow = $.extend({}, rowData);
nRow.id = sbz.uuid();
for (var y = 1; y < args[x].length; y++) {
if (y + 1 < grid.getColumns().length) {
nRow[grid.getColumns()[y + 1].field] = args[x][y];
}
}
nRow.f1000 = nRow.f2001 = nRow.f2000;
nRow.f3000 = nRow.f3001 = nRow.f2000;
nRow.__state = 0;
nRow.___path = args[x][0];
if (treeViewStack.length > 0) {
if (treeViewStack[treeViewStack.length - 1].___path.length < nRow.___path.length) {
var parent = treeViewStack[treeViewStack.length - 1];
// 找到父
var nParentPath = treeViewStack.filter((v) => {
return v.f2000 == nRow.f2000;
});
if (nParentPath.length > 0 || parentPath.indexOf(nRow.f2000) != -1) {
alert("死循环:" + parentPath);
return;
}
nRow.parentNumber = parent.f2000;
treeViewStack.push(nRow);
// 确定层级
treeViewPath(parent, nRow, x);
} else {
// 找到最近的兄弟或直接的父
var tempPaths = [];
tempPaths.push(parentPath);
for (var i = treeViewStack.length - 1; i >= 0; i--) {
if (treeViewStack[i].___path.length >= nRow.___path.length) {
treeViewStack.pop();
} else {
tempPaths.push(treeViewStack[i].f2000);
}
}
if (tempPaths.indexOf(nRow.f2000) != -1) {
alert("死循环");
return;
}
var parent = treeViewStack[treeViewStack.length - 1];
nRow.parentNumber = parent.f2000;
treeViewStack.push(nRow);
// 确定层级
treeViewPath(parent, nRow, x);
}
}
// 提示是否增加 行 ,假设增加
// 直接更新和刷新状态...
children[x] = nRow;
}
if (children && children.length > 0) {
var parents = treeViewSameNodes(rowData);
for (var i = 0; i < parents.length; i++) {
treeViewCopyData(children, parents[i]);
}
treeViewInsert(sgBomData, rowData, children);
refresh();
}
}
return true;
}
return false;
});
- slickgrid ( nsunleo-slickgrid ) 4 解决区域选择和列选择冲突
slickgrid ( nsunleo-slickgrid ) 3 解决区域选择和列选择冲突 之前启用区域选择的时候,又启用了列选择(CheckboxSelectColumn),此时发现选择状态与区域 ...
- slickgrid ( nsunleo-slickgrid ) 3 修正区域选择不能跨冻结列的问题
slickgrid ( nsunleo-slickgrid ) 3 修正区域选择不能跨冻结列的问题 上次解决区域选择不能跨冻结列问题的时候,剩了个尾巴,从右往左选择的时候,会出现选择不正常的情况,后 ...
- slickgrid ( nsunleo-slickgrid ) 2 修正区域选择不能跨冻结列的问题
slickgrid( nsunleo-slickgrid ) 2 修正区域选择不能跨冻结列的问题 周六的时候,留了个小小的尾巴,区域选择的问题进做到了定位: 问题原因,在slickgrid启动冻结之 ...
- 【opencv学习笔记六】图像的ROI区域选择与复制
图像的数据量还是比较大的,对整张图片进行处理会影响我们的处理效率,因此常常只对图像中我们需要的部分进行处理,也就是感兴趣区域ROI.今天我们来看一下如何设置图像的感兴趣区域ROI.以及对ROI区域图像 ...
- 图像的ROI区域选择与复制
[opencv学习笔记六]图像的ROI区域选择与复制 孜然 7 人赞同了该文章 图像的数据量还是比较大的,对整张图片进行处理会影响我们的处理效率,因此常常只对图像中我们需要的部分进行处理,也就是感 ...
- js实现选择及复制粘贴
最近项目有个点击复制到粘贴板的需求,在这里做一个简单的例子分享给大家,没考虑兼容性,需要兼容的大家去查找下文档 //html<p id="element">测试测试&l ...
- Vim的使用 区域选择
1.Visual Block 区域选择,这里的Visual表示视觉,图像,可视化. 2. 小写v:字符选择 shift+v(大写V):行选择 ctrl+v:矩 ...
- 个人永久性免费-Excel催化剂功能第82波-复制粘贴按源区域大小自动扩展收缩目标区域
日常工作中,复制粘贴的操作,永远是最高频的操作,没有之一,在最高频的操作上,进行优化,让过程更智能,比一天到晚鼓吹人工智能替换人的骇人听闻的新闻来得更实际.此篇带来一点点的小小的改进,让日后无数的复制 ...
- 个人永久性免费-Excel催化剂功能第44波-可见区域复制粘贴不覆盖隐藏内容
Excel的复制粘贴操作,每天都在进行,若其中稍能提升一点效率,长久来说,实在是很可观的效率提升. Excel自带的复制粘贴功能,若复制的数据源或粘贴的目标位置中有隐藏的行列内容,简单一个复制粘贴充满 ...
随机推荐
- java例题_01 不死神兔!
1 /*1 [程序 1 不死神兔] 2 题目:古典问题:有一对兔子,从出生后第 3 个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子对数为多少? 3 程 ...
- shell的配置文件
1. bash shell 的配置文件 bash shell的配置文件很多,可以分成下面类别 1.1 按生效范围划分两类 全局配置:针对所有用户皆有效 /etc/profile /etc/profil ...
- Recoil 的使用
通过简单的计数器应用来展示其使用.先来看没有 Recoil 时如何实现. 首先创建示例项目 $ yarn create react-app recoil-app --template typescri ...
- ES9的新特性:异步遍历Async iteration
ES9的新特性:异步遍历Async iteration 目录 简介 异步遍历 异步iterable的遍历 异步iterable的生成 异步方法和异步生成器 简介 在ES6中,引入了同步iteratio ...
- 使用CSS3中Canvas 实现两张图片合成一张图片【常用于合成二维码图片】
CSS3 Canvas 实现两张图片合成一张图片 需求 需求:在项目中遇到将一张固定图片和一张二维码图片合成一张新图片,并且用户能够将图片保存下载到本地. 思路:使用 CSS3 中的 Canvas 将 ...
- (九)Docker-PS 详解
1. 作用 查看 docker 容器 2. 基本语法 docker ps [OPTIONS] OPTIONS说明: -a :显示所有的容器,包括未运行的. -f :根据条件过滤显示的内容. --for ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(六)——一步一步教你如何撸Dapr之Actor服务
我个人认为Actor应该是Dapr里比较重头的部分也是Dapr一直在讲的所谓"stateful applications"真正具体的一个实现(个人认为),上一章讲到有状态服务可能很 ...
- 面试系列<5>——面向对象
面试系列--面向对象思想 一.三大特性 封装 利用抽象数据类型将数据和基于数据的操作封装在一起,使其成为一个不可分割的独立实体.数据被保护在抽象数据类型内部,尽可能地隐藏内部细节,只保留一些对外的接口 ...
- Spring Boot的自动配置原理及启动流程源码分析
概述 Spring Boot 应用目前应该是 Java 中用得最多的框架了吧.其中 Spring Boot 最具特点之一就是自动配置,基于Spring Boot 的自动配置,我们可以很快集成某个模块, ...
- Python语言程序设计(笔记)
1.平方根的格式化 知识点:平方根计算 pow(a,0.5)[可以计算负数,结果为复数] a**b 例题: 获得用户输入的一个整数a,计算a的平方根,保留小数点后3位,并打印输出. ...