mvysny / vaadin-on-kotlin

Writing full-stack statically-typed web apps on JVM at its simplest
https://www.vaadinonkotlin.eu/
MIT License
186 stars 17 forks source link

Use DatePicker or TimePicker as FilterBar component #49

Closed jhult closed 4 years ago

jhult commented 4 years ago

I want to use a Vaadin Date Picker component as a FilterBar component. An example is below:

image

For me, the goal is to let a user pick a date and the Grid results are then filtered from midnight to 11:59 PM.

Here is code that I am currently using to accomplish this:

fun <BEAN : Any, FILTER : Filter<BEAN>> FilterBar<BEAN, FILTER>.datePicker(column: Grid.Column<BEAN>): FilterBar.Binding<BEAN, FILTER> {
    require(!column.key.isNullOrBlank()) { "The column needs to have the property name as its key" }
    val component = DatePicker().apply {
        max = LocalDate.now()
        isClearButtonVisible = true
        setWidthFull()
    }
    return FilterBar.Binding.Builder(filterFactory, this, column, component) {
        // value getter
        component.value
    }.withConverter {
        DateInterval(it, it).toFilter(column.key, filterFactory, LocalDateTime::class.java)
    }.bind()
}

I was unable to use the following:

A similar request would be for Vaadin Time Picker.

jhult commented 4 years ago

Originally discussed in #45.

mvysny commented 4 years ago

Implemented support for day matching:

data class Person(var dob: LocalDateTime)

val grid = Grid<Person>(Person::class.java)
val filterBar: VokFilterBar<Person> = grid.appendHeaderRow().asFilterBar(grid)
filterBar.forField(DatePicker(), grid.getColumnBy(Person::dob)).onDay(LocalDateTime::class)

It's not as straightforward as your approach, but you will be able to simplify the function quite a lot now:

fun <BEAN : Any, FILTER : Filter<BEAN>> FilterBar<BEAN, FILTER>.datePicker(column: Grid.Column<BEAN>): FilterBar.Binding<BEAN, FILTER> {
    // require(!column.key.isNullOrBlank()) { "The column needs to have the property name as its key" } // - no need, forField() checks this automatically
    val component = DatePicker().apply {
        max = LocalDate.now()
        // isClearButtonVisible = true // no need, FilterBar.configure() does this automatically.
        // setWidthFull() // no need, FilterBar.configure() does this automatically.
    }
    return forField(component, column).onDay(LocalDateTime::class)
}
jhult commented 4 years ago

@mvysny, this works great. Thank you!

mvysny commented 4 years ago

Awesome, thank you for trying it out :+1:

I've documented the new FilterBar binding mechanism a bit here: https://github.com/mvysny/vaadin-on-kotlin/tree/master/vok-util-vaadin10

Please let me know if there's anything unclear and I'll try to improve the docs; or make the changes straight away in a PR :+1: