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 #table-row="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 #table-row="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 #table-column="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 #column-filter="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 #column-filter="{ 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 to- multiple. To convert the array of data into a comma separated string or another format, provide a function on- filterOptions.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 #pagination-bottom="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.
