diff options
Diffstat (limited to 'src')
12 files changed, 173 insertions, 29 deletions
diff --git a/src/main/kotlin/pl/treksoft/kvision/Showcase.kt b/src/main/kotlin/pl/treksoft/kvision/Showcase.kt index a0ea6881..41ceacd9 100644 --- a/src/main/kotlin/pl/treksoft/kvision/Showcase.kt +++ b/src/main/kotlin/pl/treksoft/kvision/Showcase.kt @@ -110,10 +110,50 @@ class Showcase : ApplicationBase() { val select5 = Select(listOf("a" to "Pierwsza", "b" to "Druga"), "a", label = "Lista wyboru") root.add(select5) - val select6 = Select(label = "Lista wyboru 2") + val text = Text(label = "To jest pole").apply { + placeholder = "Pole formularza" + maxlength = 5 + } + + val select6 = Select(label = "Lista wyboru 2", value = "b") select6.add(SelectOption("a", "Opcja 1")) select6.add(SelectOption("b", "Opcja 2")) select6.add(SelectOption("c", "Opcja 3")) + select6.setEventListener<Select> { + showBsSelect = { e -> + println("show") + } + shownBsSelect = { e -> + println("shown") + } + hideBsSelect = { e -> + println("hide") + e.detail.preventDefault() + } + hiddenBsSelect = { e -> + println("hidden") + } + renderedBsSelect= { e -> + println("rendered") + } + refreshedBsSelect = { e -> + println("refreshed") + } + loadedBsSelect= { e -> + println("loaded") + } + changedBsSelect = { e -> + println(e.detail.clickedIndex) + if (e.detail.clickedIndex == 0) { + self.options = listOf("x" to "x", "y" to "y", "z" to "z") + self.value = "y" + text.value = "ole" + textField.value = "ole2" + } else { + self.add(SelectOption("x", "XXX")) + } + } + } root.add(select6) val container = SimplePanel(setOf("abc", "def")) @@ -148,15 +188,14 @@ class Showcase : ApplicationBase() { textField2.size = INPUTSIZE.LARGE root.add(textField2) -/* val checkbox = CheckBox(true, label = "Kliknij aby <b>przetestować</b>", rich = true, circled = true, - style = CHECKBOXSTYLE.DANGER) + val checkbox = CheckBox(true, label = "Kliknij aby <b>przetestować</b>", rich = true) root.add(checkbox) checkbox.setEventListener<CheckBox> { click = { e -> println("click" + self.value) } change = { e -> println("change" + self.value) } - }*/ + } /* val radio = Radio(true, name = "radios", label = "Opcja 1", inline = true, style = RADIOSTYLE.DANGER, extraValue = "o1") @@ -173,11 +212,6 @@ class Showcase : ApplicationBase() { } change = { e -> println("rchange" + self.value) } }*/ - - val text = Text(label = "To jest pole").apply { - placeholder = "Pole formularza" - maxlength = 5 - } root.add(text) val textareainput = TextAreaInput(cols = 5, rows = 2, value = "To jest tekst\nTo jest <b>te</b></textarea>kst2").apply { @@ -223,6 +257,7 @@ class Showcase : ApplicationBase() { click = { console.log("x") dd2.toggle() + checkbox.value = true } } root.add(ddbutton) diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt index 123ffc4c..46aa2a90 100644 --- a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt +++ b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt @@ -48,6 +48,7 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent() { field = value refresh() } + internal var eventTarget: Widget? = null private var vnode: VNode? = null @@ -144,7 +145,7 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent() { return if (internalListeners.size > 0 || listeners.size > 0) { val internalHandlers = on(this) internalListeners.forEach { l -> (internalHandlers::apply)(l) } - val handlers = on(this) + val handlers = on(eventTarget ?: this) listeners.forEach { l -> (handlers::apply)(l) } if (internalHandlers.click != null) { if (handlers.click == null) { diff --git a/src/main/kotlin/pl/treksoft/kvision/form/AbstractTextInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/AbstractTextInput.kt index 84ad5661..8f0a09e0 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/AbstractTextInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/AbstractTextInput.kt @@ -4,21 +4,27 @@ import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.snabbdom.StringBoolPair import pl.treksoft.kvision.snabbdom.StringPair -abstract class AbstractTextInput(override var value: String? = null, +abstract class AbstractTextInput(value: String? = null, classes: Set<String> = setOf()) : Widget(classes + "form-control"), StringFormField { + init { - this.setInternalEventListener { + this.setInternalEventListener<AbstractTextInput> { input = { val v = getElementJQuery()?.`val`() as String? if (v != null && v.isNotEmpty()) { - value = v + self.value = v } else { - value = null + self.value = null } } } } + override var value: String? = value + set(value) { + field = value + refreshState() + } @Suppress("LeakingThis") var startValue: String? = value set(value) { @@ -96,4 +102,10 @@ abstract class AbstractTextInput(override var value: String? = null, } return sn } + + private fun refreshState() { + value?.let { + getElementJQuery()?.`val`(it) + } ?: getElementJQueryD()?.`val`(null) + } } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/CheckBox.kt b/src/main/kotlin/pl/treksoft/kvision/form/CheckBox.kt index f4598d4d..ecd016b2 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/CheckBox.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/CheckBox.kt @@ -73,6 +73,8 @@ open class CheckBox(value: Boolean = false, label: String? = null, val flabel: FieldLabel = FieldLabel(idc, label, rich) init { + @Suppress("LeakingThis") + input.eventTarget = this this.addInternal(input) this.addInternal(flabel) counter++ diff --git a/src/main/kotlin/pl/treksoft/kvision/form/CheckInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/CheckInput.kt index 36e59e87..746b6e3d 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/CheckInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/CheckInput.kt @@ -10,22 +10,26 @@ enum class CHECKINPUTTYPE(val type: String) { RADIO("radio") } -open class CheckInput(type: CHECKINPUTTYPE = CHECKINPUTTYPE.CHECKBOX, override var value: Boolean = false, +open class CheckInput(type: CHECKINPUTTYPE = CHECKINPUTTYPE.CHECKBOX, value: Boolean = false, classes: Set<String> = setOf()) : Widget(classes), BoolFormField { init { - this.setInternalEventListener { + this.setInternalEventListener<CheckInput> { click = { val v = getElementJQuery()?.prop("checked") as Boolean? - value = (v == true) + self.value = (v == true) } change = { val v = getElementJQuery()?.prop("checked") as Boolean? - value = (v == true) + self.value = (v == true) } } } - + override var value: Boolean = value + set(value) { + field = value + refreshState() + } @Suppress("LeakingThis") var startValue: Boolean = value set(value) { @@ -90,14 +94,14 @@ open class CheckInput(type: CHECKINPUTTYPE = CHECKINPUTTYPE.CHECKBOX, override v } override fun afterInsert(node: VNode) { - refreshCheckedState() + refreshState() } override fun afterPostpatch(node: VNode) { - refreshCheckedState() + refreshState() } - private fun refreshCheckedState() { + private fun refreshState() { val v = getElementJQuery()?.prop("checked") as Boolean? if (this.value != v) { getElementJQuery()?.prop("checked", this.value) diff --git a/src/main/kotlin/pl/treksoft/kvision/form/Radio.kt b/src/main/kotlin/pl/treksoft/kvision/form/Radio.kt index 3ee6edff..f4ca9c41 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/Radio.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/Radio.kt @@ -81,6 +81,8 @@ open class Radio(value: Boolean = false, extraValue: String? = null, label: Stri val flabel: FieldLabel = FieldLabel(idc, label, rich) init { + @Suppress("LeakingThis") + input.eventTarget = this this.addInternal(input) this.addInternal(flabel) counter++ diff --git a/src/main/kotlin/pl/treksoft/kvision/form/Select.kt b/src/main/kotlin/pl/treksoft/kvision/form/Select.kt index a8759208..e099dd43 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/Select.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/Select.kt @@ -96,6 +96,8 @@ open class Select(options: List<StringPair>? = null, value: String? = null, init { this.addInternal(flabel) + @Suppress("LeakingThis") + input.eventTarget = this this.addInternal(input) counter++ } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/SelectInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/SelectInput.kt index bd67868d..68c3b57d 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/SelectInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/SelectInput.kt @@ -2,10 +2,12 @@ package pl.treksoft.kvision.form import com.github.snabbdom.VNode import pl.treksoft.kvision.core.CssSize +import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.html.BUTTONSTYLE import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.snabbdom.StringBoolPair import pl.treksoft.kvision.snabbdom.StringPair +import pl.treksoft.kvision.snabbdom.obj private val _aKVNULL = "#kvnull" @@ -14,7 +16,7 @@ enum class SELECTWIDTHTYPE(val value: String) { FIT("fit") } -class SelectInput(options: List<StringPair>? = null, override var value: String? = null, +class SelectInput(options: List<StringPair>? = null, value: String? = null, multiple: Boolean = false, classes: Set<String> = setOf()) : SimplePanel(classes), StringFormField { internal var options = options @@ -24,6 +26,13 @@ class SelectInput(options: List<StringPair>? = null, override var value: String? } @Suppress("LeakingThis") + override var value: String? = value + set(value) { + field = value + refreshState() + } + + @Suppress("LeakingThis") var startValue: String? = value set(value) { field = value @@ -122,17 +131,42 @@ class SelectInput(options: List<StringPair>? = null, override var value: String? return kvh("select", childrenVNodes()) } + override fun add(child: Widget): SimplePanel { + super.add(child) + refreshSelectInput() + return this + } + + override fun addAll(children: List<Widget>): SimplePanel { + super.addAll(children) + refreshSelectInput() + return this + } + + override fun remove(child: Widget): SimplePanel { + super.remove(child) + refreshSelectInput() + return this + } + + override fun removeAll(): SimplePanel { + super.removeAll() + refreshSelectInput() + return this + } + private fun setChildrenFromOptions() { - this.removeAll() + super.removeAll() if (emptyOption) { - this.add(SelectOption(_aKVNULL, "")) + super.add(SelectOption(_aKVNULL, "")) } options?.let { val c = it.map { SelectOption(it.first, it.second) } - this.addAll(c) + super.addAll(c) } + this.refreshSelectInput() } override fun getSnClass(): List<StringBoolPair> { @@ -144,6 +178,11 @@ class SelectInput(options: List<StringPair>? = null, override var value: String? return cl } + fun refreshSelectInput() { + getElementJQueryD()?.selectpicker("refresh") + refreshState() + } + @Suppress("ComplexMethod") override fun getSnAttrs(): List<StringPair> { val sn = super.getSnAttrs().toMutableList() @@ -193,12 +232,43 @@ class SelectInput(options: List<StringPair>? = null, override var value: String? @Suppress("UnsafeCastFromDynamic") override fun afterInsert(node: VNode) { getElementJQueryD()?.selectpicker("render") + this.getElementJQuery()?.on("show.bs.select", { e, _ -> + this.dispatchEvent("showBsSelect", obj({ detail = e })) + }) + this.getElementJQuery()?.on("shown.bs.select", { e, _ -> + this.dispatchEvent("shownBsSelect", obj({ detail = e })) + }) + this.getElementJQuery()?.on("hide.bs.select", { e, _ -> + this.dispatchEvent("hideBsSelect", obj({ detail = e })) + }) + this.getElementJQuery()?.on("hidden.bs.select", { e, _ -> + this.dispatchEvent("hiddenBsSelect", obj({ detail = e })) + }) + this.getElementJQuery()?.on("loaded.bs.select", { e, _ -> + this.dispatchEvent("loadedBsSelect", obj({ detail = e })) + }) + this.getElementJQuery()?.on("rendered.bs.select", { e, _ -> + this.dispatchEvent("renderedBsSelect", obj({ detail = e })) + }) + this.getElementJQuery()?.on("refreshed.bs.select", { e, _ -> + this.dispatchEvent("refreshedBsSelect", obj({ detail = e })) + }) + this.getElementJQueryD()?.on("changed.bs.select", { e, cIndex: Int -> + e["clickedIndex"] = cIndex + this.dispatchEvent("changedBsSelect", obj({ detail = e })) + }) + refreshState() + } + + @Suppress("UnsafeCastFromDynamic") + private fun refreshState() { value?.let { if (multiple) { getElementJQueryD()?.selectpicker("val", it.split(",").toTypedArray()) } else { getElementJQueryD()?.selectpicker("val", it) } - } + } ?: getElementJQueryD()?.selectpicker("val", null) } + } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/Text.kt b/src/main/kotlin/pl/treksoft/kvision/form/Text.kt index 01816195..211cb1f6 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/Text.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/Text.kt @@ -18,6 +18,8 @@ open class Text(type: TEXTINPUTTYPE = TEXTINPUTTYPE.TEXT, value: String? = null, final override val input: TextInput = TextInput(type, value).apply { id = idc } init { + @Suppress("LeakingThis") + input.eventTarget = this this.addInternal(input) } } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/TextArea.kt b/src/main/kotlin/pl/treksoft/kvision/form/TextArea.kt index 9b65a306..28bbdb48 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/TextArea.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/TextArea.kt @@ -22,6 +22,8 @@ open class TextArea(cols: Int? = null, rows: Int? = null, value: String? = null, final override val input: TextAreaInput = TextAreaInput(cols, rows, value).apply { id = idc } init { + @Suppress("LeakingThis") + input.eventTarget = this this.addInternal(input) } } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/TextAreaInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/TextAreaInput.kt index 5b8dd5b5..9f27bd16 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/TextAreaInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/TextAreaInput.kt @@ -23,7 +23,7 @@ class TextAreaInput(cols: Int? = null, rows: Int? = null, value: String? = null, } override fun render(): VNode { - return value?.let { + return startValue?.let { kvh("textarea", arrayOf(it)) } ?: kvh("textarea") } diff --git a/src/main/kotlin/pl/treksoft/kvision/snabbdom/Types.kt b/src/main/kotlin/pl/treksoft/kvision/snabbdom/Types.kt index f1a79a76..ecd3316e 100644 --- a/src/main/kotlin/pl/treksoft/kvision/snabbdom/Types.kt +++ b/src/main/kotlin/pl/treksoft/kvision/snabbdom/Types.kt @@ -21,9 +21,13 @@ fun obj(init: dynamic.() -> Unit): dynamic { @Suppress("UnsafeCastFromDynamic") private fun vNodeData(): VNodeData = js("({})") +interface KvJQueryEventObject : JQueryEventObject { + val clickedIndex: Int +} + @Suppress("UnsafeCastFromDynamic") class KvEvent(type: String, eventInitDict: CustomEventInit) : CustomEvent(type, eventInitDict) { - override val detail: JQueryEventObject = obj({}) + override val detail: KvJQueryEventObject = obj({}) } interface BtOn : On { @@ -37,6 +41,14 @@ interface BtOn : On { var hiddenBsModal: ((KvEvent) -> kotlin.Unit)? var dragSplitPanel: ((KvEvent) -> kotlin.Unit)? var dragEndSplitPanel: ((KvEvent) -> kotlin.Unit)? + var showBsSelect: ((KvEvent) -> kotlin.Unit)? + var shownBsSelect: ((KvEvent) -> kotlin.Unit)? + var hideBsSelect: ((KvEvent) -> kotlin.Unit)? + var hiddenBsSelect: ((KvEvent) -> kotlin.Unit)? + var loadedBsSelect: ((KvEvent) -> kotlin.Unit)? + var renderedBsSelect: ((KvEvent) -> kotlin.Unit)? + var refreshedBsSelect: ((KvEvent) -> kotlin.Unit)? + var changedBsSelect: ((KvEvent) -> kotlin.Unit)? } interface SnOn<T> : BtOn { |