Created
July 1, 2023 07:24
-
-
Save smourier/859d0e2448591e407adff0f7f8a4ba13 to your computer and use it in GitHub Desktop.
An AG-Grid numeric editor that supports comma or dot as decimal separator.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// backspace starts the editor on Windows | |
const KEY_BACKSPACE = 'Backspace'; | |
// a numeric editor that supports comma or dot as decimal separator | |
class numericEditor { | |
init(params) { | |
// get separator, only used for initial input | |
this.decimalSeparator = params.decimalSeparator; | |
// create the cell | |
this.eInput = document.createElement('input'); | |
this.eInput.classList.add('numeric-input'); | |
if (params.eventKey === KEY_BACKSPACE) { | |
this.eInput.value = ''; | |
} | |
else if (this.isCharNumeric(params.eventKey)) { | |
this.eInput.value = params.eventKey; | |
} | |
else if (params.value !== undefined && params.value !== null) { | |
this.eInput.value = params.value; | |
if (this.decimalSeparator && this.decimalSeparator !== '.') { | |
this.eInput.value = this.eInput.value.replace('.', this.decimalSeparator); | |
} | |
} | |
this.eInput.addEventListener('keydown', (event) => { | |
if (!event.key || event.key.length !== 1) | |
return; | |
if (!this.isNumericKey(event) && event.key != ',' && event.key != '.') { | |
this.eInput.focus(); | |
if (event.preventDefault) event.preventDefault(); | |
return; | |
} | |
if (this.isNavigationKey(event) || this.isBackspace(event)) { | |
event.stopPropagation(); | |
return; | |
} | |
// compute the new value after keydown | |
// if it's incorrect don't let the key pass | |
let newValue = this.eInput.value; | |
newValue = newValue.slice(0, event.target.selectionStart) + event.key + newValue.slice(event.target.selectionStart); | |
const norm = this.normalizeValue(newValue); | |
if (norm == null) { | |
this.eInput.focus(); | |
if (event.preventDefault) event.preventDefault(); | |
return; | |
} | |
}); | |
// only start edit if key pressed is a number, not a letter (not comma nor dot) | |
const isNotANumber = | |
params.eventKey && | |
params.eventKey.length === 1 && | |
'1234567890'.indexOf(params.eventKey) < 0; | |
this.cancelBeforeStart = !!isNotANumber; | |
} | |
isBackspace(event) { | |
return event.key === KEY_BACKSPACE; | |
} | |
isNavigationKey(event) { | |
return event.key === 'ArrowLeft' || event.key === 'ArrowRight'; | |
} | |
getGui() { | |
return this.eInput; | |
} | |
afterGuiAttached() { | |
this.eInput.focus(); | |
} | |
isCancelBeforeStart() { | |
return this.cancelBeforeStart; | |
} | |
isCancelAfterEnd() { | |
const value = this.getValue(); | |
return value == null; | |
} | |
getValue() { | |
return this.normalizeValue(this.eInput.value); | |
} | |
isPopup() { | |
return false; | |
} | |
isCharNumeric(charStr) { | |
return charStr && !!/\d/.test(charStr); | |
} | |
isNumericKey(event) { | |
const charStr = event.key; | |
return this.isCharNumeric(charStr); | |
} | |
// transform a text with comma or dot into a numeric value | |
normalizeValue(value) { | |
if (!value) | |
return null; | |
const commas = (value.match(/,/g) || []).length; | |
const dots = (value.match(/\./g) || []).length; | |
if (commas > 0 && dots > 0) // can't mix both | |
return null; | |
if (commas > 1 || dots > 1) // too many | |
return null; | |
if (!commas) { | |
const number = Number.parseFloat(value); | |
if (!Number.isFinite(number)) | |
return null; | |
return number; | |
} | |
const number = Number.parseFloat(value.replace(',', '.')); | |
if (!Number.isFinite(number)) | |
return null; | |
return number; | |
} | |
// replace back commas if there were any in original text | |
normalizeValueToString(value) { | |
const number = this.normalizeValue(value); | |
if (number == null) | |
return value; | |
const hasComma = value.indexOf(',') >= 0; | |
if (!hasComma) | |
return number.toString(); | |
return number.toString().replace('.', ','); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment