Handsontable - 无法保持自定义渲染器创建的html元素可见

时间:2017-01-12 21:07:10

标签: handsontable

我正在使用handontable的开源版本(版本0.29.2)。我创建了一个自定义渲染器,在每一行上创建一个隐藏的SPAN元素/图标。当输入验证失败时,我使用jQuery以编程方式取消隐藏/显示SPAN标记/图标,使其显示在单元格的右侧。它工作得很好,但不幸的是,当我在另一个单元格中输入无效值时,第一个单元格中的图标会消失。首选行为是在存在验证问题的单元格中显示所有图标。

问题:有没有办法让所有图标都可见?

如果无法做到这一点,验证后显示图像的动手是否有不同的方法?正如您从下面的代码(以及我的jsfiddle示例)中可以看到的,我没有使用内置的handsontable验证钩子。通过内置验证,我无法添加我想要的图标 - 我只能使用invalidCellClassName覆盖无效单元格的默认样式。

我创建了一个简单的示例,其中包含说明我的问题的说明: http://jsfiddle.net/4g3a5kqc/15/

var data = [
    ["1", "abc"],
    ["2", "def"],
    ["3", "ghi"],
    ["4", "jkl"]
],
container = document.getElementById("example"),
hot1;    

// This function is a custom renderer that creates a hidden SPAN element/  
// icon.  In this example, when a user changes the value, the SPAN element
// icon will appear.
function customRenderer(instance, td, row, col, prop, value, cellProperties)             {
    td.innerHTML = value +
        '<span id="account-code-error-' + row + '-' + col + '" class="account-code-error ' +
        'glyphicon glyphicon-exclamation-sign text-warning jzb-icon-md pull-right" ' +
        'style="font-size: large; cursor: pointer; display: none;"></span>';
}

var hot1 = new Handsontable(container, {
data: data,
rowHeaders: true,
colHeaders: true,
stretchH: 'all',
cells: 
    function (row, col, prop) {
        var cellProperties = {};
        if (col == 0) {
            cellProperties.renderer = customRenderer;
        }
        return cellProperties;
    }    
});

hot1.addHook('afterChange', afterChange);

// Show the SPAN tag with the icon
// in the right-hand side of the cell.
function afterChange(changes, source) {
    console.log(changes, source);

if (source == 'edit' || source == 'autofill') {
    $.each(changes,
        function (index, element) {
            var change = element;
            var rowIndex = change[0];
            var columnIndex = change[1];
            var oldValue = change[2];
            var newValue = change[3];

            console.log(oldValue, newValue, rowIndex, columnIndex, change);

            if (columnIndex != 0) {
                return;
            }

            if (newValue >= 0) {
                return;
            }

            var cellProperties = hot1.getCellMeta(rowIndex, hot1.propToCol(columnIndex));

            var td = hot1.getCell(rowIndex, columnIndex, true);
            var span = td.getElementsByTagName("span");
            $("#" + span[0].id).show();
        });
    }
}

1 个答案:

答案 0 :(得分:1)

由于每次更改后都会调用customRenderer(),我们必须存储可见跨距的单元格,并在渲染时检查它。另一方面,如果跨度不可见(输入有效),我们需要将其从可见跨度的单元格数组中删除。工作小提琴: http://jsfiddle.net/8vdwznLs/

var data = [
    ["1", "abc"],
    ["2", "def"],
    ["3", "ghi"],
    ["4", "jkl"]
],
container = document.getElementById("example"),
hot1,
visibleSpans = [];    

// This function is a custom renderer that creates a hidden SPAN element/  
// icon.  In this example, when a user changes the value, the SPAN element
// icon will appear.
function customRenderer(instance, td, row, col, prop, value, cellProperties)             {
if (visibleSpans.indexOf(td) > -1) {
    td.innerHTML = value +
        '<span id="account-code-error-' + row + '-' + col + '" class="account-code-error ' +
        'glyphicon glyphicon-exclamation-sign text-warning jzb-icon-md pull-right" ' +
        'style="font-size: large; cursor: pointer;"></span>';
} else {
    td.innerHTML = value +
        '<span id="account-code-error-' + row + '-' + col + '" class="account-code-error ' +
        'glyphicon glyphicon-exclamation-sign text-warning jzb-icon-md pull-right" ' +
        'style="font-size: large; cursor: pointer; display: none;"></span>';
}
}

var hot1 = new Handsontable(container, {
data: data,
rowHeaders: true,
colHeaders: true,
stretchH: 'all',
cells: 
    function (row, col, prop) {
        var cellProperties = {};
        if (col == 0) {
            cellProperties.renderer = customRenderer;
        }
        return cellProperties;
    }    
});

hot1.addHook('afterChange', afterChange);

// Show the SPAN tag with the icon
// in the right-hand side of the cell.
function afterChange(changes, source) {
    console.log(changes, source);

if (source == 'edit' || source == 'autofill') {
    $.each(changes,
        function (index, element) {
            var change = element;
            var rowIndex = change[0];
            var columnIndex = change[1];
            var oldValue = change[2];
            var newValue = change[3];
            var td = hot1.getCell(rowIndex, columnIndex, true);

            console.log(oldValue, newValue, rowIndex, columnIndex, change);

            if (columnIndex != 0) {
                return;
            }

            if (newValue >= 0) {
              var indexOfSpan = visibleSpans.indexOf(td);
                if (indexOfSpan > -1) {
                  visibleSpans.splice(indexOfSpan, 1);
                  hot1.render();
                  return;
                }
              return;
            }

            var cellProperties = hot1.getCellMeta(rowIndex, hot1.propToCol(columnIndex));

            visibleSpans.push(td);
            var span = td.getElementsByTagName("span");
            span[0].setAttribute('style', '');
        });
    }
}