# Customizations
# Custom Row Template
Sometimes you might want to customize exactly how rows are displayed in a table. Vue-good-table also supports dynamic td templates where you dictate how to display the cells. Example:
<vue-good-table
:columns="columns"
:rows="rows">
<template slot="table-row" slot-scope="props">
<span v-if="props.column.field == 'age'">
<span style="font-weight: bold; color: blue;">{{props.row.age}}</span>
</span>
<span v-else>
{{props.formattedRow[props.column.field]}}
</span>
</template>
</vue-good-table>
# Result
| Name | Age | Created On | Percent |
|---|---|---|---|
| John | 20 | Jul 2nd 11 | 3.34% |
| Jane | 24 | Oct 31st 11 | 3.34% |
| Susan | 16 | Oct 30th 11 | 3.34% |
NOTE
- The original row object can be accessed via
props.row - The currently displayed table row index can be accessed via
props.index. - The original row index can be accessed via
props.row.originalIndex. You can then access the original row object by usingrows[props.row.originalIndex]. - The column object can be accessed via
props.column - You can access the formatted row data (for example - formatted date) via
props.formattedRow
# Adding custom columns
Sometimes you might want to add columns to the table that are not part of your row data. Maybe before or after the other columns.
<vue-good-table
:columns="columns"
:rows="rows">
<template slot="table-row" slot-scope="props">
<span v-if="props.column.field == 'before'">
before
</span>
<span v-else-if="props.column.field == 'after'">
after
</span>
<span v-else>
{{props.formattedRow[props.column.field]}}
</span>
</template>
</vue-good-table>
keep in mind that you'll need to add the custom columns to your column definition.
{
label: 'Before',
field: 'before'
},
{
label: 'After',
field: 'after'
},
# Result
| Before | Name | Age | Created On | Percent | After |
|---|---|---|---|---|---|
| before | John | 20 | Jul 2nd 11 | 3.34% | after |
| before | Jane | 24 | Oct 31st 11 | 3.34% | after |
| before | Susan | 16 | Oct 30th 11 | 3.34% | after |
# Custom column headers
Sometimes you might want to customize column headers. You can do that in the following way
<vue-good-table
:columns="columns"
:rows="rows">
<template slot="table-column" slot-scope="props">
<span v-if="props.column.label =='Name'">
<i class="fa fa-address-book"></i> {{props.column.label}}
</span>
<span v-else>
{{props.column.label}}
</span>
</template>
</vue-good-table>
# Custom column filters
Sometimes you might want a custom filter. You can do that in the following way:
<vue-good-table
:columns="columns"
:rows="rows">
<template slot="column-filter" slot-scope="props">
<my-custom-filter
v-if="props.column.filterOptions.customFilter"
@input="handleCustomFilter"/>
</template>
</vue-good-table>
Add a custom property in your columns to conditionally render the custom-filter slot where needed.
columns: [
{
label: 'Name',
field: 'name'
},
{
label: 'Category',
field: 'category'
},
{
label: 'Statistics',
field: 'statistics',
filterOptions: {
customFilter: true
}
}
]
// in your methods
handleCustomFilter(value) {
// filtering logic here
}
You can add a function to handle the filtering logic in your own component, or optionally updateFilters can be used.
The updateFilters method is in vue-good-table and will include your custom filter value with the other column filters.
You can also provide a function to formatValue inside of filterOptions to transform the value before filtering on it.
<vue-good-table
:columns="columns"
:rows="rows">
<template slot="column-filter" slot-scope="{ column, updateFilters }">
<my-custom-filter
v-if="column.filterOptions.customFilter"
@input="(value) => updateFilters(column, value)"/>
</template>
</vue-good-table>
In your columns, you may want to display the value from one property but need to filter on another.
If you set a slotFilterField in your filterOptions, that property will be used for the custom filter slot.
{
label: 'Name',
field: 'name.displayName',
filterOptions: {
customFilter: true,
slotFilterField: 'name.id',
formatValue: function (value) {
return valueArray.join(',');
}
}
}
Note the formatValue function. This is where you can provide formatting logic to transform your filter value.
# Upgrading from versions 2.20.0-2.21.0
Older versions of vue-good-table included a built-in multiselect filter.
If you upgrade to the latest version and would still like to use this filter, follow these steps:
- Install and set up
vue-selectin your project, follwing the guide at https://vue-select.org.
<v-select
:options="optionList"
multiple
@input="(value) => updateFilters(column, value)"
/>
- Make sure to set the
multipleattribute for a multiselect filter. - Set an array of options on the
optionsattribute ofv-select. If you were using the built in multiselect filter, move them from the column propertyfilterOptions.multiSelectDropdownItems. vue-selectemits an array of values when set tomultiple. To convert the array of data into a comma separated string or another format, provide a function onfilterOptions.formatValue.
<v-select
:options="optionList"
label="name"
multiple
@input="(valuesArray) => updateFilters(column, valuesArray)"
/>
// vue-select emits an array of any objects selected in the dropdown
// which is being converted to a string of ids to pass into the column filter value
data: {
optionList: [
{
name: 'Joan',
id: 1
},
{
name: 'Don',
id: 2
}
],
columns: [
{
label: 'name',
field: 'name',
filterOptions: {
enabled: true,
customFilter: true,
formatValue: this.formatFilterValue
}
}
]
},
methods: {
formatFilterValue(valuesArray) {
return valuesArray.map((value) => value.id).join(',');
}
}
:::
# Custom pagination
Sometimes you might want to customize the pagination. You can do that in the following way:
<vue-good-table
:columns="columns"
:rows="rows"
:pagination-options="{enabled: true}">
<template slot="pagination-bottom" slot-scope="props">
<custom-pagination
:total="props.total"
:pageChanged="props.pageChanged"
:perPageChanged="props.perPageChanged">
</custom-pagination>
</template>
</vue-good-table>
// within your <custom-pagination> component
props: {
pageChanged: {
type: Function,
},
perPageChanged: {
type: Function,
},
}
// and...
methods: {
customPageChange(customCurrentPage) {
this.pageChanged({currentPage: customCurrentPage});
},
customPerPageChange(customPerPage) {
this.perPageChanged({currentPerPage: customPerPage});
}
}
WARNING
You will have to implement your own pagination system:
- The total number of rows can be accessed via
props.total - The function to call when the current page has changed can be accessed via
props.pageChanged. - The function to call when the per page value has changed can be accessed via
props.perPageChanged.