diff --git a/404.html b/404.html new file mode 100644 index 00000000..93997026 --- /dev/null +++ b/404.html @@ -0,0 +1,43 @@ + + +
+ + + + + +One of the most common customizations in datatables is selectable rows. Creating a checkbox table with vue-good-table is easier than ever.
type: Object
Object containing select options
<vue-good-table
+ v-on:selected-rows-change="selectionChanged"
+ :columns="columns"
+ :rows="rows"
+ :select-options="{
+ enabled: true,
+ selectOnCheckboxOnly: true, // only select when checkbox is clicked instead of the row
+ selectionInfoClass: 'custom-class',
+ selectionText: 'rows selected',
+ clearSelectionText: 'clear',
+ disableSelectInfo: true, // disable the select info panel on top
+ selectAllByGroup: true, // when used in combination with a grouped table, add a checkbox in the header row to check/uncheck the entire group
+ alwaysShowSelectionInfo: false, // always show the row count, even when nothing is selected
+ }">
+
Although, the on-selected-rows-change
event should be enough for you to keep track of selected rows. If at any time you need to know what rows are selected, you can get it via ref.
this.$refs['my-table'].selectedRows;
+
<vue-good-table
+ v-on:selected-rows-change="selectionChanged"
+ :columns="columns"
+ :rows="rows"
+ :select-options="{ enabled: true }"
+ :search-options="{ enabled: true }">
+</vue-good-table>
+
Once you select a row, an info bar shows up. This bar allows for a customizable slot for your action buttons.
<vue-good-table
+ v-on:selected-rows-change="selectionChanged"
+ :columns="columns"
+ :rows="rows"
+ :select-options="{
+ enabled: true,
+ }"
+ :search-options="{ enabled: true }">
+ <template #selected-row-actions>
+ <button>Action 1</button>
+ </template>
+</vue-good-table>
+<!-- click on a row below to show the action button -->
+
type Object
A collection of filter specific properties within a column object.
columns: [
+ {
+ label: 'name',
+ field: 'user_name',
+ filterOptions: {
+ styleClass: 'class1', // class to be added to the parent th element
+ enabled: true, // enable filter for this column
+ placeholder: 'Filter This Thing', // placeholder for filter input
+ filterValue: 'Jane', // initial populated value for this filter
+ filterDropdownItems: [], // dropdown (with selected values) instead of text input
+ filterFn: this.columnFilterFn, //custom filter function that
+ trigger: 'enter', //only trigger on enter not on keyup
+ },
+ },
+ // ...
+]
+
type: string
Class to be added to the parent th element. You can specify several classes separated by a space.
type: Boolean
Switch to enable column filter.
type: String
Placeholder to use on the column filter input.
type: String
If you want filter to be pre-populated, use this property
type: String (default: '')
Allows specifying trigger for column filter. Default trigger is keyup. use 'enter' to filter only when enter key is pressed.
type Array of strings or Array of objects
allows creating a dropdown for filter as opposed to an input
//array
+filterDropdownItems: ['Blue', 'Red', 'Yellow']
+//or
+filterDropdownItems: [
+ { value: 'n', text: 'Inactive' },
+ { value: 'y', text: 'Active' },
+ { value: 'c', text: 'Check' }
+],
+
type Function
Custom filter, function of two variables: function(data, filterString)
, should return true if data matches the filterString, otherwise false
filterFn: function(data, filterString) {
+ var x = parseInt(filterString)
+ return data >= x - 5 && data <= x + 5;
+}
+// would create a filter matching numbers within 5 of the provided value
+
Each column objects can contain the following configuration options:
type String
Text to put on column header.
columns: [
+ {
+ label: 'name'
+ },
+ // ...
+]
+
type String
Row object property that this column corresponds to. This can be:
eg: 'name'
- simple row property nameeg: 'location.lat'
- nested row property name. lets say if the row had a property 'location' which was an object containing 'lat' and 'lon'columns: [
+ {
+ label: 'name',
+ field: this.fealdFn,
+ },
+ // ...
+]
+// in methods
+fieldFn(rowObj) {
+ return rowObj.name;
+}
+
type String
type of column. default: 'text'. This determines the formatting for the column and filter behavior as well. Possible values:
columns: [
+ {
+ label: 'joined On',
+ field: 'createdAt',
+ type: 'date',
+ dateInputFormat: 'yyyy-MM-dd', // expects 2018-03-16
+ dateOutputFormat: 'MMM do yyyy', // outputs Mar 16th 2018
+ },
+ // ...
+]
+
type String
provide the format to parse date string.
Tips
Vue-good-table uses date-fns for date parsing. Check out their formats here.
type String
provide the format for output date
type Boolean
enable/disable sorting on columns. This property is higher priority than global sortable property
columns: [
+ {
+ label: 'name',
+ field: 'user_name',
+ sortable: false,
+ },
+ // ...
+]
+
type String (default: 'asc')
controls the first sort type when sorting by the column. If you want the first sort type for this column to be descending, set this property to 'desc'. Possible values:
columns: [
+ {
+ label: 'name',
+ field: 'user_name',
+ sortable: true,
+ firstSortType: 'desc'
+ },
+ // ...
+]
+
type Function
custom sort function. If you want to supply your own sort function you can use this property.
// in data
+columns: [
+ {
+ label: 'Name',
+ field: 'name',
+ sortable: true,
+ sortFn: this.sortFn,
+ }
+ //...
+],
+// in methods
+methods: {
+ sortFn(x, y, col, rowX, rowY) {
+ // x - row1 value for column
+ // y - row2 value for column
+ // col - column being sorted
+ // rowX - row object for row1
+ // rowY - row object for row2
+ return (x < y ? -1 : (x > y ? 1 : 0));
+ }
+}
+
type Function
Allows for custom format of values, function(value)
, should return the formatted value to display.
// in data
+columns: [
+ {
+ label: 'Salary',
+ field: 'salary',
+ sortable: true,
+ formatFn: this.formatFn,
+ }
+ //...
+],
+// in methods
+formatFn: function(value) {
+ return '$' + value;
+}
+
type Boolean
indicates whether this column will require html rendering.
`,43)),n("div",u,[s[2]||(s[2]=n("p",{class:"hint-container-title"},"Tips",-1)),n("p",null,[s[1]||(s[1]=e("The preferred way of creating columns that have html is by ")),c(p,{to:"/guide/advanced/#custom-row-template"},{default:r(()=>s[0]||(s[0]=[e("using slots")])),_:1})])]),s[4]||(s[4]=a(`// in data
+columns: [
+ {
+ label: 'Action',
+ field: 'btn',
+ html: true,
+ }
+ //...
+],
+rows: [
+ {
+ btn: '<button>My Action</button>',
+ // ...
+ }
+]
+
type Number
provide a width value for this column
columns: [
+ {
+ label: 'name',
+ field: 'user_name',
+ width: '50px',
+ },
+ // ...
+]
+
type Boolean
hide a column
columns: [
+ {
+ label: 'name',
+ field: 'user_name',
+ hidden: true,
+ },
+ // ...
+]
+
type String
provide custom class(es) to the table header
columns: [
+ {
+ label: 'name',
+ field: 'user_name',
+ thClass: 'custom-th-class',
+ },
+ // ...
+]
+
type String
or Function
provide custom class(es) to the table cells
columns: [
+ {
+ label: 'name',
+ field: 'user_name',
+ tdClass: 'text-center',
+ },
+ // ...
+]
+
or
columns: [
+ {
+ label: 'name',
+ field: 'user_name',
+ tdClass: this.tdClassFunc,
+ },
+ // ...
+]
+// and later
+methods: {
+ tdClassFunc(row) {
+ if (row.field > 50) {
+ return 'red-class';
+ }
+ return 'green-class';
+ },
+}
+
type Boolean (default: false)
if true, this column will be ignored by the global search
columns: [
+ {
+ label: 'name',
+ field: 'user_name',
+ globalSearchDisabled: true,
+ },
+ // ...
+]
+
type String
Text to put on a simple tooltip for column header.
columns: [
+ {
+ label: 'name',
+ field: 'user_name',
+ tooltip: 'A simple tooltip',
+ },
+ // ...
+]
+
To create grouped rows, you need two things.
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :group-options="{
+ enabled: true
+ }"
+>
+</vue-good-table>
+
rows: [
+ {
+ mode: 'span', // span means this header will span all columns
+ label: 'Mammal', // this is the label that'll be used for the header
+ html: false, // if this is true, label will be rendered as html
+ children: [
+ { name: 'Elephant', diet: 'herbivore', count: 5 },
+ { name: 'Cat', diet: 'carnivore', count: 28 }
+ ]
+ }
+];
+
rows: [
+ {
+ name: 'Mammals Total', // this is the label that'll be used for the header
+ diet: undefined,
+ count: '', // total count will be displayed here
+ children: [
+ { name: 'Elephant', diet: 'herbivore', count: 5 },
+ { name: 'Cat', diet: 'carnivore', count: 28 }
+ ]
+ }
+];
+
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :group-options="{
+ enabled: true,
+ headerPosition: 'bottom'
+ }"
+>
+</vue-good-table>
+
In your column definition add a property, headerField
. This is just like field
property but for summary/header rows only. So lets say we wanted to add a sum function to this field.
// in columns
+{
+ label: 'Count',
+ field: 'count',
+ headerField: this.sumCount,
+ type: 'number',
+},
+
+// in methods we define sumCount
+methods: {
+ sumCount: function (rowObj) {
+ console.log(rowObj);
+ let sum = 0;
+ for (let i = 0; i < rowObj.children.length; i++) {
+ sum += rowObj.children[i].count;
+ }
+ return sum;
+ },
+},
+
+
If you want more control over what the header row looks like, you can use slots the same way you customize rows. For example if you want to add a button in the header row or something, this would be the way to do it.
In this case, the header row spans across all columns
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :group-options="{
+ enabled: true,
+ headerPosition: 'top'
+ }"
+>
+ <template #table-header-row="props">
+ <span class="my-fancy-class">
+ {{ props.row.label }}
+ </span>
+ </template>
+</vue-good-table>
+
In this case header row expects a value for each column
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :group-options="{
+ enabled: true,
+ headerPosition: 'top'
+ }"
+>
+ <template #table-header-row="props">
+ <span v-if="props.column.field == 'action'">
+ <button class="fancy-btn">Action</button>
+ </span>
+ <span v-else>
+ {{ props.formattedRow[props.column.field] }}
+ </span>
+ </template>
+</vue-good-table>
+
Tips
props.row
props.column
props.formattedRow
To allow the row to collapse and expand you can use the groupOption "collapsable". You can either pass in a boolean or a number. If collapsable
is set to true
then it will default to making the first column collapsable. Alternatively, you can specify the column index number. If you only add new rows to your table at the end, then the expanded or collapsed state of your rows will be maintained. However if you need to insert rows before the last one, you can pass in rowKey
inside of groupOptions
with a unique identifier for your rows. The expanded and collapsed state will then be maintained.
<vue-good-table
+ ref="myCustomTable"
+ :columns="columns"
+ :rows="rows"
+ :group-options="{
+ enabled: true,
+ rowKey:"id",
+ collapsable: true // or column index
+ }"
+>
+</vue-good-table>
+
To expand/collapse all you can use the method called expandAll
or collapseAll
.
this.$refs.myCustomTable.expandAll();
+this.$refs.myCustomTable.collapseAll();
+
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>
+
NOTE
props.row
props.index
.props.row.originalIndex
. You can then access the original row object by using rows[props.row.originalIndex]
.props.column
props.formattedRow
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'
+},
+
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>
+
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.
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:
vue-select
in your project, follwing the guide at https://vue-select.org.<v-select
+ :options="optionList"
+ multiple
+ @input="(value) => updateFilters(column, value)"
+/>
+
multiple
attribute for a multiselect filter.options
attribute of v-select
. If you were using the built in multiselect filter, move them from the column property filterOptions.multiSelectDropdownItems
.vue-select
emits 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(',');
+ }
+}
+
:::
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:
props.total
props.pageChanged
.props.perPageChanged
.Install with npm:
npm install --save vue-good-table-next
+
Import globally in app:
import VueGoodTablePlugin from 'vue-good-table-next';
+
+// import the styles
+import 'vue-good-table-next/dist/vue-good-table-next.css'
+
+Vue.use(VueGoodTablePlugin);
+
or you can import into your component:
// import the styles
+import 'vue-good-table-next/dist/vue-good-table-next.css'
+import { VueGoodTable } from 'vue-good-table-next';
+
+// add to component
+components: {
+ VueGoodTable,
+}
+
<template>
+ <div>
+ <vue-good-table
+ :columns="columns"
+ :rows="rows"/>
+ </div>
+</template>
+
+<script>
+export default {
+ name: 'my-component',
+ data(){
+ return {
+ columns: [
+ {
+ label: 'Name',
+ field: 'name',
+ },
+ {
+ label: 'Age',
+ field: 'age',
+ type: 'number',
+ },
+ {
+ label: 'Created On',
+ field: 'createdAt',
+ type: 'date',
+ dateInputFormat: 'yyyy-MM-dd',
+ dateOutputFormat: 'MMM do yy',
+ },
+ {
+ label: 'Percent',
+ field: 'score',
+ type: 'percentage',
+ },
+ ],
+ rows: [
+ { id:1, name:"John", age: 20, createdAt: null, score: 0.03343 },
+ { id:2, name:"Jane", age: 24, createdAt: '2011-10-31', score: 0.03343 },
+ { id:3, name:"Susan", age: 16, createdAt: '2011-10-30', score: 0.03343 },
+ { id:4, name:"Chris", age: 55, createdAt: '2011-10-11', score: 0.03343 },
+ { id:5, name:"Dan", age: 40, createdAt: '2011-10-21', score: 0.03343 },
+ { id:6, name:"John", age: 20, createdAt: '2011-10-31', score: 0.03343 },
+ ],
+ };
+ },
+};
+</script>
+
Create your own plugin by creating a file called vue-good-table.js
inside your Nuxt plugins
folder. Shoud look something like this:
import Vue from 'vue'
+import VueGoodTablePlugin from 'vue-good-table-next';
+
+// import the styles
+import 'vue-good-table-next/dist/vue-good-table-next.css'
+
+Vue.use(VueGoodTablePlugin);
+
As you can see, the only difference from the normal installation is that we need to reference Vue using import Vue from 'vue'
.
Next we need to declare the plugin inside your nuxt.config.js
like so:
plugins: [
+ { src: '~/plugins/vue-good-table-next', ssr: false }
+],
+
This should now work as expected.
`,8))])}const d=p(i,[["render",c],["__file","index.html.vue"]]),k=JSON.parse('{"path":"/guide/","title":"Getting Started","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Installation","slug":"installation","link":"#installation","children":[]},{"level":2,"title":"Basic Example","slug":"basic-example","link":"#basic-example","children":[]},{"level":2,"title":"Usage with Nuxt.js","slug":"usage-with-nuxt-js","link":"#usage-with-nuxt-js","children":[]}],"git":{"updatedTime":1656684582000,"contributors":[{"name":"Akshay Anand","email":"aks9800@gmail.com","commits":6},{"name":"Boris Flesch","email":"boris.flesch@gmail.com","commits":1},{"name":"Sergei Predvoditelev","email":"sergei@predvoditelev.ru","commits":1},{"name":"Tom Hopcraft","email":"CHEWX@users.noreply.github.com","commits":1}]},"filePathRelative":"guide/README.md"}');export{d as comp,k as data}; diff --git a/assets/index.html-ClzZSixM.js b/assets/index.html-ClzZSixM.js new file mode 100644 index 00000000..aabbceca --- /dev/null +++ b/assets/index.html-ClzZSixM.js @@ -0,0 +1,78 @@ +import{_ as d,r as l,o as m,c as k,a as n,e as a,b as t,w as o,d as e}from"./app-CbJnpAZk.js";const v={},b={class:"hint-container tip"};function g(h,s){const p=l("RouteLink"),c=l("fixed-header"),u=l("line-numbers-table"),i=l("rtl-table"),r=l("action-slot-table");return m(),k("div",null,[s[14]||(s[14]=n("h1",{id:"table-options",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#table-options"},[n("span",null,"Table Options")])],-1)),s[15]||(s[15]=n("p",null,"These options relate to the table as a whole",-1)),s[16]||(s[16]=n("h2",{id:"columns",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#columns"},[n("span",null,"columns")])],-1)),s[17]||(s[17]=n("p",null,[a("type: "),n("code",null,"Array")],-1)),n("p",null,[s[1]||(s[1]=a("Array containing objects that describe table columns. The column object itself can contain many ")),t(p,{to:"/guide/configuration/column-options.html"},{default:o(()=>s[0]||(s[0]=[a("configurable properties")])),_:1}),s[2]||(s[2]=a("."))]),s[18]||(s[18]=e(`[
+ {
+ label: 'Name',
+ field: 'name',
+ }
+ //...
+]
+
type: Array
Array containing row objects. Each row object contains data that will be displayed in the table row.
[
+ {
+ id:1,
+ name:"John",
+ age:20
+ },
+ //...
+]
+
type: String
Set a maximum height for table body
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ max-height="300px">
+</vue-good-table>
+
type: Boolean (default: false)
fix header so it stays in view as you scroll the table.
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ max-height="200px"
+ :fixed-header="true">
+</vue-good-table>
+
Tips
Fixed header should probably be used with max-height
type: Boolean (default: false)
Show line number for each row
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :line-numbers="true">
+</vue-good-table>
+
type: String
or Function
property to assign a class to rows. This can either be a string representing a css class-name or a function.
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :row-style-class="rowStyleClassFn">
+</vue-good-table>
+
methods: {
+ rowStyleClassFn(row) {
+ return row.age > 18 ? 'green' : 'red';
+ },
+}
+
type: Boolean (default: false)
Enable Right-To-Left layout for the table
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :rtl="true">
+</vue-good-table>
+
If you want to add table specific actions like a print button for example, you can use the Table Actions Slot. If you have global search enabled, the action panel will show up to the right of that.
Note
You don't have to have global search enabled to use this slot.
<vue-good-table
+ :columns="columns"
+ :rows="rows">
+ <template #table-actions>
+ This will show up on the top right of the table.
+ </template>
+</vue-good-table>
+
If you want a space for your buttons between pagination and the table. This is the slot you use.
<vue-good-table
+ :columns="columns"
+ :rows="rows">
+ <template #table-actions-bottom>
+ This will show up on the bottom of the table.
+ </template>
+</vue-good-table>
+
You can provide html for empty state slot as well. Example:
<vue-good-table
+ :columns="columns"
+ :rows="rows">
+ <template #emptystate>
+ This will show up when there are no rows
+ </template>
+</vue-good-table>
+
type: String
Set mode=remote
to allow sorting/filtering etc to be powered by server side instead of client side.
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ mode="remote">
+</vue-good-table>
+
type: Number
Tips
totalRecords is only useful for remote mode. When server controls pagination the table needs to know how many total rows exist.
type: Boolean (default: false)
Enable mobile-friendly List view on small devices (screenSize below 576px)
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ compactMode>
+</vue-good-table>
+
<vue-good-table
+ :columns="columns"
+ :rows="rows">
+</vue-good-table>
+
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ theme="polar-bear">
+</vue-good-table>
+
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ theme="black-rhino">
+</vue-good-table>
+
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ theme="nocturnal">
+</vue-good-table>
+
An easy to use and clean VueJS step wizard plugin.
A light, expandable link and text hover effect library for VueJS.
Cloud-based platform for UX and Product teams.
A set of options that are related to table pagination. Each of these are optional and reasonable defaults will be used if you leave off the property.
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :pagination-options="{
+ enabled: true,
+ mode: 'records',
+ perPage: 5,
+ position: 'top',
+ perPageDropdown: [3, 7, 9],
+ dropdownAllowAll: false,
+ setCurrentPage: 2,
+ nextLabel: 'next',
+ prevLabel: 'prev',
+ rowsPerPageLabel: 'Rows per page',
+ ofLabel: 'of',
+ pageLabel: 'page', // for 'pages' mode
+ allLabel: 'All',
+ infoFn: (params) => \`my own page \${params.firstRecordOnPage}\`,
+ }">
+</vue-good-table>
+
type: Boolean (default: false)
Enable Pagination for table. By default the paginator is created at the bottom of the table.
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :pagination-options="{
+ enabled: true
+ }">
+</vue-good-table>
+
type: String (default: 'records')
You can render pagination controls in two modes - 'records' and 'pages'. Below, you'll find examples of both.
Tips
For tables that may have many pages, 'pages' mode offers the ability to jump to any valid page.
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :pagination-options="{
+ enabled: true,
+ mode: 'records'
+ }">
+</vue-good-table>
+
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :pagination-options="{
+ enabled: true,
+ mode: 'pages'
+ }">
+</vue-good-table>
+
type: String (default: 'bottom')
Add pagination on 'top' or 'bottom' (top and bottom) of the table (default position is bottom)
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :pagination-options="{
+ enabled: true,
+ position: 'top'
+ }">
+</vue-good-table>
+
type: Integer (default: 10)
Number of rows to show per page
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :pagination-options="{
+ enabled: true,
+ perPage: 5
+ }">
+</vue-good-table>
+
type: Boolean (default: true)
Show or hide the per page dropdown
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :pagination-options="{
+ enabled: true,
+ perPageDropdownEnabled: false,
+ }">
+</vue-good-table>
+
type: Array (default: [10,20,30,40,50])
Customize the dropdown options for the amount of items per page
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :pagination-options="{
+ enabled: true,
+ perPageDropdown: [3, 7, 9]
+ }">
+</vue-good-table>
+
type: Boolean (default: true)
enables/disables 'All' in the per page dropdown.
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :pagination-options="{
+ enabled: true,
+ perPageDropdown: [3, 7, 9],
+ dropdownAllowAll: false,
+ }">
+</vue-good-table>
+
type: Number
set current page programmatically.
Warning
There's no validation for number of pages so please be careful using this.
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :pagination-options="{
+ enabled: true,
+ setCurrentPage: 2,
+ }">
+</vue-good-table>
+
you can change one or more of the texts shown on pagination by overriding the labels in the following way:
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :pagination-options="{
+ enabled: true,
+ nextLabel: 'next',
+ prevLabel: 'prev',
+ rowsPerPageLabel: 'Rows per page',
+ ofLabel: 'of',
+ pageLabel: 'page', // for 'pages' mode
+ allLabel: 'All',
+ }">
+</vue-good-table>
+
Provide your own function to lay out pagination info how you like:
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :pagination-options="{
+ enabled: true,
+ infoFn: (params) => \`Showing \${params.firstRecordOnPage} to \${params.lastRecordOnPage} of page \${params.currentPage}\`,
+ }">
+</vue-good-table>
+
the parameters passed to infoFn are the following:
{
+ firstRecordOnPage: 'index of the first record on the current page',
+ lastRecordOnPage: 'index of the last record on the current page',
+ totalRecords: 'total number of records',
+ currentPage: 'current page',
+ totalPage: 'total number of pages',
+}
+
you can also replace the pagination component with your own component - Custom Pagination
`,35))])}const d=t(i,[["render",c],["__file","pagination-options.html.vue"]]),v=JSON.parse('{"path":"/guide/configuration/pagination-options.html","title":"Pagination Options","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"enabled","slug":"enabled","link":"#enabled","children":[]},{"level":2,"title":"mode","slug":"mode","link":"#mode","children":[{"level":3,"title":"records mode (default)","slug":"records-mode-default","link":"#records-mode-default","children":[]},{"level":3,"title":"pages mode","slug":"pages-mode","link":"#pages-mode","children":[]}]},{"level":2,"title":"position","slug":"position","link":"#position","children":[]},{"level":2,"title":"perPage","slug":"perpage","link":"#perpage","children":[]},{"level":2,"title":"perPageDropdownEnabled","slug":"perpagedropdownenabled","link":"#perpagedropdownenabled","children":[]},{"level":2,"title":"perPageDropdown","slug":"perpagedropdown","link":"#perpagedropdown","children":[]},{"level":2,"title":"dropdownAllowAll","slug":"dropdownallowall","link":"#dropdownallowall","children":[]},{"level":2,"title":"setCurrentPage","slug":"setcurrentpage","link":"#setcurrentpage","children":[]},{"level":2,"title":"pagination label/text options","slug":"pagination-label-text-options","link":"#pagination-label-text-options","children":[{"level":3,"title":"InfoFn","slug":"infofn","link":"#infofn","children":[]}]},{"level":2,"title":"Replace Pagination Component","slug":"replace-pagination-component","link":"#replace-pagination-component","children":[]}],"git":{"updatedTime":1614453666000,"contributors":[{"name":"Akshay Anand","email":"aks9800@gmail.com","commits":6}]},"filePathRelative":"guide/configuration/pagination-options.md"}');export{d as comp,v as data}; diff --git a/assets/pagination-table-CdDEvre5.js b/assets/pagination-table-CdDEvre5.js new file mode 100644 index 00000000..b737130a --- /dev/null +++ b/assets/pagination-table-CdDEvre5.js @@ -0,0 +1 @@ +import{_ as t,r as n,o as r,c as s,b as c}from"./app-CbJnpAZk.js";const d={name:"pagination-table",props:["options"],data(){return{columns:[{label:"Name",field:"name"},{label:"Age",field:"age",type:"number"},{label:"Created On",field:"createdAt",type:"date",dateInputFormat:"yyyy-MM-dd",dateOutputFormat:"MMM do yy"},{label:"Percent",field:"score",type:"percentage"}],rows:[{id:1,name:"John",age:20,createdAt:"2011-07-02",score:.03343},{id:2,name:"Jane",age:24,createdAt:"2011-10-31",score:.03343},{id:3,name:"Susan",age:16,createdAt:"2011-10-30",score:.03343},{id:4,name:"Chris",age:55,createdAt:"2011-10-11",score:.03343},{id:5,name:"Dan",age:40,createdAt:"2011-10-21",score:.03343},{id:6,name:"John",age:20,createdAt:"2011-10-31",score:.03343}]}},computed:{},methods:{},mounted(){},components:{}};function i(l,p,a,m,e,u){const o=n("vue-good-table");return r(),s("div",null,[c(o,{columns:e.columns,rows:e.rows,"pagination-options":a.options},null,8,["columns","rows","pagination-options"])])}const _=t(d,[["render",i],["__file","pagination-table.vue"]]);export{_ as default}; diff --git a/assets/remote-workflow.html-CAuSw68r.js b/assets/remote-workflow.html-CAuSw68r.js new file mode 100644 index 00000000..270aca3f --- /dev/null +++ b/assets/remote-workflow.html-CAuSw68r.js @@ -0,0 +1,94 @@ +import{_ as s,o as a,c as e,d as t}from"./app-CbJnpAZk.js";const p={};function o(l,n){return a(),e("div",null,n[0]||(n[0]=[t(`Vue-good-table's in-built features like sorting, paging, filtering etc. are all performed client side and therefore are great for most of the use-cases. Sometimes though, we might have too much data to render all of it at once on the UI. In such cases, we would want to do things like sorting, paging, filtering on the server side. Fortunately, vue-good-table comes with remote mode
to switch from client side to server side.
When remote mode is on, vue-good-table does not perform sorting, paging, filtering etc. on the client side but instead emits events that we can use to then send proper parameters to the back-end. The server then is expected to send the correct rows to display on the UI.
Following is a workflow you can use to get a server powered vue-good-table instance:
Before we dive into remote mode, lets agree on what we're going to be sending to the server. A set of parameters that tells the server exactly what rows I need to get back. Here's a proposed parameter object to send:
serverParams: {
+ // a map of column filters example: {name: 'john', age: '20'}
+ columnFilters: {
+ },
+ sort: [
+ {
+ field: '', // example: 'name'
+ type: '' // 'asc' or 'desc'
+ }
+ ],
+
+ page: 1, // what page I want to show
+ perPage: 10 // how many items I'm showing per page
+}
+
With the above information, server should be able to generate the relevant rows to send back.
Two things are required for the server to send back
<vue-good-table
+ mode="remote"
+ :pagination-options="{
+ enabled: true,
+ }"
+ :totalRows="totalRecords"
+ :rows="rows"
+ :columns="columns"/>
+
this tells VGT to not do client side paging/sorting/filtering
Now instead of doing the above client side, each user interaction will generate events. So lets provide handlers for those events:
<vue-good-table
+ mode="remote"
+ v-on:page-change="onPageChange"
+ v-on:sort-change="onSortChange"
+ v-on:column-filter="onColumnFilter"
+ v-on:per-page-change="onPerPageChange"
+ :totalRows="totalRecords"
+ :isLoading.sync="isLoading"
+ :pagination-options="{
+ enabled: true,
+ }"
+ :rows="rows"
+ :columns="columns"/>
+
... in data
data() {
+ return {
+ isLoading: false,
+ columns: [
+ //...
+ ],
+ rows: [],
+ totalRecords: 0,
+ serverParams: {
+ columnFilters: {
+ },
+ sort: {
+ field: '',
+ type: '',
+ },
+ page: 1,
+ perPage: 10
+ }
+ };
+},
+
... handlers
methods: {
+ updateParams(newProps) {
+ this.serverParams = Object.assign({}, this.serverParams, newProps);
+ },
+
+ onPageChange(params) {
+ this.updateParams({page: params.currentPage});
+ this.loadItems();
+ },
+
+ onPerPageChange(params) {
+ this.updateParams({perPage: params.currentPerPage});
+ this.loadItems();
+ },
+
+ onSortChange(params) {
+ this.updateParams({
+ sort: [{
+ type: params.sortType,
+ field: this.columns[params.columnIndex].field,
+ }],
+ });
+ this.loadItems();
+ },
+
+ onColumnFilter(params) {
+ this.updateParams(params);
+ this.loadItems();
+ }
+
+ // load items is what brings back the rows from server
+ loadItems() {
+ getFromServer(this.serverParams).then(response => {
+ this.totalRecords = response.totalRecords;
+ this.rows = response.rows;
+ });
+ }
+}
+
serverParams
and then send a request to the backend.Tips
If you want to show loading notification manually, you can do so using table's :isLoading.sync="isLoading"
property.
Tips
to style the loading dom, you can use the slot - loadingContent
So that wasn't too bad. You now have VGT that's powered completely by your backend server.
`,29)]))}const c=s(p,[["render",o],["__file","remote-workflow.html.vue"]]),r=JSON.parse('{"path":"/guide/advanced/remote-workflow.html","title":"Server Side Table","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Why Remote Mode?","slug":"why-remote-mode","link":"#why-remote-mode","children":[]},{"level":2,"title":"Prep Work","slug":"prep-work","link":"#prep-work","children":[{"level":3,"title":"What do we send to server?","slug":"what-do-we-send-to-server","link":"#what-do-we-send-to-server","children":[]},{"level":3,"title":"What does the server send back?","slug":"what-does-the-server-send-back","link":"#what-does-the-server-send-back","children":[]}]},{"level":2,"title":"Set mode to remote","slug":"set-mode-to-remote","link":"#set-mode-to-remote","children":[]},{"level":2,"title":"Provide handlers for user events","slug":"provide-handlers-for-user-events","link":"#provide-handlers-for-user-events","children":[]},{"level":2,"title":"So, what is happening?","slug":"so-what-is-happening","link":"#so-what-is-happening","children":[]},{"level":2,"title":"Conclusion","slug":"conclusion","link":"#conclusion","children":[]}],"git":{"updatedTime":1632425937000,"contributors":[{"name":"Akshay Anand","email":"aks9800@gmail.com","commits":5},{"name":"Boris Flesch","email":"boris.flesch@gmail.com","commits":1}]},"filePathRelative":"guide/advanced/remote-workflow.md"}');export{c as comp,r as data}; diff --git a/assets/row-details-table.html-DQZqMzfp.js b/assets/row-details-table.html-DQZqMzfp.js new file mode 100644 index 00000000..f0aa7c31 --- /dev/null +++ b/assets/row-details-table.html-DQZqMzfp.js @@ -0,0 +1,18 @@ +import{_ as n,o as s,c as t,d as e}from"./app-CbJnpAZk.js";const p={};function l(o,a){return s(),t("div",null,a[0]||(a[0]=[e(`This option allows you to show or hide the details of a row on click.
type: Boolean
table-row
props now also contain props.expandedRow
this will be true if row is expanded
Object containing select options
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :enable-row-expand="true"
+ expanded-row-classes="bg-red"
+ expanded-row-detail-classes="bg-yellow"
+>
+
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :enable-row-expand="true"
+ expanded-row-classes="bg-red"
+ expanded-row-detail-classes="bg-yellow">
+ <template #row-details="props">
+ <p>{{ props.formattedRow }} (or props.row.X to access any property X of the current row)</p>
+ </template>
+</vue-good-table>
+
Vue-Good-Table's styling is written in Sass. The source files are made available as part of the npm dependency.
Vue-Good-Table's root Sass file:
@import "../node_modules/vue-good-table/src/styles/style.scss";
+
This section talks about how to configure global search options.
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :search-options="{
+ enabled: true,
+ trigger: 'enter',
+ skipDiacritics: true,
+ searchFn: mySearchFn,
+ placeholder: 'Search this table',
+ externalQuery: searchQuery,
+ v-on:search="onSearch"
+ }">
+</vue-good-table>
+
type: Boolean (default: false)
Allows a single search input for the whole table
Warning
Enabling this option disables column filters
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :search-options="{
+ enabled: true
+ }">
+</vue-good-table>
+
type: String (default: '')
Allows you to specify if you want search to trigger on 'enter' event of the input. By default table searches on key-up.
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :search-options="{
+ enabled: true,
+ trigger: 'enter'
+ }">
+</vue-good-table>
+
type: boolean (default: false)
By default, search does a diacriticless comparison so you can search through accented characters. This however slows down the search to some extent. If your data doesn't have accented characters, you can skip this check and gain some performance.
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :search-options="{
+ enabled: true,
+ skipDiacritics: true,
+ }">
+</vue-good-table>
+
type: Function
Allows you to specify your own search function for the global search
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :search-options="{
+ enabled: true,
+ searchFn: myFunc
+ }">
+</vue-good-table>
+
// in js
+methods: {
+ myFunc(row, col, cellValue, searchTerm){
+ return cellValue === 'my value';
+ },
+}
+
type: String (default: 'Search Table')
Text for global search input place holder
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :search-options="{
+ enabled: true,
+ placeholder: 'Search this table',
+ }">
+</vue-good-table>
+
type: String
If you want to use your own input for searching the table, you can use this property
<input type="text" v-model="searchTerm" >
+<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :search-options="{
+ enabled: true,
+ externalQuery: searchTerm
+ }">
+</vue-good-table>
+
// and in data
+data(){
+ return {
+ searchTerm: '',
+ // rows, columns etc...
+ };
+}
+
Set of options related to table sorting
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :sort-options="{
+ enabled: true,
+ initialSortBy: {field: 'name', type: 'asc'}
+ }">
+</vue-good-table>
+
type: Boolean (default: true)
Enable/disable sorting on table as a whole.
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :sort-options="{
+ enabled: true,
+ }">
+</vue-good-table>
+
Update
initialSortBy
now allows for sort by multiple columns
type: Object
or Array
Allows specifying a default sort for the table on wakeup. Both field and type values are required.
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :sort-options="{
+ enabled: true,
+ initialSortBy: {field: 'name', type: 'asc'}
+ }">
+</vue-good-table>
+
type: Boolean (default: true)
Enable/disable multiple column sort. Users can shift-click on multiple columns to sort by multiple columns. The first column in the array gets primary sort.
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :sort-options="{
+ enabled: true,
+ multipleColumns: true,
+ initialSortBy: [
+ {field: 'name', type: 'asc'},
+ {field: 'age', type: 'desc'}
+ ],
+ }">
+</vue-good-table>
+
Vue-good-table allows providing your own css classes for the table via styleClass option but it also has in-built classes that you can make use of.
NOTE
by default, tables have 'vgt-table striped bordered'
Base class that initializes all the core styles for the table.
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ styleClass="vgt-table">
+</vue-good-table>
+
Add row striping in your data table.
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ styleClass="vgt-table striped">
+</vue-good-table>
+
Add borders to columns/rows
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ styleClass="vgt-table bordered">
+</vue-good-table>
+
Have lots of rows? use condensed class to get more compact rows.
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ styleClass="vgt-table condensed">
+</vue-good-table>
+
event emitted on table row click
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ v-on:row-click="onRowClick">
+
methods: {
+ onRowClick(params) {
+ // params.row - row object
+ // params.pageIndex - index of this row on the current page.
+ // params.selected - if selection is enabled this argument
+ // indicates selected or not
+ // params.event - click event
+ }
+}
+
event emitted on table row click
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ v-on:row-dblclick="onRowDoubleClick">
+
methods: {
+ onRowDoubleClick(params) {
+ // params.row - row object
+ // params.pageIndex - index of this row on the current page.
+ // params.selected - if selection is enabled this argument
+ // indicates selected or not
+ // params.event - click event
+ }
+}
+
event emitted on table cell click
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ v-on:cell-click="onCellClick">
+
methods: {
+ onCellClick(params) {
+ // params.row - row object
+ // params.column - column object
+ // params.rowIndex - index of this row on the current page.
+ // params.event - click event
+ }
+}
+
event emitted on row mouseenter
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ v-on:row-mouseenter="onRowMouseover">
+
methods: {
+ onRowMouseover(params) {
+ // params.row - row object
+ // params.pageIndex - index of this row on the current page.
+ }
+}
+
event emitted on table row mouseleave
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ v-on:row-mouseleave="onRowMouseleave">
+
methods: {
+ onRowMouseleave(row, pageIndex) {
+ // row - row object
+ // pageIndex - index of this row on the current page.
+ }
+}
+
event emitted on global search (when global search is enabled)
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ v-on:search="onSearch">
+
methods: {
+ onSearch(params) {
+ // params.searchTerm - term being searched for
+ // params.rowCount - number of rows that match search
+ }
+}
+
event emitted on pagination page change (when pagination is enabled)
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ v-on:page-change="onPageChange">
+
methods: {
+ onPageChange(params) {
+ // params.currentPage - current page that pagination is at
+ // params.prevPage - previous page
+ // params.currentPerPage - number of items per page
+ // params.total - total number of items in the table
+ }
+}
+
event emitted on per page dropdown change (when pagination is enabled)
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ v-on:per-page-change="onPageChange">
+
methods: {
+ onPageChange(params) {
+ // params.currentPage - current page that pagination is at
+ // params.currentPerPage - number of items per page
+ // params.total - total number of items in the table
+ }
+}
+
event emitted on sort change.
Tips
vue-good-table now supports sorting by multiple columns, so the params is an array.
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ v-on:sort-change="onSortChange">
+
methods: {
+ onSortChange(params) {
+ // params is Vue-created proxy object:
+ // params[0].type - "asc" or "desc"
+ // params[0].field - field being sorted
+ }
+}
+
event emitted when column is filtered (only emitted for remote mode)
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ v-on:column-filter="onColumnFilter">
+
methods: {
+ onColumnFilter(params) {
+ // params.columnFilters - filter values for each column in the following format:
+ // {field1: 'filterTerm', field3: 'filterTerm2')
+ }
+}
+
event emitted when all is selected (only emitted for checkbox tables)
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :select-options="{ enabled: true }"
+ v-on:select-all="onSelectAll">
+
methods: {
+ onSelectAll(params) {
+ // params.selected - whether the select-all checkbox is checked or unchecked
+ // params.selectedRows - all rows that are selected (this page)
+ }
+}
+
event emitted whenever selection is changed (on checkbox tables)
<vue-good-table
+ :columns="columns"
+ :rows="rows"
+ :select-options="{ enabled: true }"
+ v-on:selected-rows-change="selectionChanged">
+
methods: {
+ selectionChanged(params) {
+ // params.selectedRows - all rows that are selected (this page)
+ }
+}
+