SpreadJS提供了CheckBox和Combo单元格,但是没有提供RadioButton,下面我们使用自定义单元格实现RadioButton单元格。

RadioButtonCellType

下面是实现RadioButtonTextCell的TypeScript代码,有关TypeScript可以参考用Visual Studio Code + TypeScript 完成自定义颜色选择器单元格

class RadioButtonTextCell extends GcSpread.Sheets.CustomCellType {
    constructor() {
        super();
    }
    _items: Array<any>;
    items(items): any {
        if (arguments.length === 0) {
            return this._items;
        }
        this._items = items;
        return this;
    }
    _getRadioHTML(value: any): string {
        var items = this._items;
        var innerHtml = "";
        var radioButtonPattern = '<div class="radio" style="margin-top: 10px;margin-bottom: 10px;position: relative;"><label style="min-height: 20px;padding-left: 20px;margin-bottom: 0;"><input type="radio" name="GCInnerRadios" id="optionsRadios{0}" value="{1}" {2} style="position: absolute;margin: 4px 0 0 -20px;"/>{3}</label></div>';
        if (items) {
            var count = items.length;
            if (count > 0) {
                for (var i = 0; i < count; i++) {
                    var radioText = items[i];
                    var radioValue = items[i];
                    var isChecked = value == radioValue ? 'checked="checked"' : '';
                    innerHtml += radioButtonPattern.replace(/\{0\}/g, i.toString()).replace("{1}", radioValue).replace("{2}", isChecked).replace("{3}", radioText);
                }
            }
        }
        return innerHtml;
    }
    paint(ctx: CanvasRenderingContext2D, value: any, x: number, y: number, w: number, h: number, style: GcSpread.Sheets.Style, context?: any): void {
        if (!ctx) {
            return;
        }
        var self = this,
            items = self._items;
        var DOMURL = window.URL || window.webkitURL || window;
        var cell = context.sheet.getCell(context.row, context.col);
        var img = cell.tag();
        if (img) {
            ctx.save();
            ctx.rect(x, y, w, h);
            ctx.clip();
            ctx.drawImage(img, x + 2, y + 2)
            DOMURL.revokeObjectURL(url);
            ctx.restore();
            cell.tag(null);
            return;
        }
        var svgPattern = '<svg xmlns="http://www.w3.org/2000/svg" width="{0}" height="{1}">' +
            '<foreignObject width="100%" height="100%"><div xmlns="http://www.w3.org/1999/xhtml" style="font:{2};margin:0px 2px; padding-top:1px;">{3}</div></foreignObject></svg>';
        var innerHtml = self._getRadioHTML(value);
        var data = svgPattern.replace(/\{0\}/g, w.toString()).replace(/\{1\}/g, h.toString()).replace(/\{2\}/g, style.font).replace(/\{3\}/g, innerHtml);
        img = new Image();
        var svg = new Blob([data], { type: 'image/svg+xml;charset=utf-8' });
        var url = DOMURL.createObjectURL(svg);
        cell.tag(img);
        img.onload = function () {
            context.sheet.repaint(new GcSpread.Sheets.Rect(x, y, w, h));
        }
        img.src = url;
        return;
    }
    createEditorElement(context?: any): any {
        var div = document.createElement("div");
        var $div = $(div);
        $div.attr("gcUIElement", "gcEditingInput");
        $div.css("background-color", "white");
        $div.css("position", "absolute");
        $div.css("overflow", "hidden");
        $div.css("margin", "2px");
        var html = this._getRadioHTML("");
        $div.html(html);
        return div;
    }
    deactivateEditor(editorContext: any, context?: any) {
        super.deactivateEditor(editorContext, context);
    }
    setEditorValue(editorContext: any, value: any, context?: any) {
        if (editorContext) {
            var selected = $("input[type='radio'][value='" + value + "']", $(editorContext));
            if (selected.length > 0) {
                selected.prop("checked", true);
            }
        }
        $(editorContext).val(value);
    }
    getEditorValue(editorContext: any, context?: any) {
        var selectedVal = "";
        var selected = $("input[type='radio']:checked", $(editorContext));
        if (selected.length > 0) {
            return selected.val();
        }
        return null;
    }
    updateEditor(editorContext: any, cellStyle: GcSpread.Sheets.Style, cellRect: GcSpread.Sheets.Rect, context?: any) {
        if (editorContext) {
            var height = (this._items && this._items.length * 30 > cellRect.height) ? this._items.length * 30 : cellRect.height;
            $(editorContext).width(cellRect.width - 5);
            $(editorContext).height(height - 3);
            $(editorContext).css('font', cellStyle.font);
            $(editorContext).css('padding-left', '3px');
        }
    }
    getHitInfo(x, y, cellStyle, cellRect, context) {
        var size = 30;
        var info = { x: x, y: y, row: context.row, col: context.col, cellRect: cellRect, sheetArea: context.sheetArea, isReservedLocation: false, reservedLocation: -1 };
        var self = this,
            items = self._items;
        if (items && items.length) {
            for (var i = 0; i < items.length; i++) {
                if (y - cellRect.y < size * (i + 1)) {
                    info.isReservedLocation = true;
                    info.reservedLocation = i;
                    break
                }
            }
        }
        return info;
    };
    processMouseUp(hitInfo) {
        var sheet = hitInfo.sheet;
        if (sheet && hitInfo.isReservedLocation && hitInfo.reservedLocation >= 0) {
            var row = hitInfo.row, col = hitInfo.col, sheetArea = hitInfo.sheetArea;
            var newValue = this._items[hitInfo.reservedLocation]
            var cellEditInfo = { row: row, col: col, newValue: newValue };
            var undoAction = new GcSpread.Sheets.UndoRedo.CellEditUndoAction(sheet, cellEditInfo);
            sheet.doCommand(undoAction);
            return true;
        }
        return false;
    };
}

 

RadioButtonTextCell的实现和其他自定义单元格实现基本相同,但是在paint中使用了svg转换html为Image的方式展示RadioButton效果。

在线演示地址:https://demo.grapecity.com.cn/SpreadJS/cdn/extendedExample/#/demos/radioButton


更多资源

SpreadJS中文学习指南:http://demo.grapecity.com.cn/SpreadJS/TutorialSample/#/samples

SpreadJS在线英文产品文档:http://sphelp.grapecity.com/webhelp/SpreadJSWeb/webframe.html#welcome.html

如果您对SpreadJS产品感兴趣,可以到官方网站下载试用:/developer/spreadjs

如果你有疑问,可以到GCDN论坛获得技术支持:http://gcdn.grapecity.com.cn