fix(communities): Naming validation for communities
Channel, channels category name and community name handled according to the new validation. Fixes: #2297
This commit is contained in:
parent
341d3ebcf7
commit
b9ff88f41c
|
@ -13,29 +13,29 @@ ModalPopup {
|
||||||
property var channels: []
|
property var channels: []
|
||||||
|
|
||||||
property bool isEdit: false
|
property bool isEdit: false
|
||||||
readonly property int maxDescChars: 140
|
|
||||||
property string nameValidationError: ""
|
|
||||||
property bool isValid: nameInput.isValid
|
|
||||||
|
|
||||||
|
readonly property int maxCategoryNameLength: 30
|
||||||
|
readonly property var categoryNameValidator: Utils.Validate.NoEmpty
|
||||||
|
| Utils.Validate.TextLength
|
||||||
|
| Utils.Validate.TextLowercase
|
||||||
|
|
||||||
id: popup
|
id: popup
|
||||||
height: 453
|
height: 453
|
||||||
|
|
||||||
onOpened: {
|
onOpened: {
|
||||||
nameInput.text = isEdit ? categoryName : "";
|
|
||||||
if(isEdit){
|
if(isEdit){
|
||||||
|
nameInput.text = categoryName
|
||||||
channels = JSON.parse(chatsModel.communities.activeCommunity.getChatIdsByCategory(categoryId))
|
channels = JSON.parse(chatsModel.communities.activeCommunity.getChatIdsByCategory(categoryId))
|
||||||
}
|
}
|
||||||
nameInput.forceActiveFocus(Qt.MouseFocusReason)
|
nameInput.forceActiveFocus(Qt.MouseFocusReason)
|
||||||
if(isEdit){
|
|
||||||
validate();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
onClosed: destroy()
|
onClosed: destroy()
|
||||||
|
|
||||||
function validate() {
|
function isFormValid() {
|
||||||
nameInput.validate()
|
return Utils.validateAndReturnError(nameInput.text,
|
||||||
return isValid
|
categoryNameValidator,
|
||||||
|
qsTr("category name"),
|
||||||
|
maxCategoryNameLength) === ""
|
||||||
}
|
}
|
||||||
|
|
||||||
title: isEdit ?
|
title: isEdit ?
|
||||||
|
@ -65,25 +65,15 @@ ModalPopup {
|
||||||
Input {
|
Input {
|
||||||
id: nameInput
|
id: nameInput
|
||||||
placeholderText: qsTr("Category title")
|
placeholderText: qsTr("Category title")
|
||||||
validationError: popup.nameValidationError
|
maxLength: maxCategoryNameLength
|
||||||
|
|
||||||
property bool isValid: false
|
|
||||||
|
|
||||||
onTextEdited: {
|
onTextEdited: {
|
||||||
validate()
|
text = Utils.convertSpacesToDashesAndUpperToLowerCase(text);
|
||||||
}
|
|
||||||
|
|
||||||
function validate() {
|
validationError = Utils.validateAndReturnError(text,
|
||||||
validationError = ""
|
categoryNameValidator,
|
||||||
if (nameInput.text === "") {
|
qsTr("category name"),
|
||||||
//% "You need to enter a name"
|
maxCategoryNameLength)
|
||||||
validationError = qsTrId("you-need-to-enter-a-name")
|
|
||||||
} else if (nameInput.text.length > 100) {
|
|
||||||
//% "Your name needs to be 100 characters or shorter"
|
|
||||||
validationError = qsTrId("your-name-needs-to-be-100-characters-or-shorter")
|
|
||||||
}
|
|
||||||
isValid = validationError === ""
|
|
||||||
return validationError
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,13 +203,13 @@ ModalPopup {
|
||||||
}
|
}
|
||||||
|
|
||||||
footer: StatusButton {
|
footer: StatusButton {
|
||||||
enabled: popup.isValid
|
enabled: isFormValid()
|
||||||
text: isEdit ?
|
text: isEdit ?
|
||||||
qsTr("Save") :
|
qsTr("Save") :
|
||||||
qsTr("Create")
|
qsTr("Create")
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (!validate()) {
|
if (!isFormValid()) {
|
||||||
scrollView.scrollBackUp()
|
scrollView.scrollBackUp()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,15 +12,18 @@ ModalPopup {
|
||||||
property QtObject channel
|
property QtObject channel
|
||||||
property bool isEdit: false
|
property bool isEdit: false
|
||||||
property string categoryId: ""
|
property string categoryId: ""
|
||||||
readonly property int maxDescChars: 140
|
|
||||||
property string nameValidationError: ""
|
readonly property int maxChannelNameLength: 30
|
||||||
|
readonly property var channelNameValidator: Utils.Validate.NoEmpty
|
||||||
|
| Utils.Validate.TextLength
|
||||||
|
| Utils.Validate.TextLowercaseLettersNumberAndDashes
|
||||||
|
|
||||||
|
readonly property int maxChannelDescLength: 140
|
||||||
|
readonly property var channelDescValidator: Utils.Validate.NoEmpty
|
||||||
|
| Utils.Validate.TextLength
|
||||||
|
|
||||||
property Component pinnedMessagesPopupComponent
|
property Component pinnedMessagesPopupComponent
|
||||||
|
|
||||||
property bool isValid:
|
|
||||||
nameInput.isValid &&
|
|
||||||
descriptionTextArea.isValid
|
|
||||||
|
|
||||||
id: popup
|
id: popup
|
||||||
height: 475
|
height: 475
|
||||||
|
|
||||||
|
@ -37,10 +40,15 @@ ModalPopup {
|
||||||
}
|
}
|
||||||
onClosed: destroy()
|
onClosed: destroy()
|
||||||
|
|
||||||
function validate() {
|
function isFormValid() {
|
||||||
nameInput.validate()
|
return Utils.validateAndReturnError(nameInput.text,
|
||||||
descriptionTextArea.validate()
|
channelNameValidator,
|
||||||
return isValid
|
qsTr("channel name"),
|
||||||
|
maxChannelNameLength) === ""
|
||||||
|
&& Utils.validateAndReturnError(descriptionTextArea.text,
|
||||||
|
channelDescValidator,
|
||||||
|
qsTr("channel decription"),
|
||||||
|
maxChannelDescLength) === ""
|
||||||
}
|
}
|
||||||
|
|
||||||
//% "New channel"
|
//% "New channel"
|
||||||
|
@ -70,30 +78,15 @@ ModalPopup {
|
||||||
id: nameInput
|
id: nameInput
|
||||||
//% "A cool name"
|
//% "A cool name"
|
||||||
placeholderText: qsTrId("a-cool-name")
|
placeholderText: qsTrId("a-cool-name")
|
||||||
validationError: popup.nameValidationError
|
maxLength: popup.maxChannelNameLength
|
||||||
|
|
||||||
property bool isValid: false || isEdit
|
|
||||||
|
|
||||||
onTextEdited: {
|
onTextEdited: {
|
||||||
if (text.includes(" ")) {
|
text = Utils.convertSpacesToDashesAndUpperToLowerCase(text);
|
||||||
text = text.replace(" ", "-")
|
|
||||||
}
|
|
||||||
validate()
|
|
||||||
}
|
|
||||||
|
|
||||||
function validate() {
|
validationError = Utils.validateAndReturnError(text,
|
||||||
validationError = ""
|
channelNameValidator,
|
||||||
if (nameInput.text === "") {
|
qsTr("channel name"),
|
||||||
//% "You need to enter a name"
|
maxChannelNameLength)
|
||||||
validationError = qsTrId("you-need-to-enter-a-name")
|
|
||||||
} else if (!(/^[a-z0-9\-]+$/.test(nameInput.text))) {
|
|
||||||
validationError = qsTr("Use only lowercase letters (a to z), numbers & dashes (-). Do not use chat keys.")
|
|
||||||
} else if (nameInput.text.length > 100) {
|
|
||||||
//% "Your name needs to be 100 characters or shorter"
|
|
||||||
validationError = qsTrId("your-name-needs-to-be-100-characters-or-shorter")
|
|
||||||
}
|
|
||||||
isValid = validationError === ""
|
|
||||||
return validationError
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,36 +96,28 @@ ModalPopup {
|
||||||
label: qsTrId("channel-description")
|
label: qsTrId("channel-description")
|
||||||
//% "What your channel is about"
|
//% "What your channel is about"
|
||||||
placeholderText: qsTrId("what-your-channel-is-about")
|
placeholderText: qsTrId("what-your-channel-is-about")
|
||||||
//% "The description cannot exceed %1 characters"
|
|
||||||
validationError: descriptionTextArea.text.length > popup.maxDescChars ? qsTrId("the-description-cannot-exceed-140-characters") :
|
|
||||||
popup.descriptionValidationError || ""
|
|
||||||
anchors.top: nameInput.bottom
|
anchors.top: nameInput.bottom
|
||||||
anchors.topMargin: Style.current.bigPadding
|
anchors.topMargin: Style.current.bigPadding
|
||||||
customHeight: 88
|
customHeight: 88
|
||||||
|
|
||||||
property bool isValid: false || isEdit
|
onTextChanged: {
|
||||||
onTextChanged: validate()
|
if(text.length > maxChannelDescLength)
|
||||||
|
{
|
||||||
function resetValidation() {
|
textField.remove(maxChannelDescLength, text.length)
|
||||||
isValid = false
|
return
|
||||||
validationError = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
function validate() {
|
|
||||||
validationError = ""
|
|
||||||
if (text.length > popup.maxDescChars) {
|
|
||||||
validationError = qsTrId("the-description-cannot-exceed-140-characters")
|
|
||||||
}
|
}
|
||||||
if (text === "") {
|
|
||||||
validationError = qsTr("You need to enter a description")
|
validationError = Utils.validateAndReturnError(text,
|
||||||
}
|
channelDescValidator,
|
||||||
isValid = validationError === ""
|
qsTr("channel decription"),
|
||||||
|
maxChannelDescLength)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
id: charLimit
|
id: charLimit
|
||||||
text: `${descriptionTextArea.text.length}/${maxDescChars}`
|
text: `${descriptionTextArea.text.length}/${maxChannelDescLength}`
|
||||||
anchors.top: descriptionTextArea.bottom
|
anchors.top: descriptionTextArea.bottom
|
||||||
anchors.topMargin: !descriptionTextArea.validationError ? 5 : - Style.current.smallPadding
|
anchors.topMargin: !descriptionTextArea.validationError ? 5 : - Style.current.smallPadding
|
||||||
anchors.right: descriptionTextArea.right
|
anchors.right: descriptionTextArea.right
|
||||||
|
@ -223,14 +208,14 @@ ModalPopup {
|
||||||
}
|
}
|
||||||
|
|
||||||
footer: StatusButton {
|
footer: StatusButton {
|
||||||
enabled: popup.isValid
|
enabled: isFormValid()
|
||||||
text: isEdit ?
|
text: isEdit ?
|
||||||
qsTr("Save") :
|
qsTr("Save") :
|
||||||
//% "Create"
|
//% "Create"
|
||||||
qsTrId("create")
|
qsTrId("create")
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (!validate()) {
|
if (!isFormValid()) {
|
||||||
scrollView.scrollBackUp()
|
scrollView.scrollBackUp()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,15 +7,20 @@ import "../../../../shared"
|
||||||
import "../../../../shared/status"
|
import "../../../../shared/status"
|
||||||
|
|
||||||
ModalPopup {
|
ModalPopup {
|
||||||
readonly property int maxDescChars: 140
|
|
||||||
|
|
||||||
property QtObject community: chatsModel.communities.activeCommunity
|
property QtObject community: chatsModel.communities.activeCommunity
|
||||||
|
|
||||||
property bool isEdit: false
|
property bool isEdit: false
|
||||||
property bool isValid:
|
|
||||||
nameInput.isValid &&
|
readonly property int maxCommunityNameLength: 30
|
||||||
descriptionTextArea.isValid &&
|
readonly property var communityNameValidator: Utils.Validate.NoEmpty
|
||||||
colorPicker.isValid
|
| Utils.Validate.TextLength
|
||||||
|
|
||||||
|
readonly property int maxCommunityDescLength: 140
|
||||||
|
readonly property var communityDescValidator: Utils.Validate.NoEmpty
|
||||||
|
| Utils.Validate.TextLength
|
||||||
|
|
||||||
|
readonly property var communityColorValidator: Utils.Validate.NoEmpty
|
||||||
|
| Utils.Validate.TextHexColor
|
||||||
|
|
||||||
id: popup
|
id: popup
|
||||||
height: 600
|
height: 600
|
||||||
|
@ -34,11 +39,17 @@ ModalPopup {
|
||||||
}
|
}
|
||||||
onClosed: destroy()
|
onClosed: destroy()
|
||||||
|
|
||||||
function validate() {
|
function isFormValid() {
|
||||||
nameInput.validate()
|
return Utils.validateAndReturnError(nameInput.text,
|
||||||
descriptionTextArea.validate()
|
communityNameValidator,
|
||||||
colorPicker.validate()
|
qsTr("community name"),
|
||||||
return isValid
|
maxCommunityNameLength) === ""
|
||||||
|
&& Utils.validateAndReturnError(descriptionTextArea.text,
|
||||||
|
communityDescValidator,
|
||||||
|
qsTr("community decription"),
|
||||||
|
maxCommunityDescLength) === ""
|
||||||
|
&& Utils.validateAndReturnError(colorPicker.text,
|
||||||
|
communityColorValidator) === ""
|
||||||
}
|
}
|
||||||
|
|
||||||
title: isEdit ?
|
title: isEdit ?
|
||||||
|
@ -78,28 +89,13 @@ ModalPopup {
|
||||||
label: qsTrId("name-your-community")
|
label: qsTrId("name-your-community")
|
||||||
//% "A catchy name"
|
//% "A catchy name"
|
||||||
placeholderText: qsTrId("name-your-community-placeholder")
|
placeholderText: qsTrId("name-your-community-placeholder")
|
||||||
property bool isValid: false
|
maxLength: maxCommunityNameLength
|
||||||
|
|
||||||
onTextEdited: {
|
onTextEdited: {
|
||||||
if (text.includes(" ")) {
|
validationError = Utils.validateAndReturnError(text,
|
||||||
text = text.replace(" ", "-")
|
communityNameValidator,
|
||||||
}
|
qsTr("community name"),
|
||||||
validate()
|
maxCommunityNameLength)
|
||||||
}
|
|
||||||
|
|
||||||
function validate() {
|
|
||||||
validationError = ""
|
|
||||||
if (nameInput.text === "") {
|
|
||||||
//% "You need to enter a name"
|
|
||||||
validationError = qsTrId("you-need-to-enter-a-name")
|
|
||||||
} else if (!(/^[a-z0-9\-]+$/.test(nameInput.text))) {
|
|
||||||
validationError = qsTr("Use only lowercase letters (a to z), numbers & dashes (-). Do not use chat keys.")
|
|
||||||
} else if (nameInput.text.length > 100) {
|
|
||||||
//% "Your name needs to be 100 characters or shorter"
|
|
||||||
validationError = qsTrId("your-name-needs-to-be-100-characters-or-shorter")
|
|
||||||
}
|
|
||||||
isValid = validationError === ""
|
|
||||||
return validationError
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,37 +105,29 @@ ModalPopup {
|
||||||
label: qsTrId("give-a-short-description-community")
|
label: qsTrId("give-a-short-description-community")
|
||||||
//% "What your community is about"
|
//% "What your community is about"
|
||||||
placeholderText: qsTrId("what-your-community-is-about")
|
placeholderText: qsTrId("what-your-community-is-about")
|
||||||
//% "The description cannot exceed 140 characters"
|
|
||||||
validationError: descriptionTextArea.text.length > popup.maxDescChars ? qsTrId("the-description-cannot-exceed-140-characters") :
|
|
||||||
popup.descriptionValidationError || ""
|
|
||||||
anchors.top: nameInput.bottom
|
anchors.top: nameInput.bottom
|
||||||
anchors.topMargin: Style.current.bigPadding
|
anchors.topMargin: Style.current.bigPadding
|
||||||
customHeight: 88
|
customHeight: 88
|
||||||
textField.wrapMode: TextEdit.Wrap
|
textField.wrapMode: TextEdit.Wrap
|
||||||
|
|
||||||
property bool isValid: false
|
onTextChanged: {
|
||||||
onTextChanged: validate()
|
if(text.length > maxCommunityDescLength)
|
||||||
|
{
|
||||||
function resetValidation() {
|
textField.remove(maxCommunityDescLength, text.length)
|
||||||
isValid = false
|
return
|
||||||
validationError = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
function validate() {
|
|
||||||
validationError = ""
|
|
||||||
if (text.length > popup.maxDescChars) {
|
|
||||||
validationError = qsTrId("the-description-cannot-exceed-140-characters")
|
|
||||||
}
|
}
|
||||||
if (text === "") {
|
|
||||||
validationError = qsTr("You need to enter a description")
|
validationError = Utils.validateAndReturnError(text,
|
||||||
}
|
communityDescValidator,
|
||||||
isValid = validationError === ""
|
qsTr("community decription"),
|
||||||
|
maxCommunityDescLength)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
id: charLimit
|
id: charLimit
|
||||||
text: `${descriptionTextArea.text.length}/${popup.maxDescChars}`
|
text: `${descriptionTextArea.text.length}/${maxCommunityDescLength}`
|
||||||
anchors.top: descriptionTextArea.bottom
|
anchors.top: descriptionTextArea.bottom
|
||||||
anchors.topMargin: !descriptionTextArea.validationError ? 5 : - Style.current.smallPadding
|
anchors.topMargin: !descriptionTextArea.validationError ? 5 : - Style.current.smallPadding
|
||||||
anchors.right: descriptionTextArea.right
|
anchors.right: descriptionTextArea.right
|
||||||
|
@ -285,7 +273,6 @@ ModalPopup {
|
||||||
|
|
||||||
Input {
|
Input {
|
||||||
property string defaultColor: Style.current.blue
|
property string defaultColor: Style.current.blue
|
||||||
property bool isValid: true
|
|
||||||
|
|
||||||
id: colorPicker
|
id: colorPicker
|
||||||
label: qsTr("Community color")
|
label: qsTr("Community color")
|
||||||
|
@ -295,21 +282,8 @@ ModalPopup {
|
||||||
textField.text: defaultColor
|
textField.text: defaultColor
|
||||||
textField.onReleased: colorDialog.open()
|
textField.onReleased: colorDialog.open()
|
||||||
|
|
||||||
onTextChanged: validate()
|
onTextChanged: {
|
||||||
|
validationError = Utils.validateAndReturnError(text, communityColorValidator)
|
||||||
function resetValidation() {
|
|
||||||
isValid = true
|
|
||||||
validationError = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
function validate() {
|
|
||||||
validationError = ""
|
|
||||||
if (text === "") {
|
|
||||||
validationError = qsTr("Please enter a color")
|
|
||||||
} else if (!Utils.isHexColor(colorPicker.text)) {
|
|
||||||
validationError = qsTr("Must be an hexadecimal color (eg: #4360DF)")
|
|
||||||
}
|
|
||||||
isValid = validationError === ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusIconButton {
|
StatusIconButton {
|
||||||
|
@ -447,6 +421,7 @@ ModalPopup {
|
||||||
}
|
}
|
||||||
StatusButton {
|
StatusButton {
|
||||||
id: btnCreateEdit
|
id: btnCreateEdit
|
||||||
|
enabled: isFormValid()
|
||||||
text: isEdit ?
|
text: isEdit ?
|
||||||
//% "Save"
|
//% "Save"
|
||||||
qsTrId("Save") :
|
qsTrId("Save") :
|
||||||
|
@ -454,7 +429,7 @@ ModalPopup {
|
||||||
qsTrId("create")
|
qsTrId("create")
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (!validate()) {
|
if (!isFormValid()) {
|
||||||
scrollView.scrollBackUp()
|
scrollView.scrollBackUp()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -556,6 +556,57 @@ QtObject {
|
||||||
return Array.from(new Set(array))
|
return Array.from(new Set(array))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hasUpperCaseLetter(str) {
|
||||||
|
return (/[A-Z]/.test(str))
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertSpacesToDashesAndUpperToLowerCase(str)
|
||||||
|
{
|
||||||
|
if (str.includes(" "))
|
||||||
|
str = str.replace(/ /g, "-")
|
||||||
|
|
||||||
|
if(hasUpperCaseLetter(str))
|
||||||
|
str = str.toLowerCase()
|
||||||
|
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validation section start */
|
||||||
|
|
||||||
|
enum Validate {
|
||||||
|
NoEmpty = 0x01,
|
||||||
|
TextLength = 0x02,
|
||||||
|
TextHexColor = 0x04,
|
||||||
|
TextLowercaseLettersNumberAndDashes = 0x08
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateAndReturnError(str, validation, fieldName = "field", limit = 0)
|
||||||
|
{
|
||||||
|
let errMsg = ""
|
||||||
|
|
||||||
|
if(validation & Utils.Validate.NoEmpty && str === "") {
|
||||||
|
errMsg = qsTr("You need to enter a %1").arg(fieldName)
|
||||||
|
}
|
||||||
|
|
||||||
|
if(validation & Utils.Validate.TextLength && str.length > limit) {
|
||||||
|
errMsg = qsTr("The %1 cannot exceed %2 characters").arg(fieldName, limit)
|
||||||
|
}
|
||||||
|
|
||||||
|
if(validation & Utils.Validate.TextHexColor && !isHexColor(str)) {
|
||||||
|
errMsg = qsTr("Must be an hexadecimal color (eg: #4360DF)")
|
||||||
|
}
|
||||||
|
|
||||||
|
if(validation & Utils.Validate.TextLowercaseLettersNumberAndDashes && !isValidChannelName(str)) {
|
||||||
|
errMsg = qsTr("Use only lowercase letters (a to z), numbers & dashes (-). Do not use chat keys.")
|
||||||
|
}
|
||||||
|
|
||||||
|
return errMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validation section end */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Leave this function at the bottom of the file as QT Creator messes up the code color after this
|
// Leave this function at the bottom of the file as QT Creator messes up the code color after this
|
||||||
function isPunct(c) {
|
function isPunct(c) {
|
||||||
return /(!|\@|#|\$|%|\^|&|\*|\(|\)|_|\+|\||-|=|\\|{|}|[|]|"|;|'|<|>|\?|,|\.|\/)/.test(c)
|
return /(!|\@|#|\$|%|\^|&|\*|\(|\)|_|\+|\||-|=|\\|{|}|[|]|"|;|'|<|>|\?|,|\.|\/)/.test(c)
|
||||||
|
|
|
@ -9,6 +9,7 @@ Item {
|
||||||
property string placeholderText: "My placeholder"
|
property string placeholderText: "My placeholder"
|
||||||
property string placeholderTextColor: Style.current.secondaryText
|
property string placeholderTextColor: Style.current.secondaryText
|
||||||
property alias text: inputValue.text
|
property alias text: inputValue.text
|
||||||
|
property alias maxLength: inputValue.maximumLength
|
||||||
property string validationError: ""
|
property string validationError: ""
|
||||||
property alias validationErrorAlignment: validationErrorText.horizontalAlignment
|
property alias validationErrorAlignment: validationErrorText.horizontalAlignment
|
||||||
property int validationErrorTopMargin: 1
|
property int validationErrorTopMargin: 1
|
||||||
|
|
Loading…
Reference in New Issue