diff --git a/src/components/input/Input.js b/src/components/input/Input.js index a4c4a16e..e1bcd34f 100644 --- a/src/components/input/Input.js +++ b/src/components/input/Input.js @@ -34,27 +34,6 @@ const VALIDATION_MESSAGES = { valueMissing: "Bitte füllen Sie das Feld aus.", } -/** - * Creates an error list with an item for the given validity state. - * @param {ValidityState} validityState - * @param {Object} validationMessages - * @param {String} idRef - * @returns - */ -const ErrorList = (validityState, validationMessages, idRef) => { - const errorMessages = Object.entries(validationMessages) - .filter(([property]) => validityState[property]) - .map(([_, message]) => message) - - return html` - - ` -} - /** * @attr {boolean} disabled - Disables the input element. * @attr {boolean} required - Marks the input element as required. @@ -62,6 +41,7 @@ const ErrorList = (validityState, validationMessages, idRef) => { * @attr {string} value - The value of the input element. * @attr {string} name - The name of the input element. * @attr {string} label - The label of the input element. + * @attr {string} error - A custom error that is completely independent of the validity state. Useful for displaying server side errors. * @attr {string} size - The size of the input element. * @attr {string} icon - The icon that is displayed at the end of the input element. * @attr {string} prefix - A prefix that relates to the value of the input (e.g. CHF). @@ -89,6 +69,7 @@ export class LeuInput extends LitElement { value: { type: String }, name: { type: String }, + error: { type: String }, label: { type: String }, prefix: { type: String }, @@ -110,6 +91,14 @@ export class LeuInput extends LitElement { _validity: { state: true }, } + static resolveErrorMessage(message, refernceValue) { + if (typeof message === "function") { + return message(refernceValue) + } + + return message + } + constructor() { super() @@ -119,6 +108,7 @@ export class LeuInput extends LitElement { this.value = "" this.name = "" + this.error = "" this.label = "" this.prefix = "" @@ -281,20 +271,56 @@ export class LeuInput extends LitElement { const { tooLong, tooShort, rangeOverflow, rangeUnderflow } = validationMessages - function resolveMessage(message, refernceValue) { - if (typeof message === "function") { - return message(refernceValue) - } + validationMessages.tooLong = LeuInput.resolveErrorMessage( + tooLong, + this.maxlength + ) + validationMessages.tooShort = LeuInput.resolveErrorMessage( + tooShort, + this.minlength + ) + validationMessages.rangeOverflow = LeuInput.resolveErrorMessage( + rangeOverflow, + this.max + ) + validationMessages.rangeUnderflow = LeuInput.resolveErrorMessage( + rangeUnderflow, + this.min + ) + + return validationMessages + } - return message + /** + * Creates an error list with an item for the given validity state. + * @param {ValidityState} validityState + * @param {Object} validationMessages + * @param {String} idRef + * @returns + */ + renderErrorMessages() { + if (!this.isInvalid()) { + return nothing } - validationMessages.tooLong = resolveMessage(tooLong, this.maxlength) - validationMessages.tooShort = resolveMessage(tooShort, this.minlength) - validationMessages.rangeOverflow = resolveMessage(rangeOverflow, this.max) - validationMessages.rangeUnderflow = resolveMessage(rangeUnderflow, this.min) + const validationMessages = this.getValidationMessages() + let errorMessages = this._validity + ? Object.entries(validationMessages) + .filter(([property]) => this._validity[property]) + .map(([_, message]) => message) + : [] - return validationMessages + if (this.error !== "") { + errorMessages = [this.error, errorMessages] + } + + return html` + + ` } /** @@ -328,6 +354,10 @@ export class LeuInput extends LitElement { } isInvalid() { + if (this.error !== "") { + return true + } + return this._validity === null || this.novalidate ? false : !this._validity.valid @@ -378,13 +408,7 @@ export class LeuInput extends LitElement { : nothing} ${this.renderAfterContent()} - ${isInvalid - ? ErrorList( - this._validity, - this.getValidationMessages(), - `input-${this.getId()}` - ) - : nothing} + ${this.renderErrorMessages()} ` } } diff --git a/src/components/input/stories/input.stories.js b/src/components/input/stories/input.stories.js index 34bde65c..1e6935f5 100644 --- a/src/components/input/stories/input.stories.js +++ b/src/components/input/stories/input.stories.js @@ -24,6 +24,7 @@ function Template(args) { const { label, value, + error, pattern, prefix, suffix, @@ -43,6 +44,7 @@ function Template(args) { return html`