KVision Tabulator component is based on awesome Tabulator library. It allows you to create interactive and reactive tables, with advanced sorting, filtering and editing capabilities. Tabulator component can be integrated with ObservableList<T> or Redux store and will automatically react to all changes in your data model. This component is contained in kvision-tabulator
module (you need to apply TabulatorModule
initializer and also one of CSS module initializers - see modules). KVision adds Kotlin type-safe bindings for most of Tabulator API but you should get familiar with Tabulator documentation to achieve best results.
{% hint style="info" %} Note: At the moment these functionalities are not supported: grouping, column calculations, download. Please fill a feature request if you require any of these. {% endhint %}
To create a table use io.kvision.tabulator.Tabulator
class. Although all constructor parameters have default values, you will usually want to specify Tabulator options with io.kvision.tabulator.TabulatorOptions
object . The table data can be specified in a few different ways - with local Kotlin collection, local JavaScript array or remote AJAX URL. The table component can be made reactive for all types of local data.
Data classes are preferred objects representing a single row data.
@Serializable
data class Book(val title: String, val author: String, val year: Int, val rating: Int)
val model = listOf(
Book("Fairy tales", "Hans Christian Andersen", 1836, 4),
Book("Don Quijote De La Mancha", "Miguel de Cervantes", 1610, 4),
Book("Crime and Punishment", "Fyodor Dostoevsky", 1866, 3),
Book("In Search of Lost Time", "Marcel Proust", 1920, 5)
)
tabulator(
model, options = TabulatorOptions(
layout = Layout.FITCOLUMNS,
columns = listOf(
ColumnDefinition("Title", "title"),
ColumnDefinition("Author", "author"),
ColumnDefinition("Year", "year"),
ColumnDefinition("Rating", "rating", formatter = Formatter.STAR)
)
), serializer = serializer()
) {
height = 400.px
}
To make the Tabulator component reactive just can use ObservableList
for your model. You can also use Redux store as a table data source.
You should use Any
as your Tabulator type parameter and leave both data
and dataSerializer
constructor parameters with null
values. You pass a reference to native JS array with a data
parameter inside your TabulatorOptions
object.
val model = JSON.parse<dynamic>(
"[{\"title\":\"Fairy tales\", \"author\":\"Hans Christian Andersen\", \"year\":1836, \"rating\":4}," +
"{\"title\":\"Don Quijote De La Mancha\", \"author\":\"Miguel de Cervantes\", \"year\":1610, \"rating\":4}," +
"{\"title\":\"Crime and Punishment\", \"author\": \"Fyodor Dostoevsky\", \"year\": 1866, \"rating\": 3}," +
"{\"title\":\"In Search of Lost Time\", \"author\":\"Marcel Proust\", \"year\":1920, \"rating\":5}]"
)
tabulator(TabulatorOptions(
layout = Layout.FITCOLUMNS,
columns = listOf(
ColumnDefinition("Title", "title"),
ColumnDefinition("Author", "author"),
ColumnDefinition("Year", "year"),
ColumnDefinition("Rating", "rating", formatter = Formatter.STAR)
), data = model
)
) {
height = 400.px
}
To make the Tabulator component reactive use reactiveData = true
parameter inside your TabulatorOptions
object.
Tabulator tables can get the data from the remote endpoint. You can find more information about available options in the Tabulator documentation. All these options, including ajax sorting, pagination and filtering can be used with KVision component.
tabulator(
TabulatorOptions(
ajaxURL = "/remote/tableData",
ajaxConfig = "POST",
ajaxContentType = "json",
filterMode = FilterMode.REMOTE,
sortMode = SortMode.REMOTE,
pagination = true,
paginationMode = PaginationMode.REMOTE,
layout = Layout.FITCOLUMNS,
columns = listOf(
ColumnDefinition("Title", "title"),
ColumnDefinition("Author", "author"),
ColumnDefinition("Year", "year"),
ColumnDefinition("Rating", "rating", formatter = Formatter.STAR)
)
)
) {
height = 400.px
}
You can use many different formatters to present the data in the tabulator cells. Just pass the desired Formatter
as a formatter
parameter in ColumnDefinition
.
val model = listOf(
Book("Fairy tales", "Hans Christian Andersen", 1836, 4),
Book("Don Quijote De La Mancha", "Miguel de Cervantes", 1610, 4),
Book("Crime and Punishment", "Fyodor Dostoevsky", 1866, 3),
Book("In Search of Lost Time", "Marcel Proust", 1920, 5)
)
val tabulator = tabulator(
model, options = TabulatorOptions(
layout = Layout.FITCOLUMNS,
columns = listOf(
ColumnDefinition("Title", "title"),
ColumnDefinition("Author", "author"),
ColumnDefinition("Year", "year"),
ColumnDefinition("Rating", "rating", formatter = Formatter.STAR)
)
), serializer = serializer()
) {
height = 400.px
}
Tabulator currently supports the following built-in formatter types: Formatter.PLAINTEXT
, Formatter.TEXTAREA
, Formatter.HTML
, Formatter.MONEY
, Formatter.IMAGE
, Formatter.LINK
, Formatter.DATETIME
, Formatter.DATATIMEDIFF
, Formatter.TICKCROSS
, Formatter.COLOR
, Formatter.STAR
, Formatter.TRAFFIC
, Formatter.PROGRESS
, Formatter.LOOKUP
, Formatter.BUTTONTICK
, Formatter.BUTTONCROSS
, Formatter.ROWNUM
, Formatter.HANDLE
. You can find more information about formatters configuration in the Tabulator docs.
{% hint style="info" %}
Note: You need to include Luxon library to your index.html
to use built-in date/time formatters.
{% endhint %}
You can use any KVision components to display data in Tabulator cells. You define the component with the formatterComponentFunction
property of the ColumnDefinition
class. When the Tabulator component is bound to the Kotlin data source, this function gives you also direct and type-safe access to the Kotlin data model for the current row.
@Serializable
data class Employee(
val name: String?,
val position: String?,
val office: String?,
val active: Boolean = false,
val startDate: Date?,
val salary: Int?
)
// ...
val model = mutableListOf<Employee>()
// ...
tabulator(model, options = TabulatorOptions(layout = Layout.FITCOLUMNS,
columns = listOf(
// ...
ColumnDefinition(
"Start date",
"startDate", formatterComponentFunction = { _, _, data: Employee ->
Span(data.startDate?.toStringF("YYYY-MM-DD"))
}
)
)
// ...
), serializar = serializer())
Tabulator component allows you to filter the data with external, fully type-safe Kotlin code. You can set the filtering function with setFilter
method, and then use applyFilter
after the condition change (e.g. after search input value change).
val model = listOf(
Book("Fairy tales", "Hans Christian Andersen", 1836, 4),
Book("Don Quijote De La Mancha", "Miguel de Cervantes", 1610, 4),
Book("Crime and Punishment", "Fyodor Dostoevsky", 1866, 3),
Book("In Search of Lost Time", "Marcel Proust", 1920, 5)
)
val search = textInput(TextInputType.SEARCH) {
placeholder = "Search ..."
}
val tabulator = tabulator(
model, options = TabulatorOptions(
layout = Layout.FITCOLUMNS,
columns = listOf(
ColumnDefinition("Title", "title"),
ColumnDefinition("Author", "author"),
ColumnDefinition("Year", "year"),
ColumnDefinition("Rating", "rating", formatter = Formatter.STAR)
)
), serializer = serializer()
) {
height = 400.px
setFilter { book ->
search.value?.let { book.author.contains(it) || book.title.contains(it) } ?: true
}
}
search.onEvent {
input = {
tabulator.applyFilter()
}
}
Tabulator also allows you to edit the values in each cell according to a user specified Editor
type. Just pass the desired Editor
as an editor
parameter in ColumnDefinition
.
val model = listOf(
Book("Fairy tales", "Hans Christian Andersen", 1836, 4),
Book("Don Quijote De La Mancha", "Miguel de Cervantes", 1610, 4),
Book("Crime and Punishment", "Fyodor Dostoevsky", 1866, 3),
Book("In Search of Lost Time", "Marcel Proust", 1920, 5)
)
val tabulator = tabulator(
model, options = TabulatorOptions(
layout = Layout.FITCOLUMNS,
columns = listOf(
ColumnDefinition("Title", "title", editor = Editor.INPUT),
ColumnDefinition("Author", "author", editor = Editor.INPUT),
ColumnDefinition("Year", "year", editor = Editor.NUMBER),
ColumnDefinition("Rating", "rating", formatter = Formatter.STAR, editor = Editor.STAR)
)
), serializer = serializer()
) {
height = 400.px
}
Tabulator currently supports the following built-in editor types: Editor.INPUT
, Editor.TEXTAREA
, Editor.NUMBER
, Editor.RANGE
, Editor.TICK
, Editor.STAR
, Editor.SELECT
and Editor.AUTOCOMPLETE
You can use most of KVision components to edit data in Tabulator cells. You define the component with the editorComponentFunction
property of the ColumnDefinition
class. When the Tabulator component is bound to the Kotlin data source, this function gives you also direct and type-safe access to the Kotlin data model for the current row.
@Serializable
data class Employee(
val name: String?,
val position: String?,
val office: String?,
val active: Boolean = false,
val startDate: Date?,
val salary: Int?
)
// ...
val model = mutableListOf<Employee>()
// ...
tabulator(model, options = TabulatorOptions(layout = Layout.FITCOLUMNS,
columns = listOf(
// ...
ColumnDefinition(
"Start date",
"startDate", editorComponentFunction = { _, _, success, _, data: Employee ->
DateTimeInput(value = data.startDate, format = "YYYY-MM-DD").apply {
size = InputSize.SMALL
clearBtn = false
onEvent {
change = {
success(self.value?.toStringF())
}
}
}
})
)
// ...
), serializer = serializer())
When using editable table with Tabulator component bound to Kotlin MutableList
data model, the changed data is automatically updated in the model. You can disable this function by setting dataUpdateOnEdit
Tabulator constructor parameter to false
.