diff options
Diffstat (limited to 'src/main/kotlin/pl/treksoft/kvision/modal')
-rw-r--r-- | src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt | 54 | ||||
-rw-r--r-- | src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt | 84 | ||||
-rw-r--r-- | src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt | 191 |
3 files changed, 329 insertions, 0 deletions
diff --git a/src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt b/src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt new file mode 100644 index 00000000..5e0e910a --- /dev/null +++ b/src/main/kotlin/pl/treksoft/kvision/modal/Alert.kt @@ -0,0 +1,54 @@ +package pl.treksoft.kvision.modal + +import pl.treksoft.kvision.html.ALIGN +import pl.treksoft.kvision.html.BUTTONSTYLE +import pl.treksoft.kvision.html.Button +import pl.treksoft.kvision.html.TAG +import pl.treksoft.kvision.html.Tag + +open class Alert(caption: String? = null, text: String? = null, rich: Boolean = false, + align: ALIGN = ALIGN.NONE, size: MODALSIZE? = null, animation: Boolean = true, + private val callback: (() -> Unit)? = null) : Modal(caption, true, size, animation) { + var text + get() = content.text + set(value) { + content.text = value + } + var rich + get() = content.rich + set(value) { + content.rich = value + } + var align + get() = content.align + set(value) { + content.align = value + } + + val content = Tag(TAG.SPAN, text, rich, align) + + init { + body.add(content) + val okButton = Button("OK", "ok", BUTTONSTYLE.PRIMARY) + okButton.setEventListener { + click = { + hide() + } + } + this.addButton(okButton) + } + + override fun hide() { + super.hide() + this.callback?.invoke() + } + + companion object { + @Suppress("LongParameterList") + fun show(caption: String? = null, text: String? = null, rich: Boolean = false, + align: ALIGN = ALIGN.NONE, size: MODALSIZE? = null, animation: Boolean = true, + callback: (() -> Unit)? = null) { + Alert(caption, text, rich, align, size, animation, callback).show() + } + } +} diff --git a/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt b/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt new file mode 100644 index 00000000..366eec52 --- /dev/null +++ b/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt @@ -0,0 +1,84 @@ +package pl.treksoft.kvision.modal + +import pl.treksoft.kvision.html.ALIGN +import pl.treksoft.kvision.html.BUTTONSTYLE +import pl.treksoft.kvision.html.Button +import pl.treksoft.kvision.html.TAG +import pl.treksoft.kvision.html.Tag + +open class Confirm(caption: String? = null, text: String? = null, rich: Boolean = false, + align: ALIGN = ALIGN.NONE, size: MODALSIZE? = null, animation: Boolean = true, + cancelVisible: Boolean = false, + private val noCallback: (() -> Unit)? = null, + private val yesCallback: (() -> Unit)? = null) : Modal(caption, false, size, animation, false) { + var text + get() = content.text + set(value) { + content.text = value + } + var rich + get() = content.rich + set(value) { + content.rich = value + } + var align + get() = content.align + set(value) { + content.align = value + } + var cancelVisible = cancelVisible + set(value) { + field = value + refreshCancelButton() + } + + val content = Tag(TAG.SPAN, text, rich, align) + val cancelButton = Button("Cancel", "remove") + + init { + body.add(content) + cancelButton.setEventListener { + click = { + hide() + } + } + this.addButton(cancelButton) + val noButton = Button("No", "ban-circle") + noButton.setEventListener { + click = { + hide() + noCallback?.invoke() + } + } + this.addButton(noButton) + val yesButton = Button("Yes", "ok", BUTTONSTYLE.PRIMARY) + yesButton.setEventListener { + click = { + hide() + yesCallback?.invoke() + } + } + this.addButton(yesButton) + refreshCancelButton() + } + + private fun refreshCancelButton() { + if (cancelVisible) { + cancelButton.show() + closeIcon.show() + } else { + cancelButton.hide() + closeIcon.hide() + } + } + + companion object { + @Suppress("LongParameterList") + fun show(caption: String? = null, text: String? = null, rich: Boolean = false, + align: ALIGN = ALIGN.NONE, size: MODALSIZE? = null, animation: Boolean = true, + cancelVisible: Boolean = false, + noCallback: (() -> Unit)? = null, yesCallback: (() -> Unit)? = null) { + Confirm(caption, text, rich, align, size, animation, cancelVisible, noCallback, yesCallback).show() + } + } +} diff --git a/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt b/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt new file mode 100644 index 00000000..0b11d45f --- /dev/null +++ b/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt @@ -0,0 +1,191 @@ +package pl.treksoft.kvision.modal + +import com.github.snabbdom.VNode +import org.w3c.dom.CustomEvent +import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.core.Root +import pl.treksoft.kvision.core.Widget +import pl.treksoft.kvision.helpers.CloseIcon +import pl.treksoft.kvision.html.Button +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 + +enum class MODALSIZE(val className: String) { + LARGE("modal-lg"), + SMALL("modal-sm") +} + +@Suppress("TooManyFunctions") +open class Modal(caption: String? = null, closeButton: Boolean = true, + size: MODALSIZE? = null, animation: Boolean = true, val escape: Boolean = true, + classes: Set<String> = setOf()) : Container(classes) { + var caption + get() = captionTag.text + set(value) { + captionTag.text = value + checkHeaderVisibility() + } + var closeButton + get() = closeIcon.visible + set(value) { + closeIcon.visible = value + checkHeaderVisibility() + } + var size + get() = dialog.size + set(value) { + dialog.size = value + } + var animation = animation + set(value) { + field = value + refresh() + } + + protected val dialog = ModalDialog(size) + protected val header = Container(setOf("modal-header")) + protected val closeIcon = CloseIcon() + protected val captionTag = Tag(TAG.H4, caption, classes = setOf("modal-title")) + protected val body = Container(setOf("modal-body")) + protected val footer = Container(setOf("modal-footer")) + + init { + this.hide() + this.role = "dialog" + this.addInternal(dialog) + val content = Container(setOf("modal-content")) + dialog.role = "document" + dialog.add(content) + closeIcon.visible = closeButton + closeIcon.setEventListener { + click = { + hide() + } + } + header.add(closeIcon) + header.add(captionTag) + checkHeaderVisibility() + content.add(header) + content.add(body) + content.add(footer) + val root = Root.getLastRoot() + if (root != null) { + root.addModal(this) + } else { + println("At least one Root object is required to create a modal!") + } + } + + private fun checkHeaderVisibility() { + if (!closeButton && caption == null) { + header.hide() + } else { + header.show() + } + } + + override fun add(child: Widget) { + body.add(child) + } + + override fun addAll(children: List<Widget>) { + body.addAll(children) + } + + open fun addButton(button: Button) { + footer.add(button) + } + + open fun removeButton(button: Button) { + footer.remove(button) + } + + open fun removeButtonAt(index: Int) { + footer.removeAt(index) + } + + open fun removeAllButtons() { + footer.removeAll() + } + + override fun getSnAttrs(): List<StringPair> { + val pr = super.getSnAttrs().toMutableList() + pr.add("tabindex" to "-1") + return pr + } + + override fun getSnClass(): List<StringBoolPair> { + val cl = super.getSnClass().toMutableList() + cl.add("modal" to true) + if (animation) { + cl.add("fade" to true) + } + return cl + } + + @Suppress("UnsafeCastFromDynamic") + override fun afterInsert(node: VNode) { + getElementJQueryD()?.modal(obj { + keyboard = escape + backdrop = if (escape) "true" else "static" + }) + this.getElementJQuery()?.on("show.bs.modal", { _, _ -> + val event = CustomEvent("showBsModal") + this.getElement()?.dispatchEvent(event) + }) + this.getElementJQuery()?.on("shown.bs.modal", { _, _ -> + val event = CustomEvent("shownBsModal") + this.getElement()?.dispatchEvent(event) + }) + this.getElementJQuery()?.on("hide.bs.modal", { _, _ -> + val event = CustomEvent("hideBsModal") + this.getElement()?.dispatchEvent(event) + }) + this.getElementJQuery()?.on("hidden.bs.modal", { _, _ -> + this.visible = false + val event = CustomEvent("hiddenBsModal") + this.getElement()?.dispatchEvent(event) + }) + } + + override fun hide() { + if (visible) hideInternal() + super.hide() + } + + open fun toggle() { + if (visible) + hide() + else + show() + } + + @Suppress("UnsafeCastFromDynamic") + private fun showInternal() { + getElementJQueryD()?.modal("show") + } + + @Suppress("UnsafeCastFromDynamic") + private fun hideInternal() { + getElementJQueryD()?.modal("hide") + } +} + +open class ModalDialog(size: MODALSIZE?) : Container(setOf("modal-dialog")) { + var size = size + set(value) { + field = value + refresh() + } + + override fun getSnClass(): List<StringBoolPair> { + val cl = super.getSnClass().toMutableList() + if (size != null) { + cl.add(size?.className.orEmpty() to true) + } + return cl + } +} |