aboutsummaryrefslogtreecommitdiff
path: root/kvision-modules/kvision-bootstrap-typeahead-remote
diff options
context:
space:
mode:
authorRobert Jaros <rjaros@finn.pl>2020-02-09 00:00:07 +0100
committerRobert Jaros <rjaros@finn.pl>2020-02-09 00:00:07 +0100
commit62d0118f8d35c202babfff661e1bbff4d4465498 (patch)
treedd41ecdd92001707bada31cb2885200a0c75b0e0 /kvision-modules/kvision-bootstrap-typeahead-remote
parent84d80ed8c26f30d380c7ab55f7eb5a30965daa3a (diff)
downloadkvision-62d0118f8d35c202babfff661e1bbff4d4465498.tar.gz
kvision-62d0118f8d35c202babfff661e1bbff4d4465498.tar.bz2
kvision-62d0118f8d35c202babfff661e1bbff4d4465498.zip
New TypeaheadRemote component module.
Diffstat (limited to 'kvision-modules/kvision-bootstrap-typeahead-remote')
-rw-r--r--kvision-modules/kvision-bootstrap-typeahead-remote/build.gradle6
-rw-r--r--kvision-modules/kvision-bootstrap-typeahead-remote/package.json.d/project.info3
-rw-r--r--kvision-modules/kvision-bootstrap-typeahead-remote/src/main/kotlin/pl/treksoft/kvision/form/text/TypeaheadRemote.kt167
-rw-r--r--kvision-modules/kvision-bootstrap-typeahead-remote/src/main/kotlin/pl/treksoft/kvision/form/text/TypeaheadRemoteInput.kt100
-rw-r--r--kvision-modules/kvision-bootstrap-typeahead-remote/webpack.config.d/css.js2
5 files changed, 278 insertions, 0 deletions
diff --git a/kvision-modules/kvision-bootstrap-typeahead-remote/build.gradle b/kvision-modules/kvision-bootstrap-typeahead-remote/build.gradle
new file mode 100644
index 00000000..cab403d5
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap-typeahead-remote/build.gradle
@@ -0,0 +1,6 @@
+apply from: "../shared.gradle"
+
+dependencies {
+ compile project(":kvision-modules:kvision-bootstrap-typeahead")
+ compile project(":kvision-modules:kvision-remote")
+}
diff --git a/kvision-modules/kvision-bootstrap-typeahead-remote/package.json.d/project.info b/kvision-modules/kvision-bootstrap-typeahead-remote/package.json.d/project.info
new file mode 100644
index 00000000..15dc8333
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap-typeahead-remote/package.json.d/project.info
@@ -0,0 +1,3 @@
+{
+ "description": "KVision Typeahead remote addon module"
+}
diff --git a/kvision-modules/kvision-bootstrap-typeahead-remote/src/main/kotlin/pl/treksoft/kvision/form/text/TypeaheadRemote.kt b/kvision-modules/kvision-bootstrap-typeahead-remote/src/main/kotlin/pl/treksoft/kvision/form/text/TypeaheadRemote.kt
new file mode 100644
index 00000000..961b5dd0
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap-typeahead-remote/src/main/kotlin/pl/treksoft/kvision/form/text/TypeaheadRemote.kt
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2017-present Robert Jaros
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package pl.treksoft.kvision.form.text
+
+import pl.treksoft.kvision.core.Container
+import pl.treksoft.kvision.remote.KVServiceManager
+
+/**
+ * Form field typeahead component connected to the multiplatform service.
+ *
+ * @constructor
+ * @param serviceManager multiplatform service manager
+ * @param function multiplatform service method returning the list of options
+ * @param stateFunction a function to generate the state object passed with the remote request
+ * @param items the max number of items to display in the dropdown
+ * @param minLength the minimum character length needed before triggering dropdown
+ * @param delay a delay between lookups
+ * @param type text input type (default "text")
+ * @param value text input value
+ * @param name the name attribute of the generated HTML input element
+ * @param label label text bound to the input element
+ * @param rich determines if [label] can contain HTML code
+ */
+open class TypeaheadRemote<T : Any>(
+ serviceManager: KVServiceManager<T>,
+ function: suspend T.(String?, String?) -> List<String>,
+ private val stateFunction: (() -> String)? = null,
+ items: Int? = 8, minLength: Int = 1, delay: Int = 0,
+ type: TextInputType = TextInputType.TEXT, value: String? = null, name: String? = null,
+ label: String? = null, rich: Boolean = false
+) : AbstractText(label, rich) {
+
+ /**
+ * The max number of items to display in the dropdown
+ */
+ var items
+ get() = input.items
+ set(value) {
+ input.items = value
+ }
+
+ /**
+ * The minimum character length needed before triggering dropdown
+ */
+ var minLength
+ get() = input.minLength
+ set(value) {
+ input.minLength = value
+ }
+
+ /**
+ * Determines if hints should be shown as soon as the input gets focus.
+ */
+ var showHintOnFocus
+ get() = input.showHintOnFocus
+ set(value) {
+ input.showHintOnFocus = value
+ }
+
+ /**
+ * Determines if the first suggestion is selected automatically.
+ */
+ var autoSelect
+ get() = input.autoSelect
+ set(value) {
+ input.autoSelect = value
+ }
+
+ /**
+ * A delay between lookups.
+ */
+ var delay
+ get() = input.ajaxOptions
+ set(value) {
+ input.ajaxOptions = value
+ }
+
+ /**
+ * Determines if the menu is the same size as the input it is attached to.
+ */
+ var fitToElement
+ get() = input.fitToElement
+ set(value) {
+ input.fitToElement = value
+ }
+
+ /**
+ * Text input type.
+ */
+ var type
+ get() = input.type
+ set(value) {
+ input.type = value
+ }
+ /**
+ * Determines if autocomplete is enabled for the input element.
+ */
+ var autocomplete
+ get() = input.autocomplete
+ set(value) {
+ input.autocomplete = value
+ }
+
+ final override val input: TypeaheadRemoteInput<T> =
+ TypeaheadRemoteInput(serviceManager, function, stateFunction, items, minLength, delay, type, value).apply {
+ this.id = idc
+ this.name = name
+ }
+
+ init {
+ @Suppress("LeakingThis")
+ input.eventTarget = this
+ this.addInternal(input)
+ this.addInternal(invalidFeedback)
+ }
+}
+
+/**
+ * DSL builder extension function.
+ *
+ * It takes the same parameters as the constructor of the built component.
+ */
+fun <T : Any> Container.typeaheadRemote(
+ serviceManager: KVServiceManager<T>,
+ function: suspend T.(String?, String?) -> List<String>,
+ stateFunction: (() -> String)? = null,
+ items: Int? = 8, minLength: Int = 1, delay: Int = 0,
+ type: TextInputType = TextInputType.TEXT, value: String? = null, name: String? = null,
+ label: String? = null, rich: Boolean = false, init: (TypeaheadRemote<T>.() -> Unit)? = null
+): TypeaheadRemote<T> {
+ val typeaheadRemote = TypeaheadRemote(
+ serviceManager,
+ function,
+ stateFunction,
+ items,
+ minLength,
+ delay,
+ type,
+ value,
+ name,
+ label,
+ rich
+ ).apply {
+ init?.invoke(this)
+ }
+ this.add(typeaheadRemote)
+ return typeaheadRemote
+}
diff --git a/kvision-modules/kvision-bootstrap-typeahead-remote/src/main/kotlin/pl/treksoft/kvision/form/text/TypeaheadRemoteInput.kt b/kvision-modules/kvision-bootstrap-typeahead-remote/src/main/kotlin/pl/treksoft/kvision/form/text/TypeaheadRemoteInput.kt
new file mode 100644
index 00000000..e56468d1
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap-typeahead-remote/src/main/kotlin/pl/treksoft/kvision/form/text/TypeaheadRemoteInput.kt
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2017-present Robert Jaros
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package pl.treksoft.kvision.form.text
+
+import kotlinx.serialization.ImplicitReflectionSerializer
+import kotlinx.serialization.list
+import kotlinx.serialization.serializer
+import kotlinx.serialization.stringify
+import org.w3c.dom.get
+import pl.treksoft.kvision.core.Container
+import pl.treksoft.kvision.remote.JsonRpcRequest
+import pl.treksoft.kvision.remote.KVServiceManager
+import pl.treksoft.kvision.utils.JSON
+import kotlin.browser.window
+
+/**
+ * The Typeahead control connected to the multiplatform service.
+ *
+ * @constructor
+ * @param serviceManager multiplatform service manager
+ * @param function multiplatform service method returning the list of options
+ * @param stateFunction a function to generate the state object passed with the remote request
+ * @param items the max number of items to display in the dropdown
+ * @param minLength the minimum character length needed before triggering dropdown
+ * @param delay a delay between lookups
+ * @param type text input type (default "text")
+ * @param value text input value
+ * @param classes a set of CSS class names
+ */
+@UseExperimental(ImplicitReflectionSerializer::class)
+open class TypeaheadRemoteInput<T : Any>(
+ serviceManager: KVServiceManager<T>,
+ function: suspend T.(String?, String?) -> List<String>,
+ private val stateFunction: (() -> String)? = null,
+ items: Int? = 8, minLength: Int = 1, delay: Int = 0,
+ type: TextInputType = TextInputType.TEXT, value: String? = null, classes: Set<String> = setOf()
+) : TypeaheadInput(null, null, items, minLength, delay, type, value, classes) {
+
+ private val kvUrlPrefix = window["kv_remote_url_prefix"]
+ private val urlPrefix: String = if (kvUrlPrefix != undefined) kvUrlPrefix else ""
+
+ init {
+ val (url, method) =
+ serviceManager.getCalls()[function.toString().replace("\\s".toRegex(), "")]
+ ?: throw IllegalStateException("Function not specified!")
+ this.ajaxOptions = TaAjaxOptions(
+ urlPrefix + url,
+ preprocessQuery = { query ->
+ val state = stateFunction?.invoke()
+ JSON.plain.stringify(JsonRpcRequest(0, url, listOf(query, state)))
+ },
+ preprocessData = {
+ JSON.plain.parse(String.serializer().list, it.result as String).toTypedArray()
+ },
+ httpType = HttpType.valueOf(method.name)
+ )
+ }
+}
+
+/**
+ * DSL builder extension function.
+ *
+ * It takes the same parameters as the constructor of the built component.
+ */
+fun <T : Any> Container.typeaheadRemoteInput(
+ serviceManager: KVServiceManager<T>,
+ function: suspend T.(String?, String?) -> List<String>,
+ stateFunction: (() -> String)? = null,
+ items: Int? = 8, minLength: Int = 1, delay: Int = 0,
+ type: TextInputType = TextInputType.TEXT, value: String? = null, classes: Set<String> = setOf(),
+ init: (TypeaheadRemoteInput<T>.() -> Unit)? = null
+): TypeaheadRemoteInput<T> {
+ val typeaheadRemoteInput =
+ TypeaheadRemoteInput(
+ serviceManager, function, stateFunction, items, minLength, delay, type, value, classes
+ ).apply {
+ init?.invoke(this)
+ }
+ this.add(typeaheadRemoteInput)
+ return typeaheadRemoteInput
+}
diff --git a/kvision-modules/kvision-bootstrap-typeahead-remote/webpack.config.d/css.js b/kvision-modules/kvision-bootstrap-typeahead-remote/webpack.config.d/css.js
new file mode 100644
index 00000000..5d710d35
--- /dev/null
+++ b/kvision-modules/kvision-bootstrap-typeahead-remote/webpack.config.d/css.js
@@ -0,0 +1,2 @@
+config.module.rules.push({ test: /\.css$/, loader: "style-loader!css-loader" });
+