diff options
author | Robert Jaros <rjaros@finn.pl> | 2018-01-16 00:13:54 +0100 |
---|---|---|
committer | Robert Jaros <rjaros@finn.pl> | 2018-01-16 00:13:54 +0100 |
commit | bcc5292dd95e5824da41a19bfbf64ebc25d79102 (patch) | |
tree | 5a97a4da432d2db97ea2fa6755c8b0e42394690f | |
parent | a107c5b7fe1cf0429436045e336b08d16b387367 (diff) | |
download | kvision-bcc5292dd95e5824da41a19bfbf64ebc25d79102.tar.gz kvision-bcc5292dd95e5824da41a19bfbf64ebc25d79102.tar.bz2 kvision-bcc5292dd95e5824da41a19bfbf64ebc25d79102.zip |
Spinner form controls
Unit tests
13 files changed, 639 insertions, 3 deletions
diff --git a/build.gradle b/build.gradle index 3f6767cf..65a2aa39 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.1.61' + ext.kotlin_version = '1.2.10' repositories { jcenter() @@ -57,6 +57,7 @@ kotlinFrontend { dependency "trix" dependency "fecha" dependency "bootstrap-datetime-picker" + dependency "bootstrap-touchspin" dependency("snabbdom", "0.6.9") dependency "snabbdom-virtualize" dependency "navigo" diff --git a/src/main/assets/css/style.css b/src/main/assets/css/style.css index 1917ba15..c256fc1f 100644 --- a/src/main/assets/css/style.css +++ b/src/main/assets/css/style.css @@ -85,3 +85,24 @@ trix-toolbar .trix-button-group { .form-inline .form-group, .form-inline .control-label { vertical-align: top; } + +.bootstrap-touchspin .input-group-btn-vertical> .input-sm { + padding: 7px 10px; + height: 6px; +} + +.bootstrap-touchspin .input-group-btn-vertical> .input-lg { + height: 24px; +} + +.kv-spinner-btn-none .input-group-btn-vertical { + display: none; +} + +.kv-spinner-btn-none .form-control { + border-radius: 4px !important; +} + +.kv-spinner-btn-vertical .form-control { + border-radius: 4px 0px 0px 4px !important; +} diff --git a/src/main/kotlin/pl/treksoft/kvision/Showcase.kt b/src/main/kotlin/pl/treksoft/kvision/Showcase.kt index 82651b71..a27fae2d 100644 --- a/src/main/kotlin/pl/treksoft/kvision/Showcase.kt +++ b/src/main/kotlin/pl/treksoft/kvision/Showcase.kt @@ -20,6 +20,9 @@ import pl.treksoft.kvision.form.select.Select import pl.treksoft.kvision.form.select.SelectInput import pl.treksoft.kvision.form.select.SelectOptGroup import pl.treksoft.kvision.form.select.SelectOption +import pl.treksoft.kvision.form.spinner.FORCETYPE +import pl.treksoft.kvision.form.spinner.Spinner +import pl.treksoft.kvision.form.spinner.SpinnerInput import pl.treksoft.kvision.form.string import pl.treksoft.kvision.form.text.Password import pl.treksoft.kvision.form.text.RichText @@ -414,6 +417,7 @@ class Showcase : ApplicationBase() { val checkbox: Boolean by map val radio: Boolean by map val select: String? by map + val spinner: Double? by map } val formPanel = FormPanel() { @@ -436,6 +440,7 @@ class Showcase : ApplicationBase() { // selectWidthType = SELECTWIDTHTYPE.FIT emptyOption = true }, required = true) + add("spinner", Spinner(label = "Spinner"), required = true) validator = { var result = it["text"] == it["textarea"] @@ -448,14 +453,38 @@ class Showcase : ApplicationBase() { validatorMessage = { "Pole Tekst i Obszar muszą być takie same!" } } root.add(formPanel) + val spinner = SpinnerInput(15.05, min = -100000, max = 100000, decimals = 4, forceType = FORCETYPE.ROUND, step = 0.0001).apply { + size = INPUTSIZE.LARGE + } + val ttt = TextInput(value = "abc").apply { + size = INPUTSIZE.LARGE + } + spinner.setEventListener<SpinnerInput> { + onMinBsSpinner = { e -> + console.log(e) + } + onMaxBsSpinner = { e -> + console.log(e) + } + } val formButton = Button("Pokaż dane").setEventListener<Button> { click = { console.log(formPanel.validate()) console.log(formPanel.getData().map.toString()) // formPanel.setData(Formularz(mapOf("zazn" to false, "select" to "a"))) + spinner.toggleVisible() + spinner.max = spinner.max.plus(2) + ttt.toggleVisible() } } formPanel.add(formButton) + spinner.setEventListener<SpinnerInput> { + change = { + console.log(spinner.value) + } + } + root.add(spinner) + root.add(ttt) val dd = DropDown("Dropdown", listOf("abc" to "#!/x", "def" to "#!/y"), "flag") root.add(dd) diff --git a/src/main/kotlin/pl/treksoft/kvision/core/KVManager.kt b/src/main/kotlin/pl/treksoft/kvision/core/KVManager.kt index 65a7fe6e..0c010553 100644 --- a/src/main/kotlin/pl/treksoft/kvision/core/KVManager.kt +++ b/src/main/kotlin/pl/treksoft/kvision/core/KVManager.kt @@ -31,6 +31,8 @@ object KVManager { private val trix = require("trix") private val bootstrapDateTimePickerCss = require("bootstrap-datetime-picker/css/bootstrap-datetimepicker.min.css") private val bootstrapDateTimePicker = require("bootstrap-datetime-picker/js/bootstrap-datetimepicker.min.js") + private val bootstrapTouchspinCss = require("bootstrap-touchspin/dist/jquery.bootstrap-touchspin.min.css") + private val bootstrapTouchspin = require("bootstrap-touchspin/dist/jquery.bootstrap-touchspin.min.js") internal val fecha = require("fecha") private val sdPatch = Snabbdom.init(arrayOf(classModule, attributesModule, propsModule, styleModule, diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt index fec62ec7..8a7dfd15 100644 --- a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt +++ b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt @@ -48,6 +48,11 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent() { field = value refresh() } + var surroundingSpan: Boolean = false + set(value) { + field = value + refresh() + } internal var eventTarget: Widget? = null private var vnode: VNode? = null @@ -67,12 +72,20 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent() { override fun renderVNode(): VNode { return if (surroundingClasses.isEmpty()) { - render() + if (surroundingSpan) { + h("span", arrayOf(render())) + } else { + render() + } } else { val opt = snOpt { `class` = snClasses(surroundingClasses.map { c -> c to true }) } - h("div", opt, arrayOf(render())) + if (surroundingSpan) { + h("div", opt, arrayOf(h("span", arrayOf(render())))) + } else { + h("div", opt, arrayOf(render())) + } } } @@ -265,6 +278,10 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent() { return this } + open fun toggleVisible(): Widget { + return if (visible) hide() else show() + } + override fun addCssClass(css: String): Widget { this.classes.add(css) refresh() diff --git a/src/main/kotlin/pl/treksoft/kvision/form/spinner/Spinner.kt b/src/main/kotlin/pl/treksoft/kvision/form/spinner/Spinner.kt new file mode 100644 index 00000000..c6084fa8 --- /dev/null +++ b/src/main/kotlin/pl/treksoft/kvision/form/spinner/Spinner.kt @@ -0,0 +1,148 @@ +package pl.treksoft.kvision.form.spinner + +import pl.treksoft.kvision.core.Widget +import pl.treksoft.kvision.form.FieldLabel +import pl.treksoft.kvision.form.HelpBlock +import pl.treksoft.kvision.form.NumberFormControl +import pl.treksoft.kvision.panel.SimplePanel +import pl.treksoft.kvision.snabbdom.SnOn +import pl.treksoft.kvision.snabbdom.StringBoolPair + +open class Spinner(value: Number? = null, min: Int = 0, max: Int = DEFAULT_MAX, step: Double = DEFAULT_STEP, + decimals: Int = 0, buttonsType: BUTTONSTYPE = BUTTONSTYPE.VERTICAL, + forceType: FORCETYPE = FORCETYPE.NONE, label: String? = null, + rich: Boolean = false) : SimplePanel(setOf("form-group")), NumberFormControl { + + override var value + get() = input.value + set(value) { + input.value = value + } + var min + get() = input.min + set(value) { + input.min = value + } + var max + get() = input.max + set(value) { + input.max = value + } + var step + get() = input.step + set(value) { + input.step = value + } + var decimals + get() = input.decimals + set(value) { + input.decimals = value + } + var buttonsType + get() = input.buttonsType + set(value) { + input.buttonsType = value + } + var forceType + get() = input.forceType + set(value) { + input.forceType = value + } + var placeholder + get() = input.placeholder + set(value) { + input.placeholder = value + } + var name + get() = input.name + set(value) { + input.name = value + } + override var disabled + get() = input.disabled + set(value) { + input.disabled = value + } + var autofocus + get() = input.autofocus + set(value) { + input.autofocus = value + } + var readonly + get() = input.readonly + set(value) { + input.readonly = value + } + var label + get() = flabel.text + set(value) { + flabel.text = value + } + var rich + get() = flabel.rich + set(value) { + flabel.rich = value + } + override var size + get() = input.size + set(value) { + input.size = value + } + + protected val idc = "kv_form_spinner_" + counter + final override val input: SpinnerInput = SpinnerInput(value, min, max, step, decimals, buttonsType, forceType) + .apply { id = idc } + final override val flabel: FieldLabel = FieldLabel(idc, label, rich) + final override val validationInfo: HelpBlock = HelpBlock().apply { visible = false } + + init { + @Suppress("LeakingThis") + input.eventTarget = this + this.addInternal(flabel) + this.addInternal(input) + this.addInternal(validationInfo) + counter++ + } + + companion object { + var counter = 0 + } + + override fun getSnClass(): List<StringBoolPair> { + val cl = super.getSnClass().toMutableList() + if (validatorError != null) { + cl.add("has-error" to true) + } + return cl + } + + @Suppress("UNCHECKED_CAST") + override fun <T : Widget> setEventListener(block: SnOn<T>.() -> Unit): Widget { + input.setEventListener(block) + return this + } + + override fun setEventListener(block: SnOn<Widget>.() -> Unit): Widget { + input.setEventListener(block) + return this + } + + override fun removeEventListeners(): Widget { + input.removeEventListeners() + return this + } + + override fun getValueAsString(): String? { + return input.getValueAsString() + } + + open fun spinUp(): Spinner { + input.spinUp() + return this + } + + open fun spinDown(): Spinner { + input.spinDown() + return this + } +} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt new file mode 100644 index 00000000..b7d0f959 --- /dev/null +++ b/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt @@ -0,0 +1,242 @@ +package pl.treksoft.kvision.form.spinner + +import com.github.snabbdom.VNode +import pl.treksoft.jquery.JQuery +import pl.treksoft.kvision.core.Widget +import pl.treksoft.kvision.form.INPUTSIZE +import pl.treksoft.kvision.snabbdom.StringBoolPair +import pl.treksoft.kvision.snabbdom.StringPair +import pl.treksoft.kvision.snabbdom.obj + +enum class BUTTONSTYPE { + NONE, + HORIZONTAL, + VERTICAL +} + +enum class FORCETYPE(val value: String) { + NONE("none"), + ROUND("round"), + FLOOR("floor"), + CEIL("cail") +} + +const val DEFAULT_STEP = 1.0 +const val DEFAULT_MAX = 100 + +@Suppress("TooManyFunctions") +open class SpinnerInput(value: Number? = null, min: Int = 0, max: Int = DEFAULT_MAX, step: Double = DEFAULT_STEP, + decimals: Int = 0, buttonsType: BUTTONSTYPE = BUTTONSTYPE.VERTICAL, + forceType: FORCETYPE = FORCETYPE.NONE, + classes: Set<String> = setOf()) : Widget(classes + "form-control") { + + init { + this.addSurroundingCssClass("input-group") + if (buttonsType == BUTTONSTYPE.NONE) { + this.addSurroundingCssClass("kv-spinner-btn-none") + } else { + this.removeSurroundingCssClass("kv-spinner-btn-none") + } + if (buttonsType == BUTTONSTYPE.VERTICAL) { + this.addSurroundingCssClass("kv-spinner-btn-vertical") + } else { + this.removeSurroundingCssClass("kv-spinner-btn-vertical") + } + this.surroundingSpan = true + this.refreshSpinner() + this.setInternalEventListener<SpinnerInput> { + change = { + self.changeValue() + } + } + } + + var value: Number? = value + set(value) { + field = value + refreshState() + } + var startValue: Number? = value + set(value) { + field = value + this.value = value + refresh() + } + var min: Int = min + set(value) { + field = value + refreshSpinner() + } + var max: Int = max + set(value) { + field = value + refreshSpinner() + } + var step: Double = step + set(value) { + field = value + refreshSpinner() + } + var decimals: Int = decimals + set(value) { + field = value + refreshSpinner() + } + var buttonsType: BUTTONSTYPE = buttonsType + set(value) { + field = value + refreshSpinner() + } + var forceType: FORCETYPE = forceType + set(value) { + field = value + refreshSpinner() + } + var placeholder: String? = null + set(value) { + field = value + refresh() + } + var name: String? = null + set(value) { + field = value + refresh() + } + var disabled: Boolean = false + set(value) { + field = value + refresh() + } + var autofocus: Boolean? = null + set(value) { + field = value + refresh() + } + var readonly: Boolean? = null + set(value) { + field = value + refresh() + } + var size: INPUTSIZE? = null + set(value) { + field = value + refresh() + } + + private var siblings: JQuery? = null + + override fun render(): VNode { + return kvh("input") + } + + override fun getSnClass(): List<StringBoolPair> { + val cl = super.getSnClass().toMutableList() + size?.let { + cl.add(it.className to true) + } + return cl + } + + override fun getSnAttrs(): List<StringPair> { + val sn = super.getSnAttrs().toMutableList() + sn.add("type" to "text") + startValue?.let { + sn.add("value" to it.toString()) + } + placeholder?.let { + sn.add("placeholder" to it) + } + name?.let { + sn.add("name" to it) + } + autofocus?.let { + if (it) { + sn.add("autofocus" to "autofocus") + } + } + readonly?.let { + if (it) { + sn.add("readonly" to "readonly") + } + } + if (disabled) { + sn.add("disabled" to "true") + value?.let { + sn.add("value" to it.toString()) + } + } + return sn + } + + protected open fun changeValue() { + val v = getElementJQuery()?.`val`() as String? + if (v != null && v.isNotEmpty()) { + this.value = v.toDoubleOrNull() + } else { + this.value = null + } + } + + @Suppress("UnsafeCastFromDynamic") + override fun afterInsert(node: VNode) { + getElementJQueryD()?.TouchSpin(getSettingsObj()) + siblings = getElementJQuery()?.parent(".bootstrap-touchspin")?.children("span") + size?.let { + siblings?.find("button")?.addClass(it.className) + } + this.getElementJQuery()?.on("change", { e, _ -> + if (e.asDynamic().isTrigger != null) { + val event = org.w3c.dom.events.Event("change") + this.getElement()?.dispatchEvent(event) + } + }) + this.getElementJQuery()?.on("touchspin.on.min", { e, _ -> + this.dispatchEvent("onMinBsSpinner", obj { detail = e }) + }) + this.getElementJQuery()?.on("touchspin.on.max", { e, _ -> + this.dispatchEvent("onMaxBsSpinner", obj { detail = e }) + }) + refreshState() + } + + override fun afterDestroy() { + siblings?.remove() + siblings = null + } + + fun getValueAsString(): String? { + return value?.toString() + } + + fun spinUp(): SpinnerInput { + getElementJQueryD()?.trigger("touchspin.uponce") + return this + } + + fun spinDown(): SpinnerInput { + getElementJQueryD()?.trigger("touchspin.downonce") + return this + } + + private fun refreshState() { + value?.let { + getElementJQuery()?.`val`(it.toString()) + } ?: getElementJQueryD()?.`val`(null) + } + + private fun refreshSpinner() { + getElementJQueryD()?.trigger("touchspin.updatesettings", getSettingsObj()) + } + + private fun getSettingsObj(): dynamic { + val verticalbuttons = buttonsType == BUTTONSTYPE.VERTICAL || buttonsType == BUTTONSTYPE.NONE + return obj { + this.min = min + this.max = max + this.step = step + this.decimals = decimals + this.verticalbuttons = verticalbuttons + this.forcestepdivisibility = forceType.value + } + } +} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractTextInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractTextInput.kt index 0303f5bd..88614774 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractTextInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractTextInput.kt @@ -1,5 +1,6 @@ package pl.treksoft.kvision.form.text +import com.github.snabbdom.VNode import pl.treksoft.kvision.core.Widget import pl.treksoft.kvision.form.INPUTSIZE import pl.treksoft.kvision.snabbdom.StringBoolPair @@ -98,6 +99,10 @@ abstract class AbstractTextInput(value: String? = null, return sn } + override fun afterInsert(node: VNode) { + refreshState() + } + protected open fun refreshState() { value?.let { getElementJQuery()?.`val`(it) diff --git a/src/main/kotlin/pl/treksoft/kvision/snabbdom/Types.kt b/src/main/kotlin/pl/treksoft/kvision/snabbdom/Types.kt index 1606e83a..62f8c239 100644 --- a/src/main/kotlin/pl/treksoft/kvision/snabbdom/Types.kt +++ b/src/main/kotlin/pl/treksoft/kvision/snabbdom/Types.kt @@ -52,6 +52,8 @@ interface BtOn : On { var changeDate: ((KvEvent) -> kotlin.Unit)? var showBsDateTime: ((KvEvent) -> kotlin.Unit)? var hideBsDateTime: ((KvEvent) -> kotlin.Unit)? + var onMinBsSpinner: ((KvEvent) -> kotlin.Unit)? + var onMaxBsSpinner: ((KvEvent) -> kotlin.Unit)? } interface SnOn<T> : BtOn { diff --git a/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerInputSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerInputSpec.kt new file mode 100644 index 00000000..8c90c684 --- /dev/null +++ b/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerInputSpec.kt @@ -0,0 +1,54 @@ +package test.pl.treksoft.kvision.form.spinner + +import pl.treksoft.kvision.core.Root +import pl.treksoft.kvision.form.spinner.SpinnerInput +import test.pl.treksoft.kvision.DomSpec +import kotlin.test.Test +import kotlin.test.assertEquals + +class SpinnerInputSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test") + val si = SpinnerInput(value = 13).apply { + placeholder = "place" + id = "idti" + } + root.add(si) + val value = si.getElementJQuery()?.`val`() + assertEquals("13", value, "Should render spinner input with correct value") + } + } + + @Test + fun spinUp() { + run { + val root = Root("test") + val si = SpinnerInput(value = 13).apply { + placeholder = "place" + id = "idti" + } + root.add(si) + assertEquals(13, si.value, "Should return initial value before spinUp") + si.spinUp() + assertEquals(14, si.value, "Should return changed value after spinUp") + } + } + + @Test + fun spinDown() { + run { + val root = Root("test") + val si = SpinnerInput(value = 13).apply { + placeholder = "place" + id = "idti" + } + root.add(si) + assertEquals(13, si.value, "Should return initial value before spinDown") + si.spinDown() + assertEquals(12, si.value, "Should return changed value after spinDown") + } + } +}
\ No newline at end of file diff --git a/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerSpec.kt new file mode 100644 index 00000000..b800f297 --- /dev/null +++ b/src/test/kotlin/test/pl/treksoft/kvision/form/spinner/SpinnerSpec.kt @@ -0,0 +1,53 @@ +package test.pl.treksoft.kvision.form.spinner + +import pl.treksoft.kvision.core.Root +import pl.treksoft.kvision.form.spinner.Spinner +import test.pl.treksoft.kvision.DomSpec +import kotlin.browser.document +import kotlin.test.Test +import kotlin.test.assertEquals + +class SpinnerSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test") + val ti = Spinner(value = 13, label = "Label").apply { + placeholder = "place" + name = "name" + disabled = true + } + root.add(ti) + val element = document.getElementById("test") + val id = ti.input.id + assertEquals("<div class=\"form-group\"><label class=\"control-label\" for=\"$id\">Label</label><div class=\"input-group kv-spinner-btn-vertical\"><span><div class=\"input-group bootstrap-touchspin\"><span class=\"input-group-addon bootstrap-touchspin-prefix\" style=\"display: none;\"></span><input class=\"form-control\" id=\"$id\" type=\"text\" value=\"13\" placeholder=\"place\" name=\"name\" disabled=\"\" style=\"display: block;\"><span class=\"input-group-addon bootstrap-touchspin-postfix\" style=\"display: none;\"></span><span class=\"input-group-btn-vertical\"><button class=\"btn btn-default bootstrap-touchspin-up\" type=\"button\"><i class=\"glyphicon glyphicon-chevron-up\"></i></button><button class=\"btn btn-default bootstrap-touchspin-down\" type=\"button\"><i class=\"glyphicon glyphicon-chevron-down\"></i></button></span></div></span></div></div>", element?.innerHTML, "Should render correct spinner input form control") + ti.validatorError = "Validation Error" + assertEquals("<div class=\"form-group has-error\"><label class=\"control-label\" for=\"$id\">Label</label><div class=\"input-group kv-spinner-btn-vertical\"><span><div class=\"input-group bootstrap-touchspin\"><span class=\"input-group-addon bootstrap-touchspin-prefix\" style=\"display: none;\"></span><input class=\"form-control\" id=\"$id\" type=\"text\" value=\"13\" placeholder=\"place\" name=\"name\" disabled=\"\" style=\"display: block;\"><span class=\"input-group-addon bootstrap-touchspin-postfix\" style=\"display: none;\"></span><span class=\"input-group-btn-vertical\"><button class=\"btn btn-default bootstrap-touchspin-up\" type=\"button\"><i class=\"glyphicon glyphicon-chevron-up\"></i></button><button class=\"btn btn-default bootstrap-touchspin-down\" type=\"button\"><i class=\"glyphicon glyphicon-chevron-down\"></i></button></span></div></span></div><span class=\"help-block small\">Validation Error</span></div>", element?.innerHTML, "Should render correct spinner input form control with validation error") + } + } + + @Test + fun spinUp() { + run { + val root = Root("test") + val si = Spinner(value = 13) + root.add(si) + assertEquals(13, si.value, "Should return initial value before spinUp") + si.spinUp() + assertEquals(14, si.value, "Should return changed value after spinUp") + } + } + + @Test + fun spinDown() { + run { + val root = Root("test") + val si = Spinner(value = 13) + root.add(si) + assertEquals(13, si.value, "Should return initial value before spinDown") + si.spinDown() + assertEquals(12, si.value, "Should return changed value after spinDown") + } + } +}
\ No newline at end of file diff --git a/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeInputSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeInputSpec.kt new file mode 100644 index 00000000..fe6c2b45 --- /dev/null +++ b/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeInputSpec.kt @@ -0,0 +1,28 @@ +package test.pl.treksoft.kvision.form.time + +import pl.treksoft.kvision.core.Root +import pl.treksoft.kvision.form.time.DateTimeInput +import pl.treksoft.kvision.utils.toStringF +import test.pl.treksoft.kvision.DomSpec +import kotlin.js.Date +import kotlin.test.Test +import kotlin.test.assertEquals + +class DateTimeInputSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test") + val data = Date() + val dti = DateTimeInput(value = data).apply { + placeholder = "place" + id = "idti" + } + root.add(dti) + val value = dti.getElementJQuery()?.`val`() + assertEquals(data.toStringF(dti.format), value, "Should render date time input with correctly formatted value") + } + } + +}
\ No newline at end of file diff --git a/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeSpec.kt new file mode 100644 index 00000000..1a8665b1 --- /dev/null +++ b/src/test/kotlin/test/pl/treksoft/kvision/form/time/DateTimeSpec.kt @@ -0,0 +1,34 @@ +package test.pl.treksoft.kvision.form.time + +import pl.treksoft.kvision.core.Root +import pl.treksoft.kvision.form.time.DateTime +import pl.treksoft.kvision.utils.toStringF +import test.pl.treksoft.kvision.DomSpec +import kotlin.browser.document +import kotlin.js.Date +import kotlin.test.Test +import kotlin.test.assertEquals + +class DateTimeSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test") + val data = Date() + val ti = DateTime(value = data, label = "Label").apply { + placeholder = "place" + name = "name" + disabled = true + } + root.add(ti) + val element = document.getElementById("test") + val id = ti.input.id + val datastr = data.toStringF(ti.format) + assertEquals("<div class=\"form-group\"><label class=\"control-label\" for=\"$id\">Label</label><input class=\"form-control\" id=\"$id\" type=\"text\" placeholder=\"place\" name=\"name\" disabled=\"\" value=\"$datastr\"></div>", element?.innerHTML, "Should render correct date time input form control") + ti.validatorError = "Validation Error" + assertEquals("<div class=\"form-group has-error\"><label class=\"control-label\" for=\"$id\">Label</label><input class=\"form-control\" id=\"$id\" type=\"text\" placeholder=\"place\" name=\"name\" disabled=\"\" value=\"$datastr\"><span class=\"help-block small\">Validation Error</span></div>", element?.innerHTML, "Should render correct date time input form control with validation error") + } + } + +}
\ No newline at end of file |