Corey
12/01/2025, 1:28 AMinvalidMessage on each control for styling). Since the form's field map is private, we currently have to store the controls ourselves.
Just wondering if this is intentional design. Thanks! 🙂Robert Jaros
12/01/2025, 5:44 AMCorey
12/01/2025, 5:53 AMRobert Jaros
12/01/2025, 6:18 AMcustomValdity property is designed to be set internally when form validate() method is called. Can you give me some example code?Corey
12/01/2025, 6:52 AMimport androidx.compose.runtime.Composable
import dev.kilua.core.IComponent
import dev.kilua.form.Form
import dev.kilua.form.IInput
import dev.kilua.html.div
import dev.kilua.html.helpers.TagAttrsFun
import nz.coreyh.playground.kilua.components.csErrorMessage
import nz.coreyh.playground.kilua.components.csLabel
import kotlin.reflect.KProperty1
@Composable
fun <K : Any, C : IInput<*>> IComponent.csField(
key: KProperty1<K, *>,
label: String,
validator: (C) -> List<Pair<Boolean, String?>> = { emptyList() },
className: String? = null,
controlFactory: @Composable (String) -> C
) {
val id = key.name
val classNames = mergeClasses("flex flex-col gap-2", className)
val form = Form.current
val formValidation = form.validationStateFlow.value
val fieldValidation = formValidation.fieldsValidations[id]
val invalidMessage = fieldValidation?.invalidMessage
val invalid = !invalidMessage.isNullOrEmpty()
div(classNames) {
// label
csLabel(htmlFor = id, label = label) {
if (invalid) markInvalid()
}
// render and bind control to form
val control = controlFactory(id)
control.bindWithValidationMessage(key = id,) {
val checks = validator(control)
checks.firstOrNull { !it.first } ?: (true to null)
}
if (invalid) control.markInvalid()
// error message
invalidMessage?.let { csErrorMessage(it) }
}
}
@Composable
fun TagAttrsFun.markInvalid() {
attribute("data-invalid", "true")
}Corey
12/01/2025, 6:53 AMForm#validate() which sets invalidMessage in the forms validation stateCorey
12/01/2025, 7:12 AMRobert Jaros
12/01/2025, 7:22 AMcustomValidity property only works with basic browser validation api and is not very useful).Robert Jaros
12/01/2025, 7:26 AMerror parameter to your csTextField and csFields composables.Robert Jaros
12/01/2025, 7:26 AMval invalid = error != null || !invalidMessage.isNullOrEmpty()Robert Jaros
12/01/2025, 7:27 AMerror state variable will recompose the fields and should make them look invalidCorey
12/01/2025, 7:34 AMvar error by remember { mutableStateOf<String?>(null) }
form<LoginRequest> {
csTextField(
(...)
invalid = !error.isNullOrEmpty(),
)
csTextField(
(...)
invalid = !error.isNullOrEmpty(),
)
but just wanted to see if there was a way to avoid this. thank you, I appreciate the help!