Skip to content

Commit

Permalink
Password Form Field validation
Browse files Browse the repository at this point in the history
  • Loading branch information
SAUL committed Oct 23, 2024
1 parent aba6a1a commit 21c3b6c
Show file tree
Hide file tree
Showing 4 changed files with 239 additions and 59 deletions.
7 changes: 7 additions & 0 deletions src/main/kotlin/core/form/validation/CommonRules.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ val emailRule: ValidationRule = ValidationRule(
errorMessage = "Invalid email address"
)

val urlRule: ValidationRule = ValidationRule(
condition = {url ->
url.matches(Regex("^https?://(?:www\\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b[-a-zA-Z0-9()@:%_+.~#?&/=]*$"))
},
errorMessage = "Invalid URL"
)

val passwordRule: ValidationRule = ValidationRule(
condition = { password ->
password.length >= 8 &&
Expand Down
214 changes: 156 additions & 58 deletions src/main/kotlin/ui/components/forms/PasswordForm.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,39 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import core.form.validation.FormValidator
import ui.components.FormTextField
import ui.components.PasswordTextField
import ui.theme.Font
import ui.theme.primary
import ui.theme.secondary
import ui.validators.PasswordFormFieldName

@Preview
@Composable
fun PasswordForm() {
fun PasswordForm(
formValidator: FormValidator,
isFormValid: Boolean,
onSaveClick: () -> Unit
) {

val userName = formValidator.getField(PasswordFormFieldName.USERNAME)
val email = formValidator.getField(PasswordFormFieldName.EMAIL)
val password = formValidator.getField(PasswordFormFieldName.PASSWORD)

val name = formValidator.getField(PasswordFormFieldName.NAME)
val webSiteUrl = formValidator.getField(PasswordFormFieldName.WEBSITE_URL)
val icon = formValidator.getField(PasswordFormFieldName.WEBSITE_ICON_URL)

Column(
modifier = Modifier.fillMaxSize()
.background(secondary)
.background(secondary)
)
{

Row(
modifier = Modifier.weight(1f)
.fillMaxSize(),
.fillMaxSize(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
Expand All @@ -52,86 +66,170 @@ fun PasswordForm() {

Row(
modifier = Modifier.weight(7.5f)
.fillMaxSize()
.fillMaxSize()
) {

Column(
modifier = Modifier.weight(1f)
.fillMaxSize()
.background(primary)
.padding(PaddingValues(end = 20.dp)),
.fillMaxSize()
.background(primary)
.padding(PaddingValues(end = 20.dp)),
horizontalAlignment = Alignment.End,
verticalArrangement = Arrangement.spacedBy(30.dp, Alignment.CenterVertically)
verticalArrangement = Arrangement.spacedBy(5.dp, Alignment.CenterVertically)
) {
FormTextField(
value = "fe",
onValueChange = {},
label = "Username",
icon = Icons.Filled.AccountCircle,
modifier = Modifier.height(45.dp).width(400.dp)
)
FormTextField(
value = "fe",
onValueChange = {},
label = "Email",
icon = Icons.Filled.Email,
modifier = Modifier.height(45.dp).width(400.dp)
)
PasswordTextField(
value = "fe",
onValueChange = {},
label = "Password",
modifier = Modifier.height(45.dp).width(400.dp)
)
Column(modifier = Modifier.height(80.dp)) {
FormTextField(
value = userName?.value?.value ?: "",
onValueChange = { newValue ->
userName?.value?.value = newValue
formValidator.validateField(PasswordFormFieldName.USERNAME)
},
label = "Username",
icon = Icons.Filled.AccountCircle,
modifier = Modifier.height(45.dp).width(400.dp)
)
userName?.error?.value?.let {
Text(
text = it,
color = Color.Red,
fontFamily = Font.RobotoRegular,
fontSize = 10.sp,
modifier = Modifier.padding(start = 8.dp)
)
}
}
Column(modifier = Modifier.height(80.dp)) {
FormTextField(
value = email?.value?.value ?: "",
onValueChange = { newValue ->
email?.value?.value = newValue
formValidator.validateField(PasswordFormFieldName.EMAIL)
},
label = "Email",
icon = Icons.Filled.Email,
modifier = Modifier.height(45.dp).width(400.dp)
)
email?.error?.value?.let {
Text(
text = it,
color = Color.Red,
fontFamily = Font.RobotoRegular,
fontSize = 10.sp,
modifier = Modifier.padding(start = 8.dp)
)
}
}
Column(modifier = Modifier.height(80.dp)) {
PasswordTextField(
value = password?.value?.value ?: "",
onValueChange = { newValue ->
password?.value?.value = newValue
formValidator.validateField(PasswordFormFieldName.PASSWORD)
},
label = "Password",
modifier = Modifier.height(45.dp).width(400.dp)
)
password?.error?.value?.let {
Text(
text = it,
color = Color.Red,
fontFamily = Font.RobotoRegular,
fontSize = 10.sp,
modifier = Modifier.padding(start = 8.dp)
)
}
}
}

Column(
modifier = Modifier.weight(1f)
.fillMaxSize()
.background(primary)
.padding(PaddingValues(start = 20.dp)),
.fillMaxSize()
.background(primary)
.padding(PaddingValues(start = 20.dp)),
horizontalAlignment = Alignment.Start,
verticalArrangement = Arrangement.spacedBy(30.dp, Alignment.CenterVertically)
verticalArrangement = Arrangement.spacedBy(5.dp, Alignment.CenterVertically)
) {
FormTextField(
value = "fe",
onValueChange = {},
label = "Name",
icon = Icons.Filled.Web,
modifier = Modifier.height(45.dp).width(400.dp)
)
FormTextField(
value = "fe",
onValueChange = {},
label = "Website Url",
icon = Icons.Filled.Link,
modifier = Modifier.height(45.dp).width(400.dp)
)
FormTextField(
value = "fe",
onValueChange = {},
label = "Website Icon Url",
icon = Icons.Filled.Info,
modifier = Modifier.height(45.dp).width(400.dp)
)
Column(modifier = Modifier.height(80.dp)) {
FormTextField(
value = name?.value?.value ?: "",
onValueChange = { newValue ->
name?.value?.value = newValue
formValidator.validateField(PasswordFormFieldName.NAME)
},
label = "Name",
icon = Icons.Filled.Web,
modifier = Modifier.height(45.dp).width(400.dp)
)
name?.error?.value?.let {
Text(
text = it,
color = Color.Red,
fontFamily = Font.RobotoRegular,
fontSize = 10.sp,
modifier = Modifier.padding(start = 8.dp)
)
}
}
Column(modifier = Modifier.height(80.dp)) {
FormTextField(
value = webSiteUrl?.value?.value ?: "",
onValueChange = { newValue ->
webSiteUrl?.value?.value = newValue
formValidator.validateField(PasswordFormFieldName.WEBSITE_URL)
},
label = "Website Url",
icon = Icons.Filled.Link,
modifier = Modifier.height(45.dp).width(400.dp)
)
webSiteUrl?.error?.value?.let {
Text(
text = it,
color = Color.Red,
fontFamily = Font.RobotoRegular,
fontSize = 10.sp,
modifier = Modifier.padding(start = 8.dp)
)
}
}
Column(modifier = Modifier.height(80.dp)) {
FormTextField(
value = icon?.value?.value ?: "",
onValueChange = { newValue ->
icon?.value?.value = newValue
formValidator.validateField(PasswordFormFieldName.WEBSITE_ICON_URL)
},
label = "Website Icon Url",
icon = Icons.Filled.Info,
modifier = Modifier.height(45.dp).width(400.dp)
)
icon?.error?.value?.let {
Text(
text = it,
color = Color.Red,
fontFamily = Font.RobotoRegular,
fontSize = 10.sp,
modifier = Modifier.padding(start = 8.dp)
)
}
}
}
}

Row(
modifier = Modifier.weight(1.5f)
.fillMaxSize()
.background(primary),
.fillMaxSize()
.background(primary),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(30.dp, Alignment.CenterHorizontally)
) {
Button(
onClick = {},
modifier = Modifier.width(175.dp),
enabled = true,
enabled = isFormValid,
colors = ButtonColors(
containerColor = secondary,
contentColor = Color.White,
disabledContentColor = secondary,
disabledContentColor = Color.Gray,
disabledContainerColor = secondary,
)
)
Expand All @@ -146,7 +244,7 @@ fun PasswordForm() {
)
}
Button(
onClick = {},
onClick = onSaveClick,
modifier = Modifier.width(175.dp),
colors = ButtonColors(
containerColor = secondary,
Expand Down
14 changes: 13 additions & 1 deletion src/main/kotlin/ui/screens/PasswordFormScreen.kt
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
package ui.screens

import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import cafe.adriel.voyager.core.screen.Screen
import ui.components.forms.PasswordForm
import ui.validators.passwordFormValidator

class PasswordFormScreen : Screen {

@Composable
override fun Content() {
PasswordForm()

val formValidator = remember { passwordFormValidator() }

val isFormValid by formValidator.isValid

PasswordForm(
formValidator,
isFormValid,
onSaveClick = {}
)
}

}
63 changes: 63 additions & 0 deletions src/main/kotlin/ui/validators/PasswordFormValidator.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package ui.validators

import core.form.FormField
import core.form.FormFieldName
import core.form.validation.*

fun passwordFormValidator(): FormValidator {
return FormValidator()
.addField(
PasswordFormFieldName.USERNAME, FormField(
validator = Validator()
.addRule(notNullRule(PasswordFormFieldName.USERNAME.fieldName))
.addRule(lengthRule(PasswordFormFieldName.USERNAME.fieldName, 1))
)
)
.addField(
PasswordFormFieldName.EMAIL, FormField(
validator = Validator()
.addRule(notNullRule(PasswordFormFieldName.EMAIL.fieldName))
.addRule(lengthRule(PasswordFormFieldName.EMAIL.fieldName, 1))
.addRule(emailRule)
)
)
.addField(
PasswordFormFieldName.PASSWORD, FormField(
validator = Validator()
.addRule(notNullRule(PasswordFormFieldName.PASSWORD.fieldName))
.addRule(passwordRule)
)
)
.addField(
PasswordFormFieldName.NAME, FormField(
validator = Validator()
.addRule(notNullRule(PasswordFormFieldName.NAME.fieldName))
.addRule(lengthRule(PasswordFormFieldName.NAME.fieldName, 1))
)
)
.addField(
PasswordFormFieldName.WEBSITE_URL, FormField(
validator = Validator()
.addRule(notNullRule(PasswordFormFieldName.WEBSITE_URL.fieldName))
.addRule(lengthRule(PasswordFormFieldName.WEBSITE_URL.fieldName, 1))
.addRule(urlRule)
)
)
.addField(
PasswordFormFieldName.WEBSITE_ICON_URL, FormField(
validator = Validator()
.addRule(notNullRule(PasswordFormFieldName.WEBSITE_ICON_URL.fieldName))
.addRule(lengthRule(PasswordFormFieldName.WEBSITE_ICON_URL.fieldName, 1))
.addRule(urlRule)
)
).validateAllFields()
}

enum class PasswordFormFieldName(val fieldName: String) : FormFieldName {
USERNAME("Username"),
EMAIL("Email"),
PASSWORD("Password"),
NAME("Name"),
WEBSITE_URL("Website URL"),
WEBSITE_ICON_URL("Website Icon URL");
}

0 comments on commit 21c3b6c

Please sign in to comment.