Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c7f84d16fd | |||
| 0fee248dff |
7 changed files with 56 additions and 5 deletions
|
|
@ -6,6 +6,6 @@ plugins {
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
version = "0.3.3"
|
version = "0.4.0"
|
||||||
group = "de.thetadev.formconductor"
|
group = "de.thetadev.formconductor"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import de.thetadev.formconductor.FieldResult
|
||||||
*
|
*
|
||||||
* @param V type of field value
|
* @param V type of field value
|
||||||
*/
|
*/
|
||||||
interface FormFieldScope<V : Any?> {
|
interface FormFieldScope<V> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Observable State instance of field value
|
* Observable State instance of field value
|
||||||
|
|
@ -30,7 +30,19 @@ interface FormFieldScope<V : Any?> {
|
||||||
*
|
*
|
||||||
* You're encouraged to set the field value only using this function
|
* You're encouraged to set the field value only using this function
|
||||||
*
|
*
|
||||||
* @param input input value
|
* @param input Field value
|
||||||
|
* @param validate Validate the input on update
|
||||||
*/
|
*/
|
||||||
fun setField(input: V?, validate: Boolean = true)
|
fun setField(input: V?, validate: Boolean = true)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A setter function for field value or error.
|
||||||
|
*
|
||||||
|
* Set the field value if the input is successful, fail validation if the input is an error.
|
||||||
|
*
|
||||||
|
* To be used for custom fields with built-in validation.
|
||||||
|
*
|
||||||
|
* @param input Field value or error
|
||||||
|
*/
|
||||||
|
fun setFieldResult(input: Result<V?>)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,4 +21,8 @@ internal class FormFieldScopeImpl<V>(
|
||||||
override fun setField(input: V?, validate: Boolean) {
|
override fun setField(input: V?, validate: Boolean) {
|
||||||
formField.setField(input, validate)
|
formField.setField(input, validate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun setFieldResult(input: Result<V?>) {
|
||||||
|
formField.setFieldResult(input)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,22 @@ interface FormField<V> {
|
||||||
*
|
*
|
||||||
* The function validates the field if the input is not **empty** or the field isn't **optional**
|
* The function validates the field if the input is not **empty** or the field isn't **optional**
|
||||||
*
|
*
|
||||||
* @param input
|
* @param input Field value
|
||||||
|
* @param validate Validate the input on update
|
||||||
*/
|
*/
|
||||||
fun setField(input: V?, validate: Boolean = true)
|
fun setField(input: V?, validate: Boolean = true)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A setter function for field value or error.
|
||||||
|
*
|
||||||
|
* Set the field value if the input is successful, fail validation if the input is an error.
|
||||||
|
*
|
||||||
|
* To be used for custom fields with built-in validation.
|
||||||
|
*
|
||||||
|
* @param input Field value or error
|
||||||
|
*/
|
||||||
|
fun setFieldResult(input: Result<V?>)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate the field without updating its value
|
* Validate the field without updating its value
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package de.thetadev.formconductor
|
package de.thetadev.formconductor
|
||||||
|
|
||||||
import de.thetadev.formconductor.validation.optionalFlags.OptionalFlag
|
import de.thetadev.formconductor.validation.optionalFlags.OptionalFlag
|
||||||
|
import de.thetadev.formconductor.validation.rules.ExternalValidationErrorRule
|
||||||
import de.thetadev.formconductor.validation.rules.OptionalRule
|
import de.thetadev.formconductor.validation.rules.OptionalRule
|
||||||
import de.thetadev.formconductor.validation.validators.FieldValidator
|
import de.thetadev.formconductor.validation.validators.FieldValidator
|
||||||
import de.thetadev.formconductor.validation.validators.StatelessFieldValidator
|
import de.thetadev.formconductor.validation.validators.StatelessFieldValidator
|
||||||
|
|
@ -48,6 +49,7 @@ internal class FormFieldImpl<T : Any, V>(
|
||||||
valueStream.value = input ?: defaultValue
|
valueStream.value = input ?: defaultValue
|
||||||
|
|
||||||
if (validate) {
|
if (validate) {
|
||||||
|
if (hasExternalValidationError()) resultStream.value = FieldResult.NoInput
|
||||||
validateField()
|
validateField()
|
||||||
} else if (input == null || input == "") {
|
} else if (input == null || input == "") {
|
||||||
resultStream.value = FieldResult.NoInput
|
resultStream.value = FieldResult.NoInput
|
||||||
|
|
@ -56,10 +58,23 @@ internal class FormFieldImpl<T : Any, V>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun setFieldResult(input: Result<V?>) {
|
||||||
|
input.fold(
|
||||||
|
onSuccess = { setField(it) },
|
||||||
|
onFailure = {
|
||||||
|
resultStream.value =
|
||||||
|
FieldResult.Error("Validation error", ExternalValidationErrorRule)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates the current input value and updates the field's result
|
* Validates the current input value and updates the field's result
|
||||||
*/
|
*/
|
||||||
override fun validateField(soft: Boolean) {
|
override fun validateField(soft: Boolean) {
|
||||||
|
if (hasExternalValidationError()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
val input = valueStream.value
|
val input = valueStream.value
|
||||||
// Null and empty strings are skipped for validation
|
// Null and empty strings are skipped for validation
|
||||||
if (input != null && input != "") {
|
if (input != null && input != "") {
|
||||||
|
|
@ -110,4 +125,9 @@ internal class FormFieldImpl<T : Any, V>(
|
||||||
optionalStateEvaluators.all(OptionalFlag::evaluate)
|
optionalStateEvaluators.all(OptionalFlag::evaluate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun hasExternalValidationError(): Boolean {
|
||||||
|
val result = resultStream.value
|
||||||
|
return result is FieldResult.Error && result.failedRule is ExternalValidationErrorRule
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
package de.thetadev.formconductor.validation.rules
|
||||||
|
|
||||||
|
object ExternalValidationErrorRule : ValidationRule
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
[versions]
|
[versions]
|
||||||
agp = "9.4.0"
|
agp = "9.4.1"
|
||||||
kotlinReflect = "1.7.10"
|
kotlinReflect = "1.7.10"
|
||||||
kotlin = "2.4.10"
|
kotlin = "2.4.10"
|
||||||
kotlinxCoroutinesCore = "1.11.0"
|
kotlinxCoroutinesCore = "1.11.0"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue