1 | # Vue-good-table
|
2 |
|
3 | [![npm](https://img.shields.io/npm/dm/vue-good-table.svg?style=flat-square)](https://www.npmjs.com/package/vue-good-table)
|
4 | [![npm](https://img.shields.io/github/package-json/v/xaksis/vue-good-table.svg?style=flat-square)](https://github.com/xaksis/vue-good-table/releases)
|
5 | [![npm](https://img.shields.io/github/license/xaksis/vue-good-table.svg?style=flat-square)](https://github.com/xaksis/vue-good-table/blob/master/LICENSE)
|
6 | [![](https://data.jsdelivr.com/v1/package/npm/vue-good-table/badge)](https://www.jsdelivr.com/package/npm/vue-good-table)
|
7 | [![Twitter Follow](https://img.shields.io/twitter/follow/crayonbytes.svg?label=Follow&style=social)](https://twitter.com/crayonbytes)
|
8 |
|
9 | An easy to use, clean and powerful data table for VueJS with essential features like sorting, column filtering, pagination and much more - [xaksis.github.io/vue-good-table/](https://xaksis.github.io/vue-good-table/)
|
10 |
|
11 |
|
12 | ### Basic Table
|
13 | ![Basic Screenshot](README/images/vgt-table.regular.png) -->
|
14 |
|
15 |
|
16 | Some example recipes for inspiration
|
17 | [vue-good-table Recipes](https://github.com/xaksis/vue-good-table/wiki/Vue-good-table-Recipes-(vue-good-table-2.x)) -->
|
18 |
|
19 | ## Table of contents -->
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 | - [Getting Started](#getting-started)
|
26 | - [Installing](#installing)
|
27 | - [Example Usage](#example-usage)
|
28 | - [Configuration](#configuration)
|
29 | - [Component Options](#component-options)
|
30 | - [Table](#table)
|
31 | - [Sort Options](#sort-options)
|
32 | - [Pagination Options](#pagination-options)
|
33 | - [Search Options](#search-options)
|
34 | - [Checkbox Table](#checkbox-table)
|
35 | - [Grouped Row Options](#grouped-row-options)
|
36 | - [Style/Theme](#styletheme)
|
37 | - [Column Options](#column-options)
|
38 | - [Column filter option in-depth](#column-filter-option-in-depth)
|
39 | - [Table Events](#table-events)
|
40 | - [@on-row-click](#on-row-click)
|
41 | - [@on-cell-click](#on-cell-click)
|
42 | - [@on-row-mouseenter](#on-row-mouseenter)
|
43 | - [@on-row-mouseleave](#on-row-mouseleave)
|
44 | - [@on-search](#on-search)
|
45 | - [@on-page-change](#on-page-change)
|
46 | - [@on-per-page-change](#on-per-page-change)
|
47 | - [@on-sort-change](#on-sort-change)
|
48 | - [@on-select-all](#on-select-all)
|
49 | - [@on-column-filter](#on-column-filter)
|
50 | - [@on-selected-rows-change](#on-selected-rows-change)
|
51 | - [Style Options](#style-options)
|
52 | - [.vgt-table](#vgt-table)
|
53 | - [.vgt-table .stripped](#vgt-table-stripped)
|
54 | - [.vgt-table .condensed](#vgt-table-condensed)
|
55 | - [Themes](#themes)
|
56 | - [default](#default)
|
57 | - [nocturnal `theme='nocturnal'`](#nocturnal-themenocturnal)
|
58 | - [black-rhino `theme='black-rhino'`](#black-rhino-themeblack-rhino)
|
59 | - [Advanced Customization](#advanced-customization)
|
60 | - [Custom row template](#custom-row-template)
|
61 | - [Custom column headers](#custom-column-headers)
|
62 | - [Grouped Rows](#grouped-rows)
|
63 | - [Remote Mode](#remote-mode)
|
64 | - [Table Actions Slot](#table-actions-slot)
|
65 | - [Empty state slot](#empty-state-slot)
|
66 | - [Authors](#authors)
|
67 | - [License](#license) -->
|
68 |
|
69 |
|
70 |
|
71 | ## Installing
|
72 |
|
73 | Install with npm:
|
74 | ```bash
|
75 | npm install --save vue-good-table
|
76 | ```
|
77 |
|
78 | Import globally in app:
|
79 |
|
80 | ```javascript
|
81 | import VueGoodTablePlugin from 'vue-good-table';
|
82 |
|
83 | // import the styles
|
84 | import 'vue-good-table/dist/vue-good-table.css'
|
85 |
|
86 | Vue.use(VueGoodTablePlugin);
|
87 | ```
|
88 |
|
89 | Import into your component
|
90 | ```js
|
91 | import { VueGoodTable } from 'vue-good-table';
|
92 |
|
93 | // add to component
|
94 | components: {
|
95 | VueGoodTable,
|
96 | }
|
97 | ```
|
98 |
|
99 | Import into your component using Typescript
|
100 | ```typescript
|
101 | // add to component
|
102 | components: {
|
103 | 'vue-good-table': require('vue-good-table').VueGoodTable,
|
104 | }
|
105 | ```
|
106 |
|
107 |
|
108 | ##### Example table with grouped rows and column filters
|
109 | ![Advanced Screenshot](README/images/vgt-table.advanced.png)
|
110 |
|
111 | ## Features
|
112 | * [Table Search](https://xaksis.github.io/vue-good-table/guide/configuration/search-options.html)
|
113 | * [Sorting](https://xaksis.github.io/vue-good-table/guide/configuration/sort-options.html)
|
114 | * [Column Filtering](https://xaksis.github.io/vue-good-table/guide/configuration/column-filter-options.html#filteroptions)
|
115 | * [Pagination](https://xaksis.github.io/vue-good-table/guide/configuration/pagination-options.html)
|
116 | * [Highly Customizable](https://xaksis.github.io/vue-good-table/guide/advanced/#custom-row-template)
|
117 | * [Checkbox Table](https://xaksis.github.io/vue-good-table/guide/advanced/checkbox-table.html)
|
118 | * [Grouped Rows Table](https://xaksis.github.io/vue-good-table/guide/advanced/grouped-table.html)
|
119 | * [Server Powered Table](https://xaksis.github.io/vue-good-table/guide/advanced/remote-workflow.html#why-remote-mode)
|
120 | * [Customizable Style and Themes](https://xaksis.github.io/vue-good-table/guide/style-configuration/)
|
121 |
|
122 | ## Upgrade Guide
|
123 | Hey there! coming from 1.x? find the [upgrade guide here](https://github.com/xaksis/vue-good-table/wiki/Guide-to-upgrade-from-1.x-to-v2.0)
|
124 |
|
125 |
|
126 | ### Example Usage
|
127 | ```html
|
128 | <template>
|
129 | <div>
|
130 | <vue-good-table
|
131 | :columns="columns"
|
132 | :rows="rows"
|
133 | :search-options="{
|
134 | enabled: true,
|
135 | }"
|
136 | :pagination-options="{
|
137 | enabled: true,
|
138 | perPage: 5,
|
139 | }"
|
140 | styleClass="vgt-table striped bordered"/>
|
141 | </div>
|
142 | </template>
|
143 |
|
144 | <script>
|
145 | export default {
|
146 | name: 'my-component',
|
147 | data(){
|
148 | return {
|
149 | columns: [
|
150 | {
|
151 | label: 'Name',
|
152 | field: 'name',
|
153 | filterOptions: {
|
154 | enabled: true,
|
155 | },
|
156 | },
|
157 | {
|
158 | label: 'Age',
|
159 | field: 'age',
|
160 | type: 'number',
|
161 | },
|
162 | {
|
163 | label: 'Created On',
|
164 | field: 'createdAt',
|
165 | type: 'date',
|
166 | dateInputFormat: 'YYYY-MM-DD',
|
167 | dateOutputFormat: 'MMM Do YY',
|
168 | },
|
169 | {
|
170 | label: 'Percent',
|
171 | field: 'score',
|
172 | type: 'percentage',
|
173 | },
|
174 | ],
|
175 | rows: [
|
176 | { id:1, name:"John", age: 20, createdAt: '201-10-31:9: 35 am',score: 0.03343 },
|
177 | { id:2, name:"Jane", age: 24, createdAt: '2011-10-31', score: 0.03343 },
|
178 | { id:3, name:"Susan", age: 16, createdAt: '2011-10-30', score: 0.03343 },
|
179 | { id:4, name:"Chris", age: 55, createdAt: '2011-10-11', score: 0.03343 },
|
180 | { id:5, name:"Dan", age: 40, createdAt: '2011-10-21', score: 0.03343 },
|
181 | { id:6, name:"John", age: 20, createdAt: '2011-10-31', score: 0.03343 },
|
182 | { id:7, name:"Jane", age: 24, createdAt: '20111031' },
|
183 | { id:8, name:"Susan", age: 16, createdAt: '2013-10-31', score: 0.03343 },
|
184 | ],
|
185 | };
|
186 | },
|
187 | };
|
188 | </script>
|
189 | ``` -->
|
190 | <!--
|
191 | ## Configuration
|
192 | ### Component Options
|
193 | #### Table
|
194 | These options relate to the table as a whole
|
195 |
|
196 | ##### columns `Array`
|
197 |
|
198 | Array containing objects that describe table columns. The column object itself can contain many [configurable properties](#column-options).
|
199 | ```javascript
|
200 | [
|
201 | {
|
202 | label: 'Name',
|
203 | field: 'name',
|
204 | filterable: true,
|
205 | }
|
206 | //...
|
207 | ]
|
208 | ```
|
209 |
|
210 | ##### rows `Array`
|
211 |
|
212 | Array containing row objects. Each row object contains data that will be displayed in the table row.
|
213 | ```javascript
|
214 | [
|
215 | {
|
216 | id:1,
|
217 | name:"John",
|
218 | age:20
|
219 | },
|
220 | //...
|
221 | ]
|
222 | ```
|
223 | > for **grouped rows**, you need a nested format. Refer to [Grouped Rows](#grouped-rows) for an example.
|
224 |
|
225 | ##### rtl `Boolean (default: false)`
|
226 |
|
227 | Enable Right-To-Left layout for the table
|
228 | ```html
|
229 | <vue-good-table
|
230 | :columns="columns"
|
231 | :rows="rows"
|
232 | :rtl="true">
|
233 | </vue-good-table>
|
234 | ```
|
235 |
|
236 | ##### lineNumbers `Boolean (default: false)`
|
237 | Show line number for each row
|
238 | ```html
|
239 | <vue-good-table
|
240 | :columns="columns"
|
241 | :rows="rows"
|
242 | :lineNumbers="true">
|
243 | </vue-good-table>
|
244 | ```
|
245 |
|
246 | ##### mode `String`
|
247 | Set mode=`remote` to allow sorting/filtering etc to be powered by server side instead of client side. Setting mode to remote, expects the following workflow:
|
248 |
|
249 | * pagination, sort, filter, search will emit [Table Events](#table-events) (loading div appears)
|
250 | * setup handlers for each event
|
251 | * in the handler call backend endpoints with the table params
|
252 | * update rows object with the returned response ( the loading div will disappear once you update the rows object)
|
253 |
|
254 | for a detailed workflow example check out [The remote mode workflow wiki](https://github.com/xaksis/vue-good-table/wiki/Remote-Mode-Workflow)
|
255 |
|
256 | ```html
|
257 | <vue-good-table
|
258 | :columns="columns"
|
259 | :rows="rows"
|
260 | mode="remote">
|
261 | </vue-good-table>
|
262 | ```
|
263 |
|
264 |
|
265 | #### Sort Options
|
266 | ---
|
267 | Set of options related to table sorting
|
268 | ```html
|
269 | <vue-good-table
|
270 | :columns="columns"
|
271 | :rows="rows"
|
272 | :sort-options="{
|
273 | enabled: true,
|
274 | initialSortBy: {field: 'name', type: 'asc'}
|
275 | }">
|
276 | </vue-good-table>
|
277 | ```
|
278 |
|
279 | ##### sortOptions.enabled `Boolean (default: true)`
|
280 | Enable/disable sorting on table as a whole.
|
281 | ```html
|
282 | <vue-good-table
|
283 | :columns="columns"
|
284 | :rows="rows"
|
285 | :sort-options="{
|
286 | enabled: true,
|
287 | }">
|
288 | </vue-good-table>
|
289 | ```
|
290 |
|
291 | ##### sortOptions.initialSortBy `Object`
|
292 | Allows specifying a default sort for the table on wakeup
|
293 | ```html
|
294 | <vue-good-table
|
295 | :columns="columns"
|
296 | :rows="rows"
|
297 | :sort-options="{
|
298 | enabled: true,
|
299 | initialSortBy: {field: 'name', type: 'asc'}
|
300 | }">
|
301 | </vue-good-table>
|
302 | ```
|
303 |
|
304 | ```javascript
|
305 | // in data
|
306 | defaultSort: {
|
307 | field: 'name',
|
308 | type: 'asc' //asc or desc (default: 'asc')
|
309 | }
|
310 | ```
|
311 |
|
312 | #### Pagination Options
|
313 | ---
|
314 | 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.
|
315 | ```html
|
316 | <vue-good-table
|
317 | :columns="columns"
|
318 | :rows="rows"
|
319 | :paginationOptions="{
|
320 | enabled: true,
|
321 | perPage: 5,
|
322 | position: 'top',
|
323 | perPageDropdown: [3, 7, 9],
|
324 | dropdownAllowAll: false,
|
325 | setCurrentPage: 2,
|
326 | nextLabel: 'next',
|
327 | prevLabel: 'prev',
|
328 | rowsPerPageLabel: 'Rows per page',
|
329 | ofLabel: 'of',
|
330 | allLabel: 'All',
|
331 | }">
|
332 | </vue-good-table>
|
333 | ```
|
334 | Options explained below
|
335 | ##### paginationOptions.enabled `Boolean (default: false)`
|
336 | Enable Pagination for table. By default the paginator is created at the bottom of the table.
|
337 | ```html
|
338 | <vue-good-table
|
339 | :columns="columns"
|
340 | :rows="rows"
|
341 | :paginationOptions="{
|
342 | enabled: true
|
343 | }">
|
344 | </vue-good-table>
|
345 | ```
|
346 |
|
347 | ##### paginationOptions.position `String (default: 'bottom')`
|
348 | Add pagination on `'top'` or `'bottom'` (top and bottom) of the table (default position is bottom)
|
349 | ```html
|
350 | <vue-good-table
|
351 | :columns="columns"
|
352 | :rows="rows"
|
353 | :paginationOptions="{
|
354 | enabled: true,
|
355 | position: 'top'
|
356 | }">
|
357 | </vue-good-table>
|
358 | ```
|
359 |
|
360 | ##### paginationOptions.perPage `Integer (default: 10)`
|
361 | Number of rows to show per page
|
362 | ```html
|
363 | <vue-good-table
|
364 | :columns="columns"
|
365 | :rows="rows"
|
366 | :paginationOptions="{
|
367 | enabled: true,
|
368 | perPage: 5
|
369 | }">
|
370 | </vue-good-table>
|
371 | ```
|
372 |
|
373 | ##### paginationOptions.perPageDropdown `Array (default: [10,20,30,40,50])`
|
374 | Customize the dropdown options for the amount of items per page
|
375 | ```html
|
376 | <vue-good-table
|
377 | :columns="columns"
|
378 | :rows="rows"
|
379 | :paginationOptions="{
|
380 | enabled: true,
|
381 | perPageDropdown: [3, 7, 9]
|
382 | }">
|
383 | </vue-good-table>
|
384 | ```
|
385 |
|
386 | ##### paginationOptions.dropdownAllowAll `Boolean (default: true)`
|
387 | enables/disables 'All' in the per page dropdown.
|
388 | ```html
|
389 | <vue-good-table
|
390 | :columns="columns"
|
391 | :rows="rows"
|
392 | :paginationOptions="{
|
393 | enabled: true,
|
394 | perPageDropdown: [3, 7, 9],
|
395 | dropdownAllowAll: false,
|
396 | }">
|
397 | </vue-good-table>
|
398 | ```
|
399 |
|
400 | ##### paginationOptions.setCurrentPage `Number`
|
401 | set current page programmatically.
|
402 | > There's no validation for number of pages so please be careful using this.
|
403 | ```html
|
404 | <vue-good-table
|
405 | :columns="columns"
|
406 | :rows="rows"
|
407 | :paginationOptions="{
|
408 | enabled: true,
|
409 | setCurrentPage: 2,
|
410 | }">
|
411 | </vue-good-table>
|
412 | ```
|
413 |
|
414 | ##### pagination label/text options
|
415 | you can change one or more of the texts shown on pagination by overriding the labels in the following way:
|
416 | ```html
|
417 | <vue-good-table
|
418 | :columns="columns"
|
419 | :rows="rows"
|
420 | :paginationOptions="{
|
421 | enabled: true,
|
422 | nextLabel: 'next',
|
423 | prevLabel: 'prev',
|
424 | rowsPerPageLabel: 'Rows per page',
|
425 | ofLabel: 'of',
|
426 | allLabel: 'All',
|
427 | }">
|
428 | </vue-good-table>
|
429 | ```
|
430 |
|
431 | #### Search Options
|
432 | ---
|
433 | Set of search related options. These options pertain to the global table search.
|
434 | ```html
|
435 | <vue-good-table
|
436 | :columns="columns"
|
437 | :rows="rows"
|
438 | :searchOptions="{
|
439 | enabled: true,
|
440 | trigger: 'enter',
|
441 | searchFn: mySearchFn,
|
442 | placeholder: 'Search this table',
|
443 | externalQuery: searchQuery
|
444 | }">
|
445 | </vue-good-table>
|
446 | ```
|
447 |
|
448 | Search options explained below
|
449 |
|
450 | ##### searchOptions.enabled `Boolean (default: false)`
|
451 |
|
452 | Allows a single search input for the whole table
|
453 |
|
454 | >Note: enabling this option disables column filters
|
455 | ```html
|
456 | <vue-good-table
|
457 | :columns="columns"
|
458 | :rows="rows"
|
459 | :searchOptions="{
|
460 | enabled: true
|
461 | }">
|
462 | </vue-good-table>
|
463 | ```
|
464 |
|
465 | ##### searchOptions.trigger `String (default: '')`
|
466 | Allows you to specify if you want search to trigger on 'enter' event of the input. By default table searches on key-up.
|
467 |
|
468 | ```html
|
469 | <vue-good-table
|
470 | :columns="columns"
|
471 | :rows="rows"
|
472 | :searchOptions="{
|
473 | enabled: true,
|
474 | trigger: 'enter'
|
475 | }">
|
476 | </vue-good-table>
|
477 | ```
|
478 |
|
479 | ##### searchOptions.searchFn `Function`
|
480 |
|
481 | Allows you to specify your own search function for the global search
|
482 |
|
483 | ```html
|
484 | <vue-good-table
|
485 | :columns="columns"
|
486 | :rows="rows"
|
487 | :searchOptions="{
|
488 | enabled: true,
|
489 | searchFn: myFunc
|
490 | }">
|
491 | </vue-good-table>
|
492 | ```
|
493 | ```javascript
|
494 | // in js
|
495 | methods: {
|
496 | myFunc(row, col, cellValue, searchTerm){
|
497 | return cellValue === 'my value';
|
498 | },
|
499 | }
|
500 | ```
|
501 |
|
502 | ##### searchOptions.placeholder `String (default: 'Search Table')`
|
503 | Text for global search input place holder
|
504 | ```html
|
505 | <vue-good-table
|
506 | :columns="columns"
|
507 | :rows="rows"
|
508 | :searchOptions="{
|
509 | enabled: true,
|
510 | placeholder: 'Search this table',
|
511 | }">
|
512 | </vue-good-table>
|
513 | ```
|
514 |
|
515 | ##### searchOptions.externalQuery `String`
|
516 |
|
517 | If you want to use your own input for searching the table, you can use this property
|
518 |
|
519 | ```html
|
520 | <input type="text" v-model="searchTerm" >
|
521 | <vue-good-table
|
522 | :columns="columns"
|
523 | :rows="rows"
|
524 | :searchOptions="{
|
525 | enabled: true,
|
526 | externalQuery: searchTerm
|
527 | }">
|
528 | </vue-good-table>
|
529 | ```
|
530 | ```javascript
|
531 | // and in data
|
532 | data(){
|
533 | return {
|
534 | searchTerm: '',
|
535 | // rows, columns etc...
|
536 | };
|
537 | }
|
538 | ```
|
539 |
|
540 | #### Checkbox Table
|
541 | Creating table with selectable rows (checkboxes) is easier than ever.
|
542 | ![Checkbox Screenshot](README/images/vgt-table.checkbox.png)
|
543 |
|
544 | ##### selectOptions `Object`
|
545 | Object containing select options
|
546 | ```html
|
547 | <vue-good-table
|
548 | @on-select-all="allSelected"
|
549 | @on-selected-rows-change="onSelectedRowsChange"
|
550 | @on-row-click="rowSelected"
|
551 | :columns="columns"
|
552 | :rows="rows"
|
553 | :selectOptions="{
|
554 | enabled: true,
|
555 | selectOnCheckboxOnly: true, // only select when checkbox is clicked instead of the row
|
556 | selectionInfoClass: 'custom-class',
|
557 | selectionText: 'rows selected',
|
558 | clearSelectionText: 'clear',
|
559 | }">
|
560 | ```
|
561 |
|
562 | you can get the selectedRows listening the [@on-selected-rows-change](#on-selected-rows-change) event.
|
563 |
|
564 |
|
565 | #### Grouped Row Options
|
566 | ---
|
567 | Sometimes you have a hierarchy in table and you want to group rows under subheadings, vue-good-table allows you to do that as well. Following properties relate to row grouping
|
568 |
|
569 | ##### groupOptions `Object`
|
570 | Object containing group related options.
|
571 | ```html
|
572 | <vue-good-table
|
573 | :columns="columns"
|
574 | :rows="rows"
|
575 | :group-options="{
|
576 | enabled: true,
|
577 | headerPosition: 'bottom'
|
578 | }">
|
579 | ```
|
580 | > rows are formatted differently for grouped tables, refer to [Grouped Rows](#grouped-rows) section.
|
581 |
|
582 | #### Style/Theme
|
583 | ---
|
584 | Style options for table
|
585 |
|
586 | ##### styleClass `String (default: 'vgt-table bordered')`
|
587 | Allows applying your own classes to table. Other in-built classes: condensed, striped, bordered
|
588 | ```html
|
589 | <vue-good-table
|
590 | :columns="columns"
|
591 | :rows="rows"
|
592 | styleClass="vgt-table bordered striped">
|
593 | </vue-good-table>
|
594 | ```
|
595 |
|
596 | ##### rowStyleClass `String or Function`
|
597 |
|
598 | Allows providing custom styles for rows. It can be a string: 'my-class' or a function.
|
599 | ```html
|
600 | <vue-good-table
|
601 | :columns="columns"
|
602 | :rows="rows"
|
603 | :rowStyleClass="myStyleFn">
|
604 | </vue-good-table>
|
605 | ```
|
606 | ```javascript
|
607 | // in methods
|
608 | myStyleFn(row){
|
609 | // if row has something return a specific class
|
610 | if(row.fancy) {
|
611 | return 'fancy-class';
|
612 | }
|
613 | return '';
|
614 | }
|
615 | ```
|
616 |
|
617 | ##### theme `String`
|
618 | Allows using other themes.
|
619 | Included themes:
|
620 | * [nocturnal](#nocturnal-themenocturnal)
|
621 | * [black-rhino](#black-rhino-themeblack-rhino)
|
622 |
|
623 | ```html
|
624 | <vue-good-table
|
625 | :columns="columns"
|
626 | :rows="rows"
|
627 | theme="nocturnal">
|
628 | </vue-good-table>
|
629 | ```
|
630 |
|
631 |
|
632 | ### Column Options
|
633 | ---
|
634 | Each column objects can contain the following configuration options:
|
635 |
|
636 |
|
637 | ##### label `String`
|
638 | Text to put on column header.
|
639 |
|
640 | ```javascript
|
641 | columns: [
|
642 | {
|
643 | label: 'name'
|
644 | },
|
645 | // ...
|
646 | ]
|
647 | ```
|
648 |
|
649 | ##### field `String`
|
650 |
|
651 | Row object property that this column corresponds to. This can be:
|
652 |
|
653 | * String <code>eg: 'name'</code> - simple row property name
|
654 | * String <code>eg: 'location.lat'</code>- nested row property name. lets say if the row had a property 'location' which was an object containing 'lat' and 'lon'
|
655 | * Function - a function that returns a value to be displayed based on the row object
|
656 | ```javascript
|
657 | columns: [
|
658 | {
|
659 | label: 'name',
|
660 | field: this.fealdFn,
|
661 | },
|
662 | // ...
|
663 | ]
|
664 | // in methods
|
665 | fieldFn(rowObj) {
|
666 | return rowObj.name;
|
667 | }
|
668 | ```
|
669 |
|
670 | ##### type `String`
|
671 |
|
672 | type of column. default: 'text'. This determines the formatting for the column and filter behavior as well. Possible values:
|
673 | * _number_ - right aligned
|
674 | * _decimal_ - right aligned, 2 decimal places
|
675 | * _percentage_ - expects a decimal like 0.03 and formats it as 3.00%
|
676 | * _boolean_ - right aligned
|
677 | * _date_ - expects a string representation of date eg `'20170530'`. You should also specify [dateInputFormat](#dateinputformat) and [dateOutputFormat](dateoutputformat)
|
678 |
|
679 | ```javascript
|
680 | columns: [
|
681 | {
|
682 | label: 'joined On',
|
683 | field: 'createdAt',
|
684 | type: 'date',
|
685 | dateInputFormat: 'YYYY-MM-DD', // expects 2018-03-16
|
686 | dateOutputFormat: 'MMM Do YYYY', // outputs Mar 16th 2018
|
687 | },
|
688 | // ...
|
689 | ]
|
690 | ```
|
691 |
|
692 | ##### dateInputFormat `String`
|
693 | provide the format to parse date string
|
694 |
|
695 | ##### dateOutputFormat `String`
|
696 | provide the format for output date
|
697 |
|
698 | ##### sortable `Boolean`
|
699 | enable/disable sorting on columns. This property is higher priority than global sortable property
|
700 | ```javascript
|
701 | columns: [
|
702 | {
|
703 | label: 'name',
|
704 | field: 'user_name',
|
705 | sortable: false,
|
706 | },
|
707 | // ...
|
708 | ]
|
709 | ```
|
710 |
|
711 | ##### sortFn `Function`
|
712 |
|
713 | custom sort function. If you want to supply your own sort function you can use this property.
|
714 |
|
715 | ```javascript
|
716 | // in data
|
717 | columns: [
|
718 | {
|
719 | label: 'Name',
|
720 | field: 'name',
|
721 | sortable: true,
|
722 | sortFn: this.sortFn,
|
723 | }
|
724 | //...
|
725 | ],
|
726 | // in methods
|
727 | methods: {
|
728 | sortFn(x, y, col, rowX, rowY) {
|
729 | // x - row1 value for column
|
730 | // y - row2 value for column
|
731 | // col - column being sorted
|
732 | // rowX - row object for row1
|
733 | // rowY - row object for row2
|
734 | return (x < y ? -1 : (x > y ? 1 : 0));
|
735 | }
|
736 | }
|
737 | ```
|
738 |
|
739 | ##### formatFn `Function`
|
740 | Allows for custom format of values, <code>function(value)</code>, should return the formatted value to display.
|
741 |
|
742 | ```javascript
|
743 | // in data
|
744 | columns: [
|
745 | {
|
746 | label: 'Salary',
|
747 | field: 'salary',
|
748 | sortable: true,
|
749 | formatFn: this.formatFn,
|
750 | }
|
751 | //...
|
752 | ],
|
753 | // in methods
|
754 | formatFn: function(value) {
|
755 | return '$' + value;
|
756 | }
|
757 | ```
|
758 |
|
759 | ##### html `Boolean`
|
760 | indicates whether this column will require html rendering.
|
761 | > The preferred way of creating columns that have html is by [using slots](#custom-row-template)
|
762 | ```javascript
|
763 | // in data
|
764 | columns: [
|
765 | {
|
766 | label: 'Action',
|
767 | field: 'btn',
|
768 | html: true,
|
769 | }
|
770 | //...
|
771 | ],
|
772 | rows: [
|
773 | {
|
774 | btn: '<button>My Action</button>',
|
775 | // ...
|
776 | }
|
777 | ]
|
778 | ```
|
779 |
|
780 | ##### width `Number`
|
781 | provide a width value for this column
|
782 |
|
783 | ```javascript
|
784 | columns: [
|
785 | {
|
786 | label: 'name',
|
787 | field: 'user_name',
|
788 | width: '50px',
|
789 | },
|
790 | // ...
|
791 | ]
|
792 | ```
|
793 |
|
794 | ##### hidden `Boolean`
|
795 | hide a column
|
796 | ```javascript
|
797 | columns: [
|
798 | {
|
799 | label: 'name',
|
800 | field: 'user_name',
|
801 | hidden: true,
|
802 | },
|
803 | // ...
|
804 | ]
|
805 | ```
|
806 |
|
807 | ##### thClass `String`
|
808 | provide custom class(es) to the table header
|
809 | ```javascript
|
810 | columns: [
|
811 | {
|
812 | label: 'name',
|
813 | field: 'user_name',
|
814 | thClass: 'custom-th-class',
|
815 | },
|
816 | // ...
|
817 | ]
|
818 | ```
|
819 |
|
820 | ##### tdClass `String`
|
821 | provide custom class(es) to the table cells
|
822 | ```javascript
|
823 | columns: [
|
824 | {
|
825 | label: 'name',
|
826 | field: 'user_name',
|
827 | tdClass: 'text-center',
|
828 | },
|
829 | // ...
|
830 | ]
|
831 | ```
|
832 |
|
833 | ##### globalSearchDisabled `Boolean (default: false)`
|
834 | if true, this column will be ignored by the global search
|
835 | ```javascript
|
836 | columns: [
|
837 | {
|
838 | label: 'name',
|
839 | field: 'user_name',
|
840 | globalSearchDisabled: true,
|
841 | },
|
842 | // ...
|
843 | ]
|
844 | ```
|
845 |
|
846 | ##### filterOptions `Object`
|
847 | A collection of filter specific properties. You can find more about these properties in [column filter options section](#column-filter-option-in-depth)
|
848 |
|
849 | ```javascript
|
850 | columns: [
|
851 | {
|
852 | label: 'name',
|
853 | field: 'user_name',
|
854 | filterOptions: {
|
855 | enabled: true, // enable filter for this column
|
856 | placeholder: 'Filter This Thing', // placeholder for filter input
|
857 | filterValue: 'Jane', // initial populated value for this filter
|
858 | filterDropdownItems: [], // dropdown (with selected values) instead of text input
|
859 | filterFn: this.columnFilterFn, //custom filter function that
|
860 | trigger: 'enter', //only trigger on enter not on keyup
|
861 | },
|
862 | },
|
863 | // ...
|
864 | ]
|
865 | ```
|
866 |
|
867 | #### Column filter option in-depth
|
868 | ---
|
869 | Some filterOption properties need a little more explanation
|
870 |
|
871 | ##### filterDropdownItems `Array of strings or Array of objects`
|
872 | allows creating a dropdown for filter as opposed to an input
|
873 |
|
874 | ```javascript
|
875 | //array
|
876 | filterDropdownItems: ['Blue', 'Red', 'Yellow']
|
877 | //or
|
878 | filterDropdownItems: [
|
879 | { value: 'n', text: 'Inactive' },
|
880 | { value: 'y', text: 'Active' },
|
881 | { value: 'c', text: 'Check' }
|
882 | ],
|
883 | ```
|
884 |
|
885 | ##### filterFn `Function`
|
886 | Custom filter, function of two variables: <code>function(data, filterString)</code>, should return true if data matches the filterString, otherwise false
|
887 |
|
888 | ```javascript
|
889 | filterFn: function(data, filterString) {
|
890 | var x = parseInt(filterString)
|
891 | return data >= x - 5 && data <= x + 5;
|
892 | }
|
893 | // would create a filter matching numbers within 5 of the provided value
|
894 | ```
|
895 |
|
896 | ### Table Events
|
897 |
|
898 | #### @on-row-click
|
899 | event emitted on table row click
|
900 | ```html
|
901 | <vue-good-table
|
902 | :columns="columns"
|
903 | :rows="rows"
|
904 | @on-row-click="onRowClick">
|
905 | ```
|
906 | ```javascript
|
907 | methods: {
|
908 | onRowClick(params) {
|
909 | // params.row - row object
|
910 | // params.pageIndex - index of this row on the current page.
|
911 | // params.selected - if selection is enabled this argument
|
912 | // indicates selected or not
|
913 | // params.event - click event
|
914 | }
|
915 | }
|
916 | ```
|
917 |
|
918 | #### @on-cell-click
|
919 | event emitted on table cell click
|
920 | ```html
|
921 | <vue-good-table
|
922 | :columns="columns"
|
923 | :rows="rows"
|
924 | @on-cell-click="onCellClick">
|
925 | ```
|
926 | ```javascript
|
927 | methods: {
|
928 | onCellClick(params) {
|
929 | // params.row - row object
|
930 | // params.column - column object
|
931 | // params.rowIndex - index of this row on the current page.
|
932 | // params.event - click event
|
933 | }
|
934 | }
|
935 | ```
|
936 |
|
937 | #### @on-row-mouseenter
|
938 | event emitted on row mouseenter
|
939 | ```html
|
940 | <vue-good-table
|
941 | :columns="columns"
|
942 | :rows="rows"
|
943 | @on-row-mouseenter="onRowMouseover">
|
944 | ```
|
945 | ```javascript
|
946 | methods: {
|
947 | onRowMouseover(params) {
|
948 | // params.row - row object
|
949 | // params.pageIndex - index of this row on the current page.
|
950 | }
|
951 | }
|
952 | ```
|
953 |
|
954 | #### @on-row-mouseleave
|
955 | event emitted on table row mouseleave
|
956 | ```html
|
957 | <vue-good-table
|
958 | :columns="columns"
|
959 | :rows="rows"
|
960 | @on-row-mouseleave="onRowMouseleave">
|
961 | ```
|
962 | ```javascript
|
963 | methods: {
|
964 | onRowMouseleave(row, pageIndex) {
|
965 | // row - row object
|
966 | // pageIndex - index of this row on the current page.
|
967 | }
|
968 | }
|
969 | ```
|
970 |
|
971 | #### @on-search
|
972 | event emitted on global search (when global search is enabled)
|
973 | ```html
|
974 | <vue-good-table
|
975 | :columns="columns"
|
976 | :rows="rows"
|
977 | @on-search="onSearch">
|
978 | ```
|
979 | ```javascript
|
980 | methods: {
|
981 | onSearch(params) {
|
982 | // params.searchTerm - term being searched for
|
983 | // params.rowCount - number of rows that match search
|
984 | }
|
985 | }
|
986 | ```
|
987 |
|
988 | #### @on-page-change
|
989 | event emitted on pagination page change (when pagination is enabled)
|
990 | ```html
|
991 | <vue-good-table
|
992 | :columns="columns"
|
993 | :rows="rows"
|
994 | @on-page-change="onPageChange">
|
995 | ```
|
996 | ```javascript
|
997 | methods: {
|
998 | onPageChange(params) {
|
999 | // params.currentPage - current page that pagination is at
|
1000 | // params.currentPerPage - number of items per page
|
1001 | // params.total - total number of items in the table
|
1002 | }
|
1003 | }
|
1004 | ```
|
1005 |
|
1006 | #### @on-per-page-change
|
1007 | event emitted on per page dropdown change (when pagination is enabled)
|
1008 | ```html
|
1009 | <vue-good-table
|
1010 | :columns="columns"
|
1011 | :rows="rows"
|
1012 | @on-per-page-change="onPageChange">
|
1013 | ```
|
1014 | ```javascript
|
1015 | methods: {
|
1016 | onPageChange(params) {
|
1017 | // params.currentPage - current page that pagination is at
|
1018 | // params.currentPerPage - number of items per page
|
1019 | // params.total - total number of items in the table
|
1020 | }
|
1021 | }
|
1022 | ```
|
1023 |
|
1024 | #### @on-sort-change
|
1025 | event emitted on sort change
|
1026 | ```html
|
1027 | <vue-good-table
|
1028 | :columns="columns"
|
1029 | :rows="rows"
|
1030 | @on-sort-change="onSortChange">
|
1031 | ```
|
1032 | ```javascript
|
1033 | methods: {
|
1034 | onSortChange(params) {
|
1035 | // params.sortType - ascending or descending
|
1036 | // params.columnIndex - index of column being sorted
|
1037 | }
|
1038 | }
|
1039 | ```
|
1040 |
|
1041 |
|
1042 | #### @on-select-all
|
1043 | event emitted when all is selected (only emitted for checkbox tables)
|
1044 | ```html
|
1045 | <vue-good-table
|
1046 | :columns="columns"
|
1047 | :rows="rows"
|
1048 | @on-select-all="onSelectAll">
|
1049 | ```
|
1050 | ```javascript
|
1051 | methods: {
|
1052 | onSelectAll(params) {
|
1053 | // params.selected - whether the select-all checkbox is checked or unchecked
|
1054 | // params.selectedRows - all rows that are selected (this page)
|
1055 | }
|
1056 | }
|
1057 | ```
|
1058 |
|
1059 | #on-selected-rows-change
|
1060 | event emitted each time selectedRows has changed
|
1061 | ```html
|
1062 | <vue-good-table
|
1063 | :columns="columns"
|
1064 | :rows="rows"
|
1065 | @on-selected-rows-change="onSelectedRowsChange">
|
1066 | ```
|
1067 | ```javascript
|
1068 | methods: {
|
1069 | onSelectedRowsChange(params) {
|
1070 | // params.selectedRows - all rows that are selected (this page)
|
1071 | }
|
1072 | }
|
1073 | ```
|
1074 |
|
1075 | #### @on-column-filter
|
1076 | event emitted when column is filtered (only emitted for remote mode)
|
1077 | ```html
|
1078 | <vue-good-table
|
1079 | :columns="columns"
|
1080 | :rows="rows"
|
1081 | @on-column-filter="onColumnFilter">
|
1082 | ```
|
1083 | ```javascript
|
1084 | methods: {
|
1085 | onColumnFilter(params) {
|
1086 | // params.columnFilters - filter values for each column in the following format:
|
1087 | // {field1: 'filterTerm', field3: 'filterTerm2')
|
1088 | }
|
1089 | }
|
1090 | ```
|
1091 |
|
1092 | ### Style Options
|
1093 |
|
1094 | 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
|
1095 |
|
1096 | #### .vgt-table
|
1097 | ![Table Screenshot](README/images/vgt-table.regular.png)
|
1098 |
|
1099 | #### .vgt-table .stripped
|
1100 | ![Table Bordered Striped Screenshot](README/images/vgt-table.png)
|
1101 |
|
1102 | #### .vgt-table .condensed
|
1103 | ![Table Bordered Striped Screenshot](README/images/vgt-table.condensed.png)
|
1104 |
|
1105 |
|
1106 | ## Themes
|
1107 |
|
1108 | ### default
|
1109 | ### nocturnal `theme='nocturnal'`
|
1110 | ![Nocturnal Theme Screenshot](README/images/vgt-table.nocturnal.png)
|
1111 |
|
1112 | ### black-rhino `theme='black-rhino'`
|
1113 | ![Black Rhino Theme Screenshot](README/images/vgt-table.black-rhino.png)
|
1114 |
|
1115 | ## Advanced Customization
|
1116 |
|
1117 | ### Custom row template
|
1118 | vue-good-table also supports dynamic td templates where you dictate how to display the cells. Example:
|
1119 | ```html
|
1120 | <vue-good-table
|
1121 | :columns="columns"
|
1122 | :rows="rows">
|
1123 | <template slot="table-row" slot-scope="props">
|
1124 | <span v-if="props.column.field == 'age'">
|
1125 | age: {{props.row.age}}
|
1126 | </span>
|
1127 | <span v-else>
|
1128 | {{props.formattedRow[props.column.field]}}
|
1129 | </span>
|
1130 | </template>
|
1131 | </vue-good-table>
|
1132 | ```
|
1133 | **Note:**
|
1134 | * The original row object can be accessed via `props.row`
|
1135 | * The currently displayed table row index can be accessed via `props.index` .
|
1136 | * The original row index can be accessed via `props.row.originalIndex`. You can then access the original row object by using `rows[props.row.originalIndex]`.
|
1137 | * The column object can be accessed via `props.column`
|
1138 | * You can access the formatted row data (for example - formatted date) via `props.formattedRow`
|
1139 |
|
1140 | ### Custom column headers
|
1141 | Sometimes you might want to use custom column formatting. You can do that in the following way
|
1142 | ```html
|
1143 | <vue-good-table
|
1144 | :columns="columns"
|
1145 | :rows="rows">
|
1146 | <template slot="table-column" slot-scope="props">
|
1147 | <span v-if="props.column.label =='Name'">
|
1148 | <i class="fa fa-address-book"></i> {{props.column.label}}
|
1149 | </span>
|
1150 | <span v-else>
|
1151 | {{props.column.label}}
|
1152 | </span>
|
1153 | </template>
|
1154 | </vue-good-table>
|
1155 | ```
|
1156 |
|
1157 | ### Grouped Rows
|
1158 | To create grouped rows, you need two things.
|
1159 | 1. add groupOptions to table component
|
1160 | ```html
|
1161 | <vue-good-table
|
1162 | :columns="columns"
|
1163 | :rows="rows"
|
1164 | :groupOptions="{
|
1165 | enabled: true
|
1166 | }">
|
1167 | </vue-good-table>
|
1168 | ```
|
1169 |
|
1170 | 2. make sure the rows are formatted correctly. grouped rows need to be nested with headers rows containing rows in their children property. For example:
|
1171 |
|
1172 | ```javascript
|
1173 | rows: [{
|
1174 | mode: 'span', // span means this header will span all columns
|
1175 | label: 'Header Two', // this is the label that'll be used for the header
|
1176 | children: [
|
1177 | { name: 'Chris', age: 55, createdAt: '2011-10-11', score: 0.03343 },
|
1178 | { name: 'Dan', age: 40, createdAt: '2011-10-21', score: 0.03343 },
|
1179 | ]
|
1180 | }]
|
1181 | ```
|
1182 |
|
1183 | 3. sometimes, you might want a summary row instead of a header row. for example if you want to show total score for your group
|
1184 |
|
1185 | ```javascript
|
1186 | rows: [{
|
1187 | name: 'Total', // this is the label that'll be used for the header
|
1188 | age: undefined,
|
1189 | createdAt: undefined,
|
1190 | score: 0.3, // total score here
|
1191 | children: [
|
1192 | { name: 'Chris', age: 55, createdAt: '2011-10-11', score: 0.03343 },
|
1193 | { name: 'Dan', age: 40, createdAt: '2011-10-21', score: 0.03343 },
|
1194 | ]
|
1195 | }]
|
1196 | ```
|
1197 |
|
1198 | 4. if you want the header/summary row to show up at the bottom of the group, you can specify that in the groupOptions property of the table.
|
1199 | ```html
|
1200 | <vue-good-table
|
1201 | :columns="columns"
|
1202 | :rows="rows"
|
1203 | :groupOptions="{
|
1204 | enabled: true,
|
1205 | headerPosition: 'bottom',
|
1206 | }">
|
1207 | </vue-good-table>
|
1208 | ```
|
1209 |
|
1210 | you can check out some live examples on the recipes page:
|
1211 | [vue-good-table Recipes](https://github.com/xaksis/vue-good-table/wiki/Vue-good-table-Recipes-(vue-good-table-2.x))
|
1212 |
|
1213 |
|
1214 | ### Remote Mode
|
1215 | Sometimes you might want to power the table from the backend. Where filtering, paging, sorting etc are done serverside. In order to accomplish that you can follow [The remote mode workflow wiki](https://github.com/xaksis/vue-good-table/wiki/Remote-Mode-Workflow)
|
1216 |
|
1217 | ### Table Actions Slot
|
1218 | 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.
|
1219 |
|
1220 | ```html
|
1221 | <vue-good-table
|
1222 | :columns="columns"
|
1223 | :rows="rows">
|
1224 | <div slot="table-actions">
|
1225 | This will show up on the top right of the table.
|
1226 | </div>
|
1227 | </vue-good-table>
|
1228 | ```
|
1229 |
|
1230 |
|
1231 | ### Empty state slot
|
1232 | You can provide html for empty state slot as well. Example:
|
1233 |
|
1234 | ```html
|
1235 | <vue-good-table
|
1236 | :columns="columns"
|
1237 | :rows="rows">
|
1238 | <div slot="emptystate">
|
1239 | This will show up when there are no columns
|
1240 | </div>
|
1241 | </vue-good-table>
|
1242 | ``` -->
|
1243 |
|
1244 | ## Authors
|
1245 |
|
1246 | * [xaksis](https://github.com/xaksis)
|
1247 | * [Other Contributors](https://github.com/xaksis/vue-good-table/graphs/contributors)
|
1248 |
|
1249 | ## License
|
1250 |
|
1251 | This project is licensed under the MIT License - see the [LICENSE.md](LICENSE) file for details
|
1252 |
|
\ | No newline at end of file |