From 1a23cc191251c081614d2db3c040226963eaf724 Mon Sep 17 00:00:00 2001 From: Pascal Precht Date: Fri, 10 Sep 2021 12:44:38 +0200 Subject: [PATCH] feat(StatusValidator): allow validators to provide default `errorMessage` Validators can now define a default `errorMessage` like so: ```qml StatusValidator { ... errorMessage: "..." } ``` Because there's no access to runtime validation errors, `errorMessage` have to be static. However, if applications wish to provide their own `errorMessage` they can still override it and make it dynamic: ```qml SomeValidator { ... errorMessage: input.errors.someValidator ? "Whoopsie" : "" } ``` --- sandbox/StatusInputPage.qml | 17 +++++++------ src/StatusQ/Controls/StatusInput.qml | 24 ++++++++++++++----- .../Validators/StatusMinLengthValidator.qml | 6 +++++ .../Controls/Validators/StatusValidator.qml | 1 + 4 files changed, 35 insertions(+), 13 deletions(-) diff --git a/sandbox/StatusInputPage.qml b/sandbox/StatusInputPage.qml index bd86b08e..617ffc1c 100644 --- a/sandbox/StatusInputPage.qml +++ b/sandbox/StatusInputPage.qml @@ -84,19 +84,22 @@ Column { } StatusInput { + id: input label: "Label" charLimit: 30 input.placeholderText: "Input with validator" validators: [ - StatusMinLengthValidator { minLength: 10 } - ] - - onTextChanged: { - if (errors && errors.minLength) { - errorMessage = `Value can't be shorter than ${errors.minLength.min} but got ${errors.minLength.actual}` + StatusMinLengthValidator { + minLength: 10 + errorMessage: { + if (input.errors && input.errors.minLength) { + return `Value can't be shorter than ${input.errors.minLength.min} but got ${input.errors.minLength.actual}` + } + return "" + } } - } + ] } StatusInput { diff --git a/src/StatusQ/Controls/StatusInput.qml b/src/StatusQ/Controls/StatusInput.qml index 8c2e1915..02fecc82 100644 --- a/src/StatusQ/Controls/StatusInput.qml +++ b/src/StatusQ/Controls/StatusInput.qml @@ -34,18 +34,30 @@ Item { property var errors: ({}) function validate() { + statusBaseInput.valid = true if (validators.length) { for (let idx in validators) { - let result = validators[idx].validate(statusBaseInput.text) + let validator = validators[idx] + let result = validator.validate(statusBaseInput.text) if (typeof result === "boolean" && result) { - statusBaseInput.valid = true + statusBaseInput.valid = statusBaseInput.valid && true + delete errors[validator.name] } else { if (!errors) { errors = {} } - errors[validators[idx].name] = result - statusBaseInput.valid = false + result.errorMessage = validator.errorMessage + errors[validator.name] = result + statusBaseInput.valid = statusBaseInput.valid && false + } + } + if (errors){ + let errs = Object.values(errors) + if (errs && errs[0]) { + errorMessage.text = errs[0].errorMessage || root.errorMessage; + } else { + errorMessage.text = "" } } } @@ -123,11 +135,11 @@ Item { anchors.leftMargin: 16 height: visible ? implicitHeight : 0 - visible: !!root.errorMessage && !statusBaseInput.valid + visible: !!text && !statusBaseInput.valid font.pixelSize: 12 color: Theme.palette.dangerColor1 - text: root.errorMessage + horizontalAlignment: Text.AlignRight wrapMode: Text.WordWrap diff --git a/src/StatusQ/Controls/Validators/StatusMinLengthValidator.qml b/src/StatusQ/Controls/Validators/StatusMinLengthValidator.qml index f6a2c171..f9b4ca85 100644 --- a/src/StatusQ/Controls/Validators/StatusMinLengthValidator.qml +++ b/src/StatusQ/Controls/Validators/StatusMinLengthValidator.qml @@ -6,6 +6,12 @@ StatusValidator { name: "minLength" + errorMessage: { + minLength === 1 ? + "Please enter a value" : + `The value must be at least ${minLength} characters.` + } + validate: function (value) { return value.length >= minLength ? true : { min: minLength, diff --git a/src/StatusQ/Controls/Validators/StatusValidator.qml b/src/StatusQ/Controls/Validators/StatusValidator.qml index 3e12d5b7..05bfd6cc 100644 --- a/src/StatusQ/Controls/Validators/StatusValidator.qml +++ b/src/StatusQ/Controls/Validators/StatusValidator.qml @@ -4,6 +4,7 @@ QtObject { id: statusValidator property string name: "" + property string errorMessage: "invalid input" property var validate: function (value) { return true