aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Jaros <rjaros@finn.pl>2020-05-10 00:40:58 +0200
committerRobert Jaros <rjaros@finn.pl>2020-05-10 00:40:58 +0200
commite1b6840c9beb82d8761aa0e9376b356d5f12fa79 (patch)
tree2ed780c2758fd2e178a67fde003d5df2b4cd2302
parent0f8aff227926c298107c149072f8dcb0bb5a1747 (diff)
downloadkvision-e1b6840c9beb82d8761aa0e9376b356d5f12fa79.tar.gz
kvision-e1b6840c9beb82d8761aa0e9376b356d5f12fa79.tar.bz2
kvision-e1b6840c9beb82d8761aa0e9376b356d5f12fa79.zip
Add simplified version of FormPanel DSL builder function to easily create HTML form elements with attributes.
-rw-r--r--kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt2
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/form/Form.kt67
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt30
3 files changed, 67 insertions, 32 deletions
diff --git a/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt b/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt
index bdae5091..e1678e90 100644
--- a/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt
+++ b/kvision-modules/kvision-bootstrap-upload/src/main/kotlin/pl/treksoft/kvision/utils/Utils.kt
@@ -61,7 +61,7 @@ suspend fun <K : Any> Form<K>.getDataWithFileContent(): K {
value.getValue()
}
})
- return this.modelFactory(map.withDefault { null })
+ return this.modelFactory?.invoke(map.withDefault { null }) ?: throw IllegalStateException("Serializer not defined")
}
/**
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<in F : FormControl>(
* @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<K : Any>(
private val panel: FormPanel<K>? = null,
- private val serializer: KSerializer<K>,
+ private val serializer: KSerializer<K>? = null,
private val customSerializers: Map<KClass<*>, KSerializer<*>>? = null
) {
- val modelFactory: (Map<String, Any?>) -> K
+ val modelFactory: ((Map<String, Any?>) -> K)?
val fields: MutableMap<String, FormControl> = mutableMapOf()
internal val fieldsParams: MutableMap<String, Any> = mutableMapOf()
internal var validatorMessage: ((Form<K>) -> String?)? = null
internal var validator: ((Form<K>) -> 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<KFile>)?.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<KFile>)?.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<K : Any>(
*/
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<K : Any>(
* @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<K : Any>(
method: FormMethod? = null, action: String? = null, enctype: FormEnctype? = null,
private val type: FormType? = null, condensed: Boolean = false,
horizRatio: FormHorizontalRatio = FormHorizontalRatio.RATIO_2, classes: Set<String> = setOf(),
- serializer: KSerializer<K>, customSerializers: Map<KClass<*>, KSerializer<*>>? = null
+ serializer: KSerializer<K>? = null, customSerializers: Map<KClass<*>, KSerializer<*>>? = null
) : SimplePanel(classes) {
/**
@@ -516,3 +517,30 @@ inline fun <reified K : Any> 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<String>? = null, className: String? = null,
+ init: (FormPanel<Any>.() -> Unit)? = null
+): FormPanel<Any> {
+ val formPanel =
+ FormPanel<Any>(
+ method,
+ action,
+ enctype,
+ type,
+ condensed,
+ horizRatio,
+ classes ?: className.set
+ )
+ init?.invoke(formPanel)
+ this.add(formPanel)
+ return formPanel
+}