Ellia.Duan 发表于 2024-9-2 10:31:42

下拉框支持选项背景色

本帖最后由 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]
查看完整版本: 下拉框支持选项背景色