For my upcoming project, I am looking to incorporate the Handsontable JavaScript grid framework. However, I have encountered a small bug that is hindering me from utilizing this library to its fullest potential.
The task at hand involves displaying a table with German prices, formatted as "18,50 €". In the German language, the comma serves as the decimal point. The default configuration of Handsontable only includes the English language option for the embedded "numeral.js" helper library. To address this, I added the German (de) language definition for numeral.js. By defining the cell format as "0.00 $", I successfully displayed prices correctly as "18,50 €" within the grid.
However, an issue arises when selecting a cell with a value like "1,50 €" by clicking on it, then copying ("Ctrl+C") and pasting ("Ctrl+V") into another cell. The pasted value turns out incorrect as "15,00 €". This discrepancy occurs because the copied value in the clipboard is represented as "1.5" and is interpreted incorrectly upon pasting.
I've included the necessary HTML and JavaScript code snippets below:
<div id="exampleGrid"></div>
Javascript:
(function () {
var language = {
delimiters: {
thousands: '.',
decimal: ','
},
abbreviations: {
thousand: 'k',
million: 'm',
billion: 'b',
trillion: 't'
},
ordinal: function (number) {
return '.';
},
currency: {
symbol: '€'
}
};
if (typeof window !== 'undefined' && this.numeral && this.numeral.language) {
this.numeral.language('de', language);
}
}());
$("#exampleGrid").handsontable({
data: [ [1.5], [] ],
rowHeaders: true,
colHeaders: true,
columns: [
{ type: 'numeric', format: '0.00 $', language: 'de'}
]
});
To further illustrate the problem, I've created a jsfiddle demonstration: http://jsfiddle.net/hU6Kz/4873/
Despite working with version 0.23.0, my attempts to work around this bug using hooks and custom validators have been unsuccessful. These approaches failed to provide the original value "1.5" within event callbacks, instead returning the erroneous value "15". Even employing the "beforeChange" hook within the handsontable constructor did not yield the desired result:
beforeChange: function (changes, source) {
for (var i = changes.length - 1; i >= 0; i--) {
console.log('Changes: source:' + source + ' row:' + changes[i][0] + ' col:' + changes[i][1] + ' old:' + changes[i][2] + ' new:' + changes[i][3]);
}
}
Upon performing the copy and paste action of "1,50 €," the console output displays:
Changes: source:paste row:1 col:0 old:null new:15
In analyzing the source code, I identified the 'validateChanges' function which contributes to the issue:
if (numeral.validate(changes[i][3])) {
changes[i][3] = numeral().unformat(changes[i][3]);
}
Executing this code with the current numeral language set as 'de' results in "15." Hence, it becomes apparent why the original copied value isn't captured accurately during the "beforeChange" hook trigger.
Moving forward, resolving this challenge poses a question mark. How can we tackle this dilemma effectively?
Update:
Further exploration reveals the impact of 'validateChanges' where:
numeral().unformat('1.5 €')
This operation confirms the derivation of "15" under the 'de' numeral language setting. As such, the timing of 'validateChanges' preceding the invocation of the hook 'beforeChange' underscores the root cause of the issue.
Now, what are the next steps to navigate through this obstacle?