SpreadJS does not automatically convert Numeric Keypad decimal separator based on culture
When using SpreadJS with the Culture Manager to set a comma (,) as the decimal separator, input from the standard keyboard behaves as expected. For example, entering 12,555 is correctly recognized and formatted as a number.
However, when using the Numeric Keypad, the decimal key (.) continues to insert a dot (.), regardless of the configured culture. As a result, a value like 12.555 is interpreted as a string instead of a number.
Unlike Microsoft Excel, SpreadJS does not automatically adjust the decimal separator based on locale when the input comes from the operating system or browser.
This behavior is expected in SpreadJS, as it relies on the input provided by the browser/OS. To achieve Excel-like behavior, you can implement a workaround that intercepts Numeric Keypad input and converts the dot (.) into a comma (,).
Below is a sample implementation:
const spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"));
const sheet = spread.getActiveSheet();
var myCulture = new GC.Spread.Common.CultureInfo();
myCulture.NumberFormat.numberDecimalSeparator = ",";
myCulture.NumberFormat.numberGroupSeparator = ".";
myCulture.NumberFormat.listSeparator = ";";
GC.Spread.Common.CultureManager.addCultureInfo("custom-comma", myCulture);
GC.Spread.Common.CultureManager.culture("custom-comma");
sheet.getRange(-1, -1, sheet.getRowCount(), sheet.getColumnCount())
.formatter("#,##0.00");
var isLocalizedDecimalSeparator = true;
var oldActivateEditorFn = GC.Spread.Sheets.CellTypes.Text.prototype.activateEditor;
var oldIsReservedKeyFn = GC.Spread.Sheets.CellTypes.Text.prototype.isReservedKey;
function insertTextAtCaret(el, text) {
el.focus();
var selection = window.getSelection();
if (!selection || selection.rangeCount === 0) {
el.innerText += text;
return;
}
var range = selection.getRangeAt(0);
range.deleteContents();
var textNode = document.createTextNode(text);
range.insertNode(textNode);
range.setStartAfter(textNode);
range.setEndAfter(textNode);
selection.removeAllRanges();
selection.addRange(range);
}
GC.Spread.Sheets.CellTypes.Text.prototype.activateEditor = function (
editorContext,
cellStyle,
cellRect,
context
) {
if (!editorContext._numpadDecimalHandlerAttached) {
editorContext.addEventListener("keydown", function (event) {
if (
event.code === "NumpadDecimal" &&
isLocalizedDecimalSeparator
) {
event.preventDefault();
insertTextAtCaret(event.currentTarget, ",");
}
});
editorContext._numpadDecimalHandlerAttached = true;
}
return oldActivateEditorFn.apply(this, arguments);
};
GC.Spread.Sheets.CellTypes.Text.prototype.isReservedKey = function (e, context) {
if (
e.code === "NumpadDecimal" &&
!context.isEditing &&
isLocalizedDecimalSeparator
) {
setTimeout(function () {
context.sheet.startEdit(false, ",");
}, 0);
return true;
}
return oldIsReservedKeyFn.apply(this, arguments);
};
As shown above, you can use a custom input handler to ensure the correct decimal separator is applied when using the Numeric Keypad in SpreadJS.
Kristina Ismail