From 0e5740e935dffd3aaba073c4b490f1a8e17894e4 Mon Sep 17 00:00:00 2001 From: Kateryna Tkachenko Date: Thu, 18 Apr 2024 13:41:51 +0200 Subject: [PATCH] Additional validation for integers --- package.json | 2 +- src/EditText/EditText.js | 4 +++ src/TextInput/TextInputValidityState.js | 38 +++++++++++++++++++++---- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index e438b85..2056859 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@elsci-io/ui-essential", - "version": "1.0.56", + "version": "1.0.57", "description": "Material Design components created for products built by elsci.io", "main": "src/index.js", "type": "module", diff --git a/src/EditText/EditText.js b/src/EditText/EditText.js index 8d9cf0e..7c40216 100644 --- a/src/EditText/EditText.js +++ b/src/EditText/EditText.js @@ -234,6 +234,9 @@ export default class EditText extends HTMLElement { let patternAttr = ""; if (this.hasAttribute("pattern")) patternAttr = `pattern="${this.getAttribute("pattern")}"` + let numberTypeAttr = ""; + if (this.hasAttribute("number-type")) + numberTypeAttr = `number-type="${this.getAttribute("number-type")}"` return ` `; diff --git a/src/TextInput/TextInputValidityState.js b/src/TextInput/TextInputValidityState.js index 9ea5849..e166269 100644 --- a/src/TextInput/TextInputValidityState.js +++ b/src/TextInput/TextInputValidityState.js @@ -53,9 +53,10 @@ export default class TextInputValidityState { {badInput, customError, patternMismatch, typeMismatch, valid, rangeOverflow, rangeUnderflow, tooLong, tooShort, valueMissing, stepMismatch}, this.#isBlanknessConstraintViolated(), - this.#isRangeConstraintViolated() + this.#isRangeConstraintViolated(), + this.#isStepConstraintViolated() ); - cv.valid = !cv.valueMissing && !cv.rangeUnderflow && !cv.rangeOverflow; + cv.valid = !cv.valueMissing && !cv.rangeUnderflow && !cv.rangeOverflow && !cv.stepMismatch; return cv; } @@ -82,14 +83,41 @@ export default class TextInputValidityState { return {rangeUnderflow: (min !== "" && +value < +min), rangeOverflow: (max !== "" && +value > +max)}; } + /** + * This method serves to supplement internal validation to determine whether a float qualifies as an integer. + * The internal validation for an input type="number" step="1" doesn't consistently cover all cases. + * For example, the number 2.00000001 might be considered an integer by the internal validator. + * So we are using attribute 'number-type="integer"' + * The aim is to widen this validation range. Now, the comparison for an integer works correctly when a number + * has no more than 16 digits. However, if a number has 17 digits or more, this function returns incorrect result. + * @return {{stepMismatch: boolean}} + */ + #isStepConstraintViolated() { + if (this.#inputElement.type !== "number") + return {stepMismatch: false}; + const numberType = this.#textInput.getAttribute('number-type'); + if (!numberType || numberType !== "integer") + return {stepMismatch: false}; + const stepMismatch = !Number.isInteger(this.#inputElement.valueAsNumber); + return {stepMismatch: stepMismatch}; + } + #getValidationMessage(validityState) { const isTypeNumber = this.#inputElement.type === "number"; const {badInput, rangeOverflow, rangeUnderflow, tooLong, tooShort, valueMissing, stepMismatch} = validityState; if (isTypeNumber && badInput) return "Invalid number"; - if (isTypeNumber && stepMismatch && this.#inputElement.step === "1") { - // Here we validate only floats because if step is 1, then the value must be an integer. - return "Must be an integer"; + if (isTypeNumber && stepMismatch) { + if (this.#inputElement.step === "1" ){ + // Here we checked floats because if step is 1, then the value must be an integer. + // Now we can use attribute 'number-type="integer"', but we have previously written inputs, + // that's why don't want to remove this code + return "Must be an integer"; + } + const numberType = this.#textInput.getAttribute('number-type'); + if (numberType || numberType === "integer") { + return "Must be an integer"; + } } if (rangeOverflow) return "Greater than " + this.#inputElement.max;