diff options
14 files changed, 349 insertions, 159 deletions
diff --git a/src/main/kotlin/pl/treksoft/kvision/Showcase.kt b/src/main/kotlin/pl/treksoft/kvision/Showcase.kt index afe49299..f1406505 100644 --- a/src/main/kotlin/pl/treksoft/kvision/Showcase.kt +++ b/src/main/kotlin/pl/treksoft/kvision/Showcase.kt @@ -4,14 +4,7 @@ import pl.treksoft.kvision.basic.Label import pl.treksoft.kvision.core.* import pl.treksoft.kvision.dropdown.DD.* import pl.treksoft.kvision.dropdown.DropDown -import pl.treksoft.kvision.form.CHECKBOXSTYLE -import pl.treksoft.kvision.form.CheckBox -import pl.treksoft.kvision.form.INPUTSIZE -import pl.treksoft.kvision.form.RADIOSTYLE -import pl.treksoft.kvision.form.Radio -import pl.treksoft.kvision.form.TEXTINPUTTYPE -import pl.treksoft.kvision.form.Text -import pl.treksoft.kvision.form.TextInput +import pl.treksoft.kvision.form.* import pl.treksoft.kvision.html.* import pl.treksoft.kvision.html.TAG.DIV import pl.treksoft.kvision.html.TAG.H1 @@ -90,6 +83,20 @@ class Showcase : ApplicationBase() { val text = Text(placeholder = "Pole formularza", maxlength = 5, label = "To jest pole") root.add(text) + val textareainput = TextAreaInput(cols = 5, rows = 2, placeholder = "...", value = "To jest tekst\nTo jest <b>te</b></textarea>kst2") + root.add(textareainput) + + val textarea = TextArea(cols = 5, rows = 2, placeholder = "...", value = "To jest tekst\nTo jest <b>te</b></textarea>kst2", label = "Pole długie") + root.add(textarea) + textarea.setEventListener<TextArea> { + input = { e -> + println("ta i" + self.value) + } + change = { e -> + println("ta c" + self.value) + } + } + val dd = DropDown("Dropdown", listOf("abc" to "#!/x", "def" to "#!/y"), "flag") root.add(dd) dd.setEventListener<DropDown> { diff --git a/src/main/kotlin/pl/treksoft/kvision/form/AbstractText.kt b/src/main/kotlin/pl/treksoft/kvision/form/AbstractText.kt new file mode 100644 index 00000000..98619dbc --- /dev/null +++ b/src/main/kotlin/pl/treksoft/kvision/form/AbstractText.kt @@ -0,0 +1,84 @@ +package pl.treksoft.kvision.form + +import pl.treksoft.kvision.core.Container +import pl.treksoft.kvision.core.Widget +import pl.treksoft.kvision.snabbdom.SnOn + +abstract class AbstractText(label: String? = null, rich: Boolean = false) : + Container(setOf("form-group")), StringFormField { + + override var value + get() = input.value + set(value) { + input.value = value + } + var startValue + get() = input.startValue + set(value) { + input.startValue = value + } + var placeholder + get() = input.placeholder + set(value) { + input.placeholder = value + } + var name + get() = input.name + set(value) { + input.name = value + } + var maxlength + get() = input.maxlength + set(value) { + input.maxlength = value + } + override var disabled + get() = input.disabled + set(value) { + input.disabled = 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_text_" + counter + internal abstract val input: AbstractTextInput + internal val flabel: FieldLabel = FieldLabel(idc, label, rich) + + init { + this.addInternal(flabel) + counter++ + } + + companion object { + var counter = 0 + } + + @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 + } +} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/AbstractTextInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/AbstractTextInput.kt new file mode 100644 index 00000000..4423d2d4 --- /dev/null +++ b/src/main/kotlin/pl/treksoft/kvision/form/AbstractTextInput.kt @@ -0,0 +1,105 @@ +package pl.treksoft.kvision.form + +import com.github.snabbdom.VNode +import pl.treksoft.kvision.core.Widget +import pl.treksoft.kvision.snabbdom.StringBoolPair +import pl.treksoft.kvision.snabbdom.StringPair + +abstract class AbstractTextInput(placeholder: String? = null, + override var value: String? = null, name: String? = null, maxlength: Int? = null, + disabled: Boolean = false, id: String? = null, + classes: Set<String> = setOf()) : Widget(classes + "form-control"), StringFormField { + init { + this.id = id + } + + @Suppress("LeakingThis") + var startValue: String? = value + set(value) { + field = value + this.value = value + refresh() + } + var placeholder: String? = placeholder + set(value) { + field = value + refresh() + } + var name: String? = name + set(value) { + field = value + refresh() + } + var maxlength: Int? = maxlength + set(value) { + field = value + refresh() + } + override var disabled: Boolean = disabled + set(value) { + field = value + refresh() + } + var autofocus: Boolean? = null + set(value) { + field = value + refresh() + } + var readonly: Boolean? = null + set(value) { + field = value + refresh() + } + override var size: INPUTSIZE? = null + set(value) { + field = value + refresh() + } + + override fun getSnClass(): List<StringBoolPair> { + val cl = super.getSnClass().toMutableList() + size?.let { + cl.add(it.className to true) + } + return cl + } + + @Suppress("ComplexMethod") + override fun getSnAttrs(): List<StringPair> { + val sn = super.getSnAttrs().toMutableList() + placeholder?.let { + sn.add("placeholder" to it) + } + name?.let { + sn.add("name" to it) + } + autofocus?.let { + if (it) { + sn.add("autofocus" to "autofocus") + } + } + maxlength?.let { + sn.add("maxlength" to ("" + it)) + } + readonly?.let { + if (it) { + sn.add("readonly" to "readonly") + } + } + if (disabled) { + sn.add("disabled" to "true") + } + return sn + } + + override fun afterInsert(node: VNode) { + this.getElementJQuery()?.on("input", { _, _ -> + val v = getElementJQuery()?.`val`() as String? + if (v != null && v.isNotEmpty()) { + value = v + } else { + value = null + } + }) + } +} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/CheckBox.kt b/src/main/kotlin/pl/treksoft/kvision/form/CheckBox.kt index 87963922..325c1982 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/CheckBox.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/CheckBox.kt @@ -94,6 +94,11 @@ open class CheckBox(value: Boolean = false, name: String? = null, style: CHECKBO return this } + override fun removeEventListeners(): Widget { + input.removeEventListeners() + return this + } + override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() style?.let { diff --git a/src/main/kotlin/pl/treksoft/kvision/form/Radio.kt b/src/main/kotlin/pl/treksoft/kvision/form/Radio.kt index f8db5162..eebbe65a 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/Radio.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/Radio.kt @@ -99,6 +99,11 @@ open class Radio(value: Boolean = false, extraValue: String? = null, name: Strin return this } + override fun removeEventListeners(): Widget { + input.removeEventListeners() + return this + } + override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() if (!squared) { diff --git a/src/main/kotlin/pl/treksoft/kvision/form/Text.kt b/src/main/kotlin/pl/treksoft/kvision/form/Text.kt index 0980099f..ce23974d 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/Text.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/Text.kt @@ -1,75 +1,24 @@ package pl.treksoft.kvision.form -import pl.treksoft.kvision.core.Container - open class Text(type: TEXTINPUTTYPE = TEXTINPUTTYPE.TEXT, placeholder: String? = null, value: String? = null, name: String? = null, maxlength: Int? = null, label: String? = null, rich: Boolean = false, - disabled: Boolean = false) : Container(setOf("form-group")), StringFormField { + disabled: Boolean = false) : AbstractText(label, rich) { - override var value - get() = input.value - set(value) { - input.value = value - } - var startValue - get() = input.startValue - set(value) { - input.startValue = value - } var type get() = input.type set(value) { input.type = value } - var placeholder - get() = input.placeholder - set(value) { - input.placeholder = value - } - var name - get() = input.name - set(value) { - input.name = value - } - var maxlength - get() = input.maxlength - set(value) { - input.maxlength = value - } - override var disabled - get() = input.disabled - set(value) { - input.disabled = value - } - var label - get() = flabel.text - set(value) { - flabel.text = value - } - var rich - get() = flabel.rich + var autocomplete + get() = input.autocomplete set(value) { - flabel.rich = value - } - override var size - get() = input.size - set(value) { - input.size = value + input.autocomplete = value } - private val idc = "kv_form_text_" + counter - internal val input: TextInput = TextInput(type, placeholder, value, name, maxlength, disabled, idc) - internal val flabel: FieldLabel = FieldLabel(idc, label, rich) + override final val input: TextInput = TextInput(type, placeholder, value, name, maxlength, disabled, idc) init { - this.addInternal(flabel) this.addInternal(input) - counter++ } - - companion object { - var counter = 0 - } - } diff --git a/src/main/kotlin/pl/treksoft/kvision/form/TextArea.kt b/src/main/kotlin/pl/treksoft/kvision/form/TextArea.kt new file mode 100644 index 00000000..2efa99c9 --- /dev/null +++ b/src/main/kotlin/pl/treksoft/kvision/form/TextArea.kt @@ -0,0 +1,28 @@ +package pl.treksoft.kvision.form + +open class TextArea(cols: Int? = null, rows: Int? = null, placeholder: String? = null, value: String? = null, + name: String? = null, maxlength: Int? = null, label: String? = null, rich: Boolean = false, + disabled: Boolean = false) : AbstractText(label, rich) { + + var cols + get() = input.cols + set(value) { + input.cols = value + } + var rows + get() = input.rows + set(value) { + input.rows = value + } + var wrapHard + get() = input.wrapHard + set(value) { + input.wrapHard = value + } + + override final val input: TextAreaInput = TextAreaInput(cols, rows, placeholder, value, name, maxlength, disabled, idc) + + init { + 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 new file mode 100644 index 00000000..35961285 --- /dev/null +++ b/src/main/kotlin/pl/treksoft/kvision/form/TextAreaInput.kt @@ -0,0 +1,47 @@ +package pl.treksoft.kvision.form + +import com.github.snabbdom.VNode +import pl.treksoft.kvision.snabbdom.StringPair + +class TextAreaInput(cols: Int? = null, rows: Int? = null, placeholder: String? = null, + value: String? = null, name: String? = null, maxlength: Int? = null, + disabled: Boolean = false, id: String? = null, classes: Set<String> = setOf()) : + AbstractTextInput(placeholder, value, name, maxlength, disabled, id, classes) { + + var cols: Int? = cols + set(value) { + field = value + refresh() + } + var rows: Int? = rows + set(value) { + field = value + refresh() + } + var wrapHard: Boolean = false + set(value) { + field = value + refresh() + } + + override fun render(): VNode { + return value?.let { + kvh("textarea", arrayOf(it)) + } ?: kvh("textarea") + } + + @Suppress("ComplexMethod") + override fun getSnAttrs(): List<StringPair> { + val sn = super.getSnAttrs().toMutableList() + cols?.let { + sn.add("cols" to ("" + it)) + } + rows?.let { + sn.add("rows" to ("" + it)) + } + if (wrapHard) { + sn.add("wrap" to "hard") + } + return sn + } +} diff --git a/src/main/kotlin/pl/treksoft/kvision/form/TextInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/TextInput.kt index 08a39e87..6cf0f239 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/TextInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/TextInput.kt @@ -1,8 +1,6 @@ package pl.treksoft.kvision.form import com.github.snabbdom.VNode -import pl.treksoft.kvision.core.Widget -import pl.treksoft.kvision.snabbdom.StringBoolPair import pl.treksoft.kvision.snabbdom.StringPair enum class TEXTINPUTTYPE(val type: String) { @@ -11,92 +9,32 @@ enum class TEXTINPUTTYPE(val type: String) { } class TextInput(type: TEXTINPUTTYPE = TEXTINPUTTYPE.TEXT, placeholder: String? = null, - override var value: String? = null, name: String? = null, maxlength: Int? = null, - disabled: Boolean = false, id: String? = null, - classes: Set<String> = setOf()) : Widget(classes + "form-control"), StringFormField { - init { - this.id = id - } + value: String? = null, name: String? = null, maxlength: Int? = null, + disabled: Boolean = false, id: String? = null, classes: Set<String> = setOf()) : + AbstractTextInput(placeholder, value, name, maxlength, disabled, id, classes) { - @Suppress("LeakingThis") - var startValue: String? = value - set(value) { - field = value - this.value = value - refresh() - } var type: TEXTINPUTTYPE = type set(value) { field = value refresh() } - var placeholder: String? = placeholder - set(value) { - field = value - refresh() - } - var name: String? = name - set(value) { - field = value - refresh() - } - var maxlength: Int? = maxlength - set(value) { - field = value - refresh() - } - override var disabled: Boolean = disabled - set(value) { - field = value - refresh() - } - var autocomplete: Boolean? = null set(value) { field = value refresh() } - var autofocus: Boolean? = null - set(value) { - field = value - refresh() - } - var readonly: Boolean? = null - set(value) { - field = value - refresh() - } - override var size: INPUTSIZE? = null - set(value) { - field = value - refresh() - } 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 - } - @Suppress("ComplexMethod") override fun getSnAttrs(): List<StringPair> { val sn = super.getSnAttrs().toMutableList() sn.add("type" to type.type) - placeholder?.let { - sn.add("placeholder" to it) - } startValue?.let { sn.add("value" to it) } - name?.let { - sn.add("name" to it) - } autocomplete?.let { if (it) { sn.add("autocomplete" to "on") @@ -104,33 +42,6 @@ class TextInput(type: TEXTINPUTTYPE = TEXTINPUTTYPE.TEXT, placeholder: String? = sn.add("autocomplete" to "off") } } - autofocus?.let { - if (it) { - sn.add("autofocus" to "autofocus") - } - } - maxlength?.let { - sn.add("maxlength" to ("" + it)) - } - readonly?.let { - if (it) { - sn.add("readonly" to "readonly") - } - } - if (disabled) { - sn.add("disabled" to "true") - } return sn } - - override fun afterInsert(node: VNode) { - this.getElementJQuery()?.on("input", { _, _ -> - val v = getElementJQuery()?.`val`() as String? - if (v != null && v.isNotEmpty()) { - value = v - } else { - value = null - } - }) - } } diff --git a/src/test/kotlin/test/pl/treksoft/kvision/form/PasswordSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/form/PasswordSpec.kt index 4563da03..b03112a7 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/form/PasswordSpec.kt +++ b/src/test/kotlin/test/pl/treksoft/kvision/form/PasswordSpec.kt @@ -19,7 +19,7 @@ class PasswordSpec : DomSpec { root.add(ti) val element = document.getElementById("test") val id = ti.input.id - assertEquals("<div class=\"form-group\"><label for=\"$id\">Label</label><input class=\"form-control\" id=\"$id\" type=\"password\" placeholder=\"place\" value=\"abc\" name=\"name\" maxlength=\"15\" disabled=\"\"></div>", element?.innerHTML, "Should render correct input form field") + assertEquals("<div class=\"form-group\"><label for=\"$id\">Label</label><input class=\"form-control\" id=\"$id\" placeholder=\"place\" name=\"name\" maxlength=\"15\" disabled=\"\" type=\"password\" value=\"abc\"></div>", element?.innerHTML, "Should render correct input form field") } } diff --git a/src/test/kotlin/test/pl/treksoft/kvision/form/TextAreaInputSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/form/TextAreaInputSpec.kt new file mode 100644 index 00000000..630a0eed --- /dev/null +++ b/src/test/kotlin/test/pl/treksoft/kvision/form/TextAreaInputSpec.kt @@ -0,0 +1,24 @@ +package test.pl.treksoft.kvision.form + +import pl.treksoft.kvision.core.Root +import pl.treksoft.kvision.form.TextAreaInput +import test.pl.treksoft.kvision.DomSpec +import kotlin.browser.document +import kotlin.test.Test +import kotlin.test.assertEquals + +class TextAreaInputSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test") + val ti = TextAreaInput(cols = 5, rows = 2, placeholder = "place", value = "abc", name = "name", + maxlength = 15, id = "idti", disabled = true) + root.add(ti) + val element = document.getElementById("test") + assertEquals("<textarea class=\"form-control\" id=\"idti\" placeholder=\"place\" name=\"name\" maxlength=\"15\" disabled=\"\" cols=\"5\" rows=\"2\">abc</textarea>", element?.innerHTML, "Should render correct input field") + } + } + +}
\ No newline at end of file diff --git a/src/test/kotlin/test/pl/treksoft/kvision/form/TextAreaSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/form/TextAreaSpec.kt new file mode 100644 index 00000000..e422ac2b --- /dev/null +++ b/src/test/kotlin/test/pl/treksoft/kvision/form/TextAreaSpec.kt @@ -0,0 +1,25 @@ +package test.pl.treksoft.kvision.form + +import pl.treksoft.kvision.core.Root +import pl.treksoft.kvision.form.TextArea +import test.pl.treksoft.kvision.DomSpec +import kotlin.browser.document +import kotlin.test.Test +import kotlin.test.assertEquals + +class TextAreaSpec : DomSpec { + + @Test + fun render() { + run { + val root = Root("test") + val ti = TextArea(cols = 5, rows = 2, placeholder = "place", value = "abc", name = "name", + maxlength = 15, disabled = true, label = "Label") + root.add(ti) + val element = document.getElementById("test") + val id = ti.input.id + assertEquals("<div class=\"form-group\"><label for=\"$id\">Label</label><textarea class=\"form-control\" id=\"$id\" placeholder=\"place\" name=\"name\" maxlength=\"15\" disabled=\"\" cols=\"5\" rows=\"2\">abc</textarea></div>", element?.innerHTML, "Should render correct input form field") + } + } + +}
\ No newline at end of file diff --git a/src/test/kotlin/test/pl/treksoft/kvision/form/TextInputSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/form/TextInputSpec.kt index 55325436..9e5ed64d 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/form/TextInputSpec.kt +++ b/src/test/kotlin/test/pl/treksoft/kvision/form/TextInputSpec.kt @@ -18,7 +18,7 @@ class TextInputSpec : DomSpec { maxlength = 15, id = "idti", disabled = true) root.add(ti) val element = document.getElementById("test") - assertEquals("<input class=\"form-control\" id=\"idti\" type=\"password\" placeholder=\"place\" value=\"abc\" name=\"name\" maxlength=\"15\" disabled=\"\">", element?.innerHTML, "Should render correct input field") + assertEquals("<input class=\"form-control\" id=\"idti\" placeholder=\"place\" name=\"name\" maxlength=\"15\" disabled=\"\" type=\"password\" value=\"abc\">", element?.innerHTML, "Should render correct input field") } } diff --git a/src/test/kotlin/test/pl/treksoft/kvision/form/TextSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/form/TextSpec.kt index 5e378d55..675d9db8 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/form/TextSpec.kt +++ b/src/test/kotlin/test/pl/treksoft/kvision/form/TextSpec.kt @@ -18,7 +18,7 @@ class TextSpec : DomSpec { root.add(ti) val element = document.getElementById("test") val id = ti.input.id - assertEquals("<div class=\"form-group\"><label for=\"$id\">Label</label><input class=\"form-control\" id=\"$id\" type=\"text\" placeholder=\"place\" value=\"abc\" name=\"name\" maxlength=\"15\" disabled=\"\"></div>", element?.innerHTML, "Should render correct input form field") + assertEquals("<div class=\"form-group\"><label for=\"$id\">Label</label><input class=\"form-control\" id=\"$id\" placeholder=\"place\" name=\"name\" maxlength=\"15\" disabled=\"\" type=\"text\" value=\"abc\"></div>", element?.innerHTML, "Should render correct input form field") } } |