Hi, I have a question. Is there an easier way to...
# kvision
k
Hi, I have a question. Is there an easier way to convert the Select component (with multiple=true) into a Tag Input?
r
what do you mean?
k
not with free text, but selectable from options.
r
I don't think you can get Tags input control with current KVision components
You need to create new component. There are probably some options available which could be used for this.
k
Please let me know if you know any options.. I initially tried using select2 component, but I was stuck with binding the value, and css bits of it..
r
Took me some experiments but seems to work ;-)
build.gradle.kts:
Copy code
sourceSets["main"].dependencies {
        implementation(npm("typeahead.js","0.11.1"))
        implementation(npm("bootstrap4-tagsinput-umd","1.0.2"))
        implementation("io.kvision:kvision:$kvisionVersion")
        implementation("io.kvision:kvision-bootstrap:$kvisionVersion")
        implementation("io.kvision:kvision-bootstrap-css:$kvisionVersion")
        implementation("io.kvision:kvision-i18n:$kvisionVersion")
    }
App.kt:
Copy code
class App : Application() {
    init {
        require("bootstrap4-tagsinput-umd/tagsinput.css")
        require("bootstrap4-tagsinput-umd/tagsinput.js")
        require("typeahead.js")
    }

    override fun start() {
        root("kvapp") {
            val sources = listOf("Amsterdam", "Washington", "Sydney", "Beijing", "Cairo")
            val sourceFun = { query: String?, callback: (Array<String>) -> Unit ->
                callback(sources.filter { it.startsWith(query ?: "", ignoreCase = true) }.toTypedArray())
            }
            val options = obj {
                typeaheadjs = arrayOf(obj {}, obj {
                    name = "names"
                    source = sourceFun
                })
                freeInput = false
            }
            vPanel(spacing = 3) {
                width = 100.perc
                padding = 10.px
                val tagsInput = textInput {
                    addAfterInsertHook {
                        getElementJQueryD().tagsinput(options)
                    }
                }
                button("Print values").onClick {
                    println(tagsInput.getElementJQuery()?.`val`()?.toString()?.split(","))
                }
            }
        }
    }
}
k
awesome.. Maybe we can include this as kvision component. I was actually trying something like this...
Copy code
inputTag(){
    id :String
    name :String
    freeInput :Boolean
    src : List<String>
    ignoreCase :Boolean
    containsOrStartswith:
}
or inject options directly.. Thank you for the support..
one more thing on that, I could not bind it like this..
Copy code
add(
    //MyObject::listOfStringType,
    TextInput {
        id = "category-input-tag"
        addAfterInsertHook {
            getElementJQueryD().tagsinput(options)
        }
    }
)
even setting value doesn't work:
Copy code
add(
    //MyObject::listOfStringType,
    TextInput {
        id = "category-input-tag"
        value= myobjectInstance.listOfStringType?.joinToString { "," }
        addAfterInsertHook {
            getElementJQueryD().tagsinput(options)
        }
    }
)
My bad, the joinString is wrong in the value, Setting the "value" works. but I need to set to the formdata manually. while submitting, as the binding doesn't compile.
r
You need to use
Text
instead of
TextInput
. Should work with this:
Copy code
Text(label = "Tags:") {
                    input.addAfterInsertHook {
                        input.getElementJQueryD().tagsinput(options)
                    }
                }
k
TextInput with value= setting works fine..
Copy code
add(
    //MyObject::myAtribute,
    TextInput {
        id = "category-input-tag"
        value = valueAsCommaDelimitedString
        addAfterInsertHook {
            getElementJQueryD().tagsinput(options)
        }
    }
)
this works
but do you mean the MyObject::myattribute will work only with Text ?
r
Yes
k
ah I see.. cheers