下拉框支持选项背景色
本帖最后由 Ellia.Duan 于 2024-9-2 10:56 编辑在SpreadJS中,下拉框是支持多选的,具体可以参考这篇学习指南。但是在一些场景中,想标识不同选项,如
下面,我们看下怎么实现吧:
1、定义Style
在上面给出的学习指南中,介绍了在Style中定义cellButtons以及dropDowns属性,分别用来控制打开下拉框选项以及下拉框选项。
基本用法是:
var style = new GC.Spread.Sheets.Style();
style.cellButtons = [
{
imageType: GC.Spread.Sheets.ButtonImageType.dropdown,
command: "openList",
useButtonStyle: true,
}
];
style.dropDowns = [
{
type: GC.Spread.Sheets.DropDownType.list,
option: {
items: [
{
text: 'item1',
value: 'item1'
},
{
text: 'item2',
value: 'item2'
},
{
text: 'item3',
value: 'item3'
},
{
text: 'item4',
value: 'item4'
}
],
}
}
];
sheet.setText(2, 1, "Vertical text list");
sheet.setStyle(3, 1, style);但是,我们在点击选项的时候,要增加一个背景色。所以,这里dropDowns 中的option我们自定义一下:
customStyle.dropDowns = [
{
type: GC.Spread.Sheets.DropDownType.list,
option: colorListData
}
];然后定义colorListData
var colorListData = {
multiSelect: true,
onItemSelected: colorClicked,
items: generateThemeColors
};在上述代码中,我们定义了三个属性,multiSelect用来表示支持多选,onItemSelected用来表示选中事件,items表示下拉框选项。
接下来 ,我们定义下items
let colorMap = ['#1abc9c', '#2ecc71', '#3498db', '#9b59b6', '#34495e', '#f1c40f', '#e67e22', '#C76DA2', '#e74c3c', '#95a5a6'];
let arr = ['item1', 'item2', 'item3', 'item4', 'item5', 'item6', 'item7', 'item8', 'item9', 'item10']
function generateColors(count, start, stop) {
var div = document.createElement("div");
div.style.width = "50px";
var step = (stop - start) / count | 0;
for (var i = start, index = 0; i < stop && index < count; i += step, index++) {
var item = document.createElement("div");
item.style.backgroundColor = colorMap;
item.style.width = '35px';
item.style.height = '15px';
item.style.border = '1px solid #c3c3c3';
item.style.color = 'white';
item.style.padding = '2px';
item.style.margin = '4px';
item.classList.add("custom-color-block");
item.innerHTML = arr
div.appendChild(item);
}
return div;
}
在上述代码中,我们遍历了arr,生成了dom元素,并为dom元素。
我们运行一下上述代码,结果如下:
此时选中B2单元格,选中item1 ,因为B2单元格一开始包含item1,所以此时如果再次选择item1,应该是取消选中item1 ,但是显示了undefined ,如下图所示
这是为什么呢,不知道大家还记不记上面提到了onItemSelected用来表示选中事件 ,我们接下来对onItemSelected进行编码:
function colorClicked(event) {
var target = event.target;
if (target && target.classList.contains("custom-color-block")) {
return target.innerHTML;
}
}
添加上述代码后,我们就可以正常显示选中内容了。
但是,光选中内容还不够,怎么将选中内容的颜色也添加到单元格中呢?
接下来,我们需要自定义单元格。
2、自定义单元格
在SpreadJS中,是支持自定义单元格的,具体可以参考这篇学习指南:在这篇指南中,我们看到将布尔值true|false 转换为黄色五角星和灰色五角星。
看具体的代码,我们发现重写了Paint方法,所以我们也需要重写下paint ,具体代码如下:
ColorBlockCellType = function () {
GC.Spread.Sheets.CellTypes.Base.apply(this, arguments);
this.typeName = 'ColorBlockCellType'
}
ColorBlockCellType.prototype = new GC.Spread.Sheets.CellTypes.Base();
ColorBlockCellType.prototype.paint = function (ctx, value, x, y, w, h, style, options) {
//using the base text to render the text option.
GC.Spread.Sheets.CellTypes.Text.prototype.paint.call(this, ctx, '', x, y, w, h, style, options);
if (style.cellButtons && style.cellButtons.length > 0) {
w = w - 28 * style.cellButtons.length;
}
var valueArr = value && value.split(','), newH = h, newY = y, newStyle = style.clone(), padding = 4,
newX = x;
var sheet = options.sheet, zoomFactor = sheet.zoom();
if (valueArr && valueArr.length > 0) {
newH = newH - 4;
newY = y + 2;
// remove the un-support options for block style;
newStyle.cellButtons = [];
valueArr.forEach((item, index) => {
var itemWidth = GC.Spread.Sheets.CellTypes.Text.prototype.getAutoFitWidth(item, item, newStyle, zoomFactor, options) + 4;
var itemBackground = colorMap;
newStyle.backColor = itemBackground;
newStyle.foreColor = 'white';
if (newX + itemWidth > x + w) {
itemWidth = x + w - newX;
}
if (itemWidth <= 0) {
return;
}
GC.Spread.Sheets.CellTypes.Text.prototype.paint.call(this, ctx, item, newX, newY, itemWidth, newH, newStyle, options);
newX += itemWidth + padding;
});
}
};
在上述代码中 ,我们遍历了每一个选项,给其添加背景色,前景色。·重新计算宽高,以及位置。
最后,我们为上述单元格赋值
spread.suspendPaint();
sheet.setText(0, 0, "Custom list");
sheet.setColumnWidth(1, 500);
sheet.setValue(0, 1, 'item1');
sheet.setValue(1, 1, 'item1,item2');
sheet.setValue(2, 1, 'item1,item2,item3');
sheet.setValue(3, 1, 'item1,item2,item3,item4');
sheet.setValue(4, 1, 'item1,item2,item3,item4,item5');
sheet.setValue(5, 1, 'item1,item2,item3,item4,item5,item6');
sheet.setValue(6, 1, 'item1,item2,item3,item4,item5,item6,item7');
sheet.setValue(7, 1, 'item1,item2,item3,item4,item5,item6,item7,item8');
sheet.setValue(8, 1, 'item1,item2,item3,item4,item5,item6,item7,item8,item9');
sheet.setValue(9, 1, 'item1,item2,item3,item4,item5,item6,item7,item8,item9,item10');
sheet.getRange('B1:B10').setStyle(customStyle);
sheet.getRange('B1:C10').cellType(new ColorBlockCellType());
spread.resumePaint();那么,本次想要实现的功能就实现了,具体可以参考附件demo。
还有一点点小问题,为什么这个自定义单元格,toJSON后,再次fromJSON不生效呢?这个是因为我们在序列化过程,要对自定义单元格添加一个标识typeName,
具体可以参考:https://demo.grapecity.com.cn/sp ... erialization/purejs。
这里要注意,typeName要与勾选函数functionName一致。如下图所示:
有时候,发现,为什么复制粘贴,填充的时候,自定义单元格不生效,这个是因为ColorBlockCellType要全局定义。
页:
[1]