# 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-select
in 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
multiple
attribute for a multiselect filter. - Set an array of options on the
options
attribute ofv-select
. If you were using the built in multiselect filter, move them from the column propertyfilterOptions.multiSelectDropdownItems
. vue-select
emits 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
.