Skip to content

Commit 4174fcc

Browse files
Merge pull request benjamin-luescher#9 from benjamin-luescher/feature/is_visible_refactoring
Ignore hidden fields for validation
2 parents d4cbef6 + d172d96 commit 4174fcc

File tree

11 files changed

+37
-35
lines changed

11 files changed

+37
-35
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ dependencyResolutionManagement {
2323
2424
2. Add the dependency in your build.gradle file.
2525
```kotlin
26-
implementation 'com.github.benjamin-luescher:compose-form:0.2.4'
26+
implementation 'com.github.benjamin-luescher:compose-form:0.2.5'
2727
```
2828

2929
## Easy example

app/src/main/java/com/edorex/mobile/composeForm/MainForm.kt

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.edorex.mobile.composeForm
22

3-
import android.util.Log
43
import androidx.compose.runtime.mutableStateOf
54
import ch.benlu.composeform.*
65
import ch.benlu.composeform.validators.*
@@ -45,6 +44,7 @@ class MainForm(resourcesProvider: ResourcesProvider): Form() {
4544
@FormField
4645
val passwordConfirm = FieldState(
4746
state = mutableStateOf<String?>(null),
47+
isVisible = { password.state.value != null && password.state.value!!.isNotEmpty() },
4848
validators = mutableListOf(
4949
IsEqualValidator({ password.state.value })
5050
)
@@ -83,15 +83,14 @@ class MainForm(resourcesProvider: ResourcesProvider): Form() {
8383
null,
8484
Country(code = "CH", name = "Switzerland"),
8585
Country(code = "DE", name = "Germany")
86-
),
87-
optionItemFormatter = {
88-
if (it != null) {
89-
"${it.name} (${it.code})"
90-
} else {
91-
"All"
92-
}
86+
)
87+
) {
88+
if (it != null) {
89+
"${it.name} (${it.code})"
90+
} else {
91+
"All"
9392
}
94-
)
93+
}
9594

9695
@FormField
9796
val startDate = FieldState(

composeform/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ publishing {
6969
release(MavenPublication) {
7070
groupId = 'com.github.benjamin-luescher'
7171
artifactId = 'compose-form'
72-
version = '0.2.4'
72+
version = '0.2.5'
7373

7474
afterEvaluate {
7575
from components.release

composeform/src/main/java/ch/benlu/composeform/Field.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,12 @@ import androidx.compose.ui.text.input.KeyboardType
88
import androidx.compose.ui.text.input.VisualTransformation
99
import java.util.*
1010

11-
abstract class Field<T> constructor(
11+
abstract class Field<T> (
1212
open val fieldState: FieldState<T?>,
1313
open val label: String,
1414
open val form: Form,
1515
open val keyboardType: KeyboardType = KeyboardType.Text,
1616
open val visualTransformation: VisualTransformation = VisualTransformation.None,
17-
open val isVisible: Boolean = true,
1817
open val isEnabled: Boolean = true,
1918
open val modifier: Modifier? = Modifier,
2019
open val imeAction: ImeAction? = ImeAction.Next,

composeform/src/main/java/ch/benlu/composeform/FieldState.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ class FieldState<T>(
88
val validators: MutableList<Validator<T>> = mutableListOf(),
99
val errorText: MutableList<String> = mutableListOf(),
1010
val isValid: MutableState<Boolean?> = mutableStateOf(false),
11+
val isVisible: () -> Boolean = { true },
1112
val hasChanges: MutableState<Boolean?> = mutableStateOf(false),
1213
var options: MutableList<T> = mutableListOf(),
1314
val optionItemFormatter: ((T?) -> String)? = null,
1415
) {
1516
fun hasError(): Boolean {
16-
return isValid.value == false && hasChanges.value == true
17+
return isVisible() && isValid.value == false && hasChanges.value == true
1718
}
1819

1920
fun selectedOption(): T? {

composeform/src/main/java/ch/benlu/composeform/Form.kt

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ abstract class Form {
88

99
abstract fun self(): Form
1010

11+
/**
12+
* Returns a list of all fields in the form.
13+
*/
1114
private fun getFormFields(): List<Pair<String, FormField?>> {
1215
return this::class.java.declaredFields.map {
1316
Pair(it.name, it.getAnnotation(FormField::class.java))
@@ -21,9 +24,10 @@ abstract class Form {
2124
f.isAccessible = true
2225

2326
try {
24-
val fieldState = (f.get(this) as FieldState<Any>)
25-
val value = fieldState.state?.value
26-
Log.d("Form", "$name:${value}")
27+
val fieldState = (f.get(this) as FieldState<*>)
28+
val value = fieldState.state.value
29+
val isVisible = fieldState.isVisible()
30+
Log.d("Form", "$name:${value} (isVisible: $isVisible)")
2731
} catch (e: Exception) {
2832
Log.e("Form", e.toString())
2933
}
@@ -32,8 +36,10 @@ abstract class Form {
3236

3337
/**
3438
* Triggers validation for all fields in the form.
39+
* @param markAsChanged If true, all fields will be marked as changed.
40+
* @param ignoreInvisible If true, invisible fields will be ignored during validation.
3541
*/
36-
fun validate(ignoreUntouched: Boolean = false) {
42+
fun validate(markAsChanged: Boolean = false, ignoreInvisible: Boolean = true) {
3743
var isValid = true
3844
val formFields = getFormFields()
3945

@@ -42,8 +48,15 @@ abstract class Form {
4248
val f = this::class.java.getDeclaredField(name)
4349
f.isAccessible = true
4450

51+
4552
try {
4653
val fieldState = (f.get(this) as FieldState<Any>)
54+
55+
// if we should ignore invisible fields, skip validation
56+
if (ignoreInvisible && !fieldState.isVisible()) {
57+
return@forEach
58+
}
59+
4760
val value = fieldState.state?.value
4861
val validators = fieldState.validators
4962

@@ -58,14 +71,14 @@ abstract class Form {
5871
isValid = false
5972
isFieldValid = false
6073
// add error text to fieldState
61-
fieldState.errorText.add(it.errorText!!)
74+
fieldState.errorText.add(it.errorText)
6275
}
6376
}
6477
Log.d("Form", "Field Validation ($name): $isFieldValid")
6578
fieldState.isValid.value = isFieldValid
6679

6780
// if we should ignore untouched fields, every field should be marked as changed
68-
if (ignoreUntouched) {
81+
if (markAsChanged) {
6982
fieldState.hasChanges.value = true
7083
}
7184

composeform/src/main/java/ch/benlu/composeform/fields/CheckboxField.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ class CheckboxField(
1313
form: Form,
1414
modifier: Modifier? = Modifier,
1515
fieldState: FieldState<Boolean?>,
16-
isVisible: Boolean = true,
1716
isEnabled: Boolean = true,
1817
imeAction: ImeAction = ImeAction.Next,
1918
formatter: ((raw: Boolean?) -> String)? = null,
@@ -22,7 +21,6 @@ class CheckboxField(
2221
label = label,
2322
form = form,
2423
fieldState = fieldState,
25-
isVisible = isVisible,
2624
isEnabled = isEnabled,
2725
modifier = modifier,
2826
imeAction = imeAction,
@@ -36,7 +34,7 @@ class CheckboxField(
3634
@Composable
3735
override fun Field() {
3836
this.updateComposableValue()
39-
if (!isVisible) {
37+
if (!fieldState.isVisible()) {
4038
return
4139
}
4240
CheckboxComponent(

composeform/src/main/java/ch/benlu/composeform/fields/DateField.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ class DateField(
2121
form: Form,
2222
modifier: Modifier? = Modifier,
2323
fieldState: FieldState<Date?>,
24-
isVisible: Boolean = true,
2524
isEnabled: Boolean = true,
2625
imeAction: ImeAction = ImeAction.Next,
2726
formatter: ((raw: Date?) -> String)? = null,
@@ -31,7 +30,6 @@ class DateField(
3130
label = label,
3231
form = form,
3332
fieldState = fieldState,
34-
isVisible = isVisible,
3533
isEnabled = isEnabled,
3634
modifier = modifier,
3735
imeAction = imeAction,
@@ -45,7 +43,7 @@ class DateField(
4543
@Composable
4644
override fun Field() {
4745
this.updateComposableValue()
48-
if (!isVisible) {
46+
if (!fieldState.isVisible()) {
4947
return
5048
}
5149

composeform/src/main/java/ch/benlu/composeform/fields/PasswordField.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,13 @@ class PasswordField(
2525
form: Form,
2626
modifier: Modifier? = Modifier,
2727
fieldState: FieldState<String?>,
28-
isVisible: Boolean = true,
2928
isEnabled: Boolean = true,
3029
imeAction: ImeAction = ImeAction.Next,
3130
changed: ((v: String?) -> Unit)? = null
3231
) : Field<String>(
3332
label = label,
3433
form = form,
3534
fieldState = fieldState,
36-
isVisible = isVisible,
3735
isEnabled = isEnabled,
3836
modifier = modifier,
3937
imeAction = imeAction,
@@ -48,7 +46,7 @@ class PasswordField(
4846
@Composable
4947
override fun Field() {
5048
this.updateComposableValue()
51-
if (!isVisible) {
49+
if (!fieldState.isVisible()) {
5250
return
5351
}
5452

composeform/src/main/java/ch/benlu/composeform/fields/PickerField.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ class PickerField<T: PickerValue>(
2525
form: Form,
2626
modifier: Modifier? = Modifier,
2727
fieldState: FieldState<T?>,
28-
isVisible: Boolean = true,
2928
isEnabled: Boolean = true,
3029
imeAction: ImeAction = ImeAction.Next,
3130
formatter: ((raw: T?) -> String)? = null,
@@ -35,7 +34,6 @@ class PickerField<T: PickerValue>(
3534
label = label,
3635
form = form,
3736
fieldState = fieldState,
38-
isVisible = isVisible,
3937
isEnabled = isEnabled,
4038
modifier = modifier,
4139
imeAction = imeAction,
@@ -46,7 +44,7 @@ class PickerField<T: PickerValue>(
4644
@Composable
4745
override fun Field() {
4846
this.updateComposableValue()
49-
if (!isVisible) {
47+
if (!fieldState.isVisible()) {
5048
return
5149
}
5250

0 commit comments

Comments
 (0)