From e1b6840c9beb82d8761aa0e9376b356d5f12fa79 Mon Sep 17 00:00:00 2001 From: Robert Jaros Date: Sun, 10 May 2020 00:40:58 +0200 Subject: Add simplified version of FormPanel DSL builder function to easily create HTML form elements with attributes. --- src/main/kotlin/pl/treksoft/kvision/form/Form.kt | 67 ++++++++++++---------- .../kotlin/pl/treksoft/kvision/form/FormPanel.kt | 30 +++++++++- 2 files changed, 66 insertions(+), 31 deletions(-) (limited to 'src/main/kotlin') diff --git a/src/main/kotlin/pl/treksoft/kvision/form/Form.kt b/src/main/kotlin/pl/treksoft/kvision/form/Form.kt index 783653ce..eb0e5aee 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/Form.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/Form.kt @@ -55,42 +55,45 @@ internal data class FieldParams( * @param K model class type * @param panel optional instance of [FormPanel] * @param serializer a serializer for model type + * @param customSerializers a map of custom serializers for model type */ @Suppress("TooManyFunctions") class Form( private val panel: FormPanel? = null, - private val serializer: KSerializer, + private val serializer: KSerializer? = null, private val customSerializers: Map, KSerializer<*>>? = null ) { - val modelFactory: (Map) -> K + val modelFactory: ((Map) -> K)? val fields: MutableMap = mutableMapOf() internal val fieldsParams: MutableMap = mutableMapOf() internal var validatorMessage: ((Form) -> String?)? = null internal var validator: ((Form) -> Boolean?)? = null init { - modelFactory = { - val json = js("{}") - it.forEach { (key, value) -> - val v = when (value) { - is Date -> { - value.toStringF() - } - is List<*> -> { - @Suppress("UNCHECKED_CAST") - ((value as? List)?.toObj(KFile.serializer().list)) + modelFactory = serializer?.let { + { + val json = js("{}") + it.forEach { (key, value) -> + val v = when (value) { + is Date -> { + value.toStringF() + } + is List<*> -> { + @Suppress("UNCHECKED_CAST") + ((value as? List)?.toObj(KFile.serializer().list)) + } + else -> value } - else -> value + json[key] = v } - json[key] = v - } - val serializersModule = if (customSerializers == null) { - serializersModuleOf(Date::class, DateSerializer) - } else { - serializersModuleOf(customSerializers + (Date::class to DateSerializer)) + val serializersModule = if (customSerializers == null) { + serializersModuleOf(Date::class, DateSerializer) + } else { + serializersModuleOf(customSerializers + (Date::class to DateSerializer)) + } + DynamicObjectParser(serializersModule).parse(json, serializer) } - DynamicObjectParser(serializersModule).parse(json, serializer) } } @@ -274,7 +277,7 @@ class Form( */ fun getData(): K { val map = fields.entries.associateBy({ it.key }, { it.value.getValue() }) - return modelFactory(map.withDefault { null }) + return modelFactory?.invoke(map.withDefault { null }) ?: throw IllegalStateException("Serializer not defined") } /** @@ -282,17 +285,21 @@ class Form( * @return data model as JSON */ fun getDataJson(): Json { - val serializersModule = if (customSerializers == null) { - serializersModuleOf(Date::class, DateSerializer) + return if (serializer != null) { + val serializersModule = if (customSerializers == null) { + serializersModuleOf(Date::class, DateSerializer) + } else { + serializersModuleOf(customSerializers + (Date::class to DateSerializer)) + } + NativeJSON.parse( + kotlinx.serialization.json.Json(context = serializersModule).stringify( + serializer, + getData() + ) + ) } else { - serializersModuleOf(customSerializers + (Date::class to DateSerializer)) + NativeJSON.parse("{}") } - return NativeJSON.parse( - kotlinx.serialization.json.Json(context = serializersModule).stringify( - serializer, - getData() - ) - ) } /** diff --git a/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt b/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt index 7353179a..35d64751 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt @@ -102,13 +102,14 @@ enum class FormTarget(internal val target: String) { * @param horizRatio horizontal form layout ratio * @param classes set of CSS class names * @param serializer a serializer for model type + * @param customSerializers a map of custom serializers for model type */ @Suppress("TooManyFunctions") open class FormPanel( method: FormMethod? = null, action: String? = null, enctype: FormEnctype? = null, private val type: FormType? = null, condensed: Boolean = false, horizRatio: FormHorizontalRatio = FormHorizontalRatio.RATIO_2, classes: Set = setOf(), - serializer: KSerializer, customSerializers: Map, KSerializer<*>>? = null + serializer: KSerializer? = null, customSerializers: Map, KSerializer<*>>? = null ) : SimplePanel(classes) { /** @@ -516,3 +517,30 @@ inline fun Container.formPanel( this.add(formPanel) return formPanel } + +/** + * DSL builder extension function. + * + * Simplified version of formPanel container without data model support. + */ +fun Container.form( + method: FormMethod? = null, action: String? = null, enctype: FormEnctype? = null, + type: FormType? = null, condensed: Boolean = false, + horizRatio: FormHorizontalRatio = FormHorizontalRatio.RATIO_2, + classes: Set? = null, className: String? = null, + init: (FormPanel.() -> Unit)? = null +): FormPanel { + val formPanel = + FormPanel( + method, + action, + enctype, + type, + condensed, + horizRatio, + classes ?: className.set + ) + init?.invoke(formPanel) + this.add(formPanel) + return formPanel +} -- cgit