diff options
author | Robert Jaros <rjaros@finn.pl> | 2017-09-15 13:08:34 +0200 |
---|---|---|
committer | Robert Jaros <rjaros@finn.pl> | 2017-09-15 13:08:34 +0200 |
commit | 3d8cac6ab126a5fcb2bc8c0fed864afdaa4349ea (patch) | |
tree | 0b9c05db4e9c254a12de54d8e75bcb84cd4d712b | |
parent | 04e33bba30b821dc6634cd049798eb944b03717f (diff) | |
download | kvision-3d8cac6ab126a5fcb2bc8c0fed864afdaa4349ea.tar.gz kvision-3d8cac6ab126a5fcb2bc8c0fed864afdaa4349ea.tar.bz2 kvision-3d8cac6ab126a5fcb2bc8c0fed864afdaa4349ea.zip |
Support child nodes of dropdown component
-rw-r--r-- | build.gradle | 2 | ||||
-rw-r--r-- | src/main/kotlin/pl/treksoft/kvision/Showcase.kt | 13 | ||||
-rw-r--r-- | src/main/kotlin/pl/treksoft/kvision/core/Container.kt | 12 | ||||
-rw-r--r-- | src/main/kotlin/pl/treksoft/kvision/core/Widget.kt | 3 | ||||
-rw-r--r-- | src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt | 159 |
5 files changed, 157 insertions, 32 deletions
diff --git a/build.gradle b/build.gradle index 3b937d0c..bcb67d44 100644 --- a/build.gradle +++ b/build.gradle @@ -32,7 +32,7 @@ dependencies { compile "org.jetbrains.kotlin:kotlin-test-js:$kotlin_version" // for now only compile configuration is supported compile "com.github.snabbdom:snabbdom-kotlin:0.1.0" compile "pl.treksoft:navigo-kotlin:0.0.1" - compile "pl.treksoft:jquery-kotlin:0.0.1" + compile "pl.treksoft:jquery-kotlin:0.0.2" } kotlinFrontend { diff --git a/src/main/kotlin/pl/treksoft/kvision/Showcase.kt b/src/main/kotlin/pl/treksoft/kvision/Showcase.kt index 6275fe88..9ab1ac0e 100644 --- a/src/main/kotlin/pl/treksoft/kvision/Showcase.kt +++ b/src/main/kotlin/pl/treksoft/kvision/Showcase.kt @@ -47,6 +47,13 @@ class Showcase : ApplicationBase() { hiddenBsDropdown = { e -> println("hidden" + e.detail) } } + val dd3 = DropDown("Dropdown3", icon = "file") + dd3.add(Tag(TAG.H4, "ABC")) + dd3.add(Button("To jest button")) + dd3.add(Image(Img("kotlin.png"))) + root.add(dd3) + + val p = Tag(TAG.P, "To jest prawo", align = ALIGN.RIGHT) p.title = "Tytuł" root.add(p) @@ -68,7 +75,11 @@ class Showcase : ApplicationBase() { val button = Button("To jest przycisk FA", "fa-flag", BUTTONSTYLE.DANGER) button.setEventListener<Button> { - click = { _ -> println(self.text) } + click = { _ -> + println(self.text) + dd3.text = "Zmiana" + dd3.style = BUTTONSTYLE.WARNING + } } root.add(button) val button2 = Button("To jest przycisk", "flag", BUTTONSTYLE.DANGER) diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Container.kt b/src/main/kotlin/pl/treksoft/kvision/core/Container.kt index 028c55ce..2d81f630 100644 --- a/src/main/kotlin/pl/treksoft/kvision/core/Container.kt +++ b/src/main/kotlin/pl/treksoft/kvision/core/Container.kt @@ -13,12 +13,16 @@ open class Container(classes: Set<String> = setOf()) : Widget(classes) { return children.filter { it.visible }.map { it.render() }.toTypedArray() } - open fun add(child: Widget) { + protected fun addInternal(child: Widget) { children.add(child) child.parent = this refresh() } + open fun add(child: Widget) { + addInternal(child) + } + open fun addAll(children: List<Widget>) { this.children.addAll(children) children.map { it.parent = this } @@ -36,4 +40,10 @@ open class Container(classes: Set<String> = setOf()) : Widget(classes) { refresh() } + open fun removeAll() { + children.map { it.clearParent() } + children.clear() + refresh() + } + } diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt index 142c3069..9c6941b7 100644 --- a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt +++ b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt @@ -27,8 +27,9 @@ open class Widget(classes: Set<String> = setOf()) : KVObject { var visible: Boolean = true set(value) { + val oldField = field field = value - refresh() + if (oldField != field) refresh() } var title: String? = null set(value) { diff --git a/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt b/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt index 57890a81..f2784e5a 100644 --- a/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt +++ b/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt @@ -4,6 +4,7 @@ import com.github.snabbdom.VNode import org.w3c.dom.CustomEvent import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.ResString +import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.html.BUTTONSIZE import pl.treksoft.kvision.html.BUTTONSTYLE import pl.treksoft.kvision.html.Button @@ -12,6 +13,7 @@ import pl.treksoft.kvision.html.Link import pl.treksoft.kvision.html.ListTag import pl.treksoft.kvision.html.TAG import pl.treksoft.kvision.html.Tag +import pl.treksoft.kvision.snabbdom.StringBoolPair import pl.treksoft.kvision.snabbdom.StringPair import pl.treksoft.kvision.snabbdom.obj @@ -21,42 +23,72 @@ enum class DD(val POS: String) { SEPARATOR("DD#SEPARATOR") } -open class DropDown(text: String, elements: List<StringPair>, icon: String? = null, +open class DropDown(text: String, elements: List<StringPair>? = null, icon: String? = null, style: BUTTONSTYLE = BUTTONSTYLE.DEFAULT, size: BUTTONSIZE? = null, block: Boolean = false, disabled: Boolean = false, image: ResString? = null, dropup: Boolean = false, classes: Set<String> = setOf()) : Container(classes) { + var text + get() = button.text + set(value) { + button.text = value + } + var elements = elements + set(value) { + field = elements + setChildrenFromElements() + } + var icon + get() = button.icon + set(value) { + button.icon = value + } + var style + get() = button.style + set(value) { + button.style = value + } + var size + get() = button.size + set(value) { + button.size = value + } + var block + get() = button.block + set(value) { + button.block = value + } + var disabled + get() = button.disabled + set(value) { + button.disabled = value + } + var image + get() = button.image + set(value) { + button.image = value + } + var dropup = dropup + set(value) { + field = value + refresh() + } + val idc = "kv_dropdown_" + counter val button: DropDownButton = DropDownButton(idc, text, icon, style, size, block, disabled, image, setOf("dropdown")) val list: DropDownListTag = DropDownListTag(idc, setOf("dropdown-menu")) init { - this.addCssClass(if (dropup) "dropup" else "dropdown") - val children = elements.map { - when (it.second) { - DD.HEADER.POS -> Tag(TAG.LI, it.first, classes = setOf("dropdown-header")) - DD.SEPARATOR.POS -> { - val tag = Tag(TAG.LI, it.first, classes = setOf("divider")) - tag.role = "separator" - tag - } - DD.DISABLED.POS -> { - val tag = Tag(TAG.LI, classes = setOf("disabled")) - tag.add(Link(it.first, "#")) - tag - } - else -> Link(it.first, it.second) - } - } button.setEventListener { click = { - list.getElementJQueryD().dropdown("toggle") + toggle() } } - list.addAll(children) - this.add(button) - this.add(list) + list.hide() + setChildrenFromElements() + this.addInternal(button) + this.addInternal(list) counter++ } @@ -64,27 +96,74 @@ open class DropDown(text: String, elements: List<StringPair>, icon: String? = nu var counter = 0 } + override fun add(child: Widget) { + list.add(child) + } + + override fun addAll(children: List<Widget>) { + list.addAll(children) + } + + private fun setChildrenFromElements() { + val elems = elements + if (elems != null) { + val c = elems.map { + when (it.second) { + DD.HEADER.POS -> Tag(TAG.LI, it.first, classes = setOf("dropdown-header")) + DD.SEPARATOR.POS -> { + val tag = Tag(TAG.LI, it.first, classes = setOf("divider")) + tag.role = "separator" + tag + } + DD.DISABLED.POS -> { + val tag = Tag(TAG.LI, classes = setOf("disabled")) + tag.add(Link(it.first, "#")) + tag + } + else -> Link(it.first, it.second) + } + } + list.addAll(c) + } else { + list.removeAll() + } + } + + @Suppress("UnsafeCastFromDynamic") override fun afterInsert(node: VNode) { this.getElementJQuery()?.on("show.bs.dropdown", { _, _ -> val event = CustomEvent("showBsDropdown", obj({ detail = button })) - this.getElement()?.dispatchEvent(event) as Any + this.getElement()?.dispatchEvent(event) }) this.getElementJQuery()?.on("shown.bs.dropdown", { _, _ -> val event = CustomEvent("shownBsDropdown", obj({ detail = button })) - this.getElement()?.dispatchEvent(event) as Any + this.getElement()?.dispatchEvent(event) }) this.getElementJQuery()?.on("hide.bs.dropdown", { _, _ -> val event = CustomEvent("hideBsDropdown", obj({ detail = button })) - this.getElement()?.dispatchEvent(event) as Any + this.getElement()?.dispatchEvent(event) }) this.getElementJQuery()?.on("hidden.bs.dropdown", { _, _ -> + list.visible = false val event = CustomEvent("hiddenBsDropdown", obj({ detail = button })) - this.getElement()?.dispatchEvent(event) as Any + this.getElement()?.dispatchEvent(event) }) } + override fun getSnClass(): List<StringBoolPair> { + val cl = super.getSnClass().toMutableList() + if (dropup) + cl.add("dropup" to true) + else + cl.add("dropdown" to true) + return cl + } + open fun toggle() { - list.getElementJQueryD().dropdown("toggle") + if (list.visible) + list.hide() + else + list.show() } } @@ -103,9 +182,33 @@ open class DropDownButton(id: String, text: String, icon: String? = null, style: } } -open class DropDownListTag(val ariaId: String, classes: Set<String> = setOf()) : ListTag(LIST.UL, null, +open class DropDownListTag(private val ariaId: String, classes: Set<String> = setOf()) : ListTag(LIST.UL, null, false, classes) { + override fun getSnAttrs(): List<StringPair> { return super.getSnAttrs() + listOf("aria-labelledby" to ariaId) } + + override fun hide() { + if (visible) hideInternal() + super.hide() + } + + override fun afterInsert(node: VNode) { + if (visible) showInternal() + } + + @Suppress("UnsafeCastFromDynamic") + private fun showInternal() { + if (getElementJQueryD()?.`is`(":hidden")) { + getElementJQueryD()?.dropdown("toggle") + } + } + + @Suppress("UnsafeCastFromDynamic") + private fun hideInternal() { + if (!getElementJQueryD()?.`is`(":hidden")) { + getElementJQueryD()?.dropdown("toggle") + } + } } |