├── .gitignore
├── docs
├── favicon.png
├── vgt-logo.png
├── hero-image.png
├── vgt-logo-2x.png
├── assets
│ ├── img
│ │ └── search.83621669.svg
│ └── js
│ │ ├── 4.751cd6eb.js
│ │ ├── 5.f9c81e08.js
│ │ ├── 24.e026c190.js
│ │ ├── 20.c7c2a7a6.js
│ │ ├── 23.8a55ba7a.js
│ │ ├── 17.78aa3f39.js
│ │ ├── 21.2dfef136.js
│ │ ├── 22.ec06531f.js
│ │ ├── 38.fc6dd42f.js
│ │ ├── 16.b0065a94.js
│ │ ├── 8.f51d7e4e.js
│ │ ├── 7.3f6cd7fb.js
│ │ ├── 13.941a2941.js
│ │ ├── 19.d6dddf3d.js
│ │ ├── 11.c8a5abb4.js
│ │ ├── 14.00a22c84.js
│ │ ├── 18.23bc9f91.js
│ │ ├── 10.54b5e228.js
│ │ ├── 9.e00df4e4.js
│ │ ├── 12.36cf977b.js
│ │ ├── 15.2193695d.js
│ │ ├── 6.9355beb5.js
│ │ └── 3.e88f9927.js
└── 404.html
├── vp-docs
├── .vuepress
│ ├── theme
│ │ ├── index.js
│ │ ├── layouts
│ │ │ └── Layout.vue
│ │ └── components
│ │ │ ├── UserBitAd.vue
│ │ │ ├── CarbonAds.vue
│ │ │ └── Banner.vue
│ ├── public
│ │ ├── favicon.png
│ │ ├── vgt-logo.png
│ │ ├── hero-image.png
│ │ └── vgt-logo-2x.png
│ ├── dist
│ │ ├── vgt-table.regular.png
│ │ ├── assets
│ │ │ ├── img
│ │ │ │ └── search.83621669.svg
│ │ │ └── js
│ │ │ │ ├── 15.125b08dc.js
│ │ │ │ ├── 16.9e087e7c.js
│ │ │ │ ├── 17.0ee802cb.js
│ │ │ │ ├── 21.6ce211a6.js
│ │ │ │ ├── 19.5eb669bb.js
│ │ │ │ ├── 18.57facccb.js
│ │ │ │ ├── 20.6c61e0f6.js
│ │ │ │ ├── 2.bc66dc77.js
│ │ │ │ └── 4.df9755ec.js
│ │ ├── 404.html
│ │ └── index.html
│ ├── enhanceApp.js
│ ├── components
│ │ ├── other-projects.vue
│ │ ├── basic-table.vue
│ │ ├── rtl-table.vue
│ │ ├── line-numbers-table.vue
│ │ ├── fixed-header.vue
│ │ ├── custom-row.vue
│ │ ├── theme-example.vue
│ │ ├── search-demo.vue
│ │ ├── external-query.vue
│ │ ├── checkbox-table.vue
│ │ ├── pagination-table.vue
│ │ ├── before-after-columns.vue
│ │ ├── grouped-table.vue
│ │ ├── action-slot-table.vue
│ │ ├── grouped-custom-span.vue
│ │ └── grouped-custom.vue
│ └── config.js
├── guide
│ ├── style-configuration
│ │ ├── sass.md
│ │ ├── README.md
│ │ └── style-classes.md
│ ├── configuration
│ │ ├── sort-options.md
│ │ ├── column-filter-options.md
│ │ ├── search-options.md
│ │ ├── README.md
│ │ └── table-events.md
│ ├── advanced
│ │ ├── checkbox-table.md
│ │ ├── remote-workflow.md
│ │ └── grouped-table.md
│ └── README.md
└── README.md
├── .npmignore
├── README
└── images
│ ├── vgt-table.png
│ ├── vgt-table.regular.png
│ ├── vgt-table.advanced.png
│ ├── vgt-table.checkbox.png
│ ├── vgt-table.condensed.png
│ ├── vgt-table.nocturnal.png
│ └── vgt-table.black-rhino.png
├── src
├── styles
│ ├── _condensed.scss
│ ├── _striped.scss
│ ├── _wrap.scss
│ ├── _bordered.scss
│ ├── nocturnal
│ │ ├── _overrides.scss
│ │ └── nocturnal.scss
│ ├── _loading.scss
│ ├── _rtl.scss
│ ├── black-rhino
│ │ ├── _overrides.scss
│ │ └── black-rhino.scss
│ ├── _table.scss
│ ├── polar-bear
│ │ ├── _overrides.scss
│ │ └── polar-bear.scss
│ ├── style.scss
│ ├── _input.scss
│ ├── _variables.scss
│ ├── _utils.scss
│ ├── _compact.scss
│ ├── _control-bar.scss
│ ├── _table-th.scss
│ └── _table-footer.scss
├── components
│ ├── types
│ │ ├── decimal.js
│ │ ├── percentage.js
│ │ ├── index.js
│ │ ├── boolean.js
│ │ ├── number.js
│ │ ├── date.js
│ │ └── default.js
│ ├── utils
│ │ ├── constants.js
│ │ └── sort.js
│ ├── VgtGlobalSearch.vue
│ ├── pagination
│ │ └── VgtPaginationPageInfo.vue
│ └── VgtHeaderRow.vue
└── index.js
├── test
├── unit
│ ├── .eslintrc
│ ├── specs
│ │ ├── types
│ │ │ ├── decimal.spec.js
│ │ │ ├── percentage.spec.js
│ │ │ ├── number.spec.js
│ │ │ ├── date.spec.js
│ │ │ └── default.spec.js
│ │ ├── Pagination.spec.js
│ │ └── Table.spec.js
│ ├── index.js
│ └── karma.conf.js
└── e2e
│ ├── specs
│ └── test.js
│ ├── custom-assertions
│ └── elementCount.js
│ ├── runner.js
│ └── nightwatch.conf.js
├── dev
├── index.html
├── main.js
└── grouped-table.vue
├── .github
└── issue_template.md
├── deploy-docs.sh
├── .eslintrc
├── bili.config.js
├── LICENSE
├── package.json
└── CODE_OF_CONDUCT.md
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | npm-debug.log
3 | node_modules/
4 |
--------------------------------------------------------------------------------
/docs/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaksis/vue-good-table/HEAD/docs/favicon.png
--------------------------------------------------------------------------------
/docs/vgt-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaksis/vue-good-table/HEAD/docs/vgt-logo.png
--------------------------------------------------------------------------------
/docs/hero-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaksis/vue-good-table/HEAD/docs/hero-image.png
--------------------------------------------------------------------------------
/docs/vgt-logo-2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaksis/vue-good-table/HEAD/docs/vgt-logo-2x.png
--------------------------------------------------------------------------------
/vp-docs/.vuepress/theme/index.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extend: '@vuepress/theme-default'
3 | }
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .gitignore
2 | .DS_Store
3 | node_modules/
4 | *.log
5 | dev
6 | src
7 | docs
8 | vp-docs
9 | .babelrc
--------------------------------------------------------------------------------
/README/images/vgt-table.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaksis/vue-good-table/HEAD/README/images/vgt-table.png
--------------------------------------------------------------------------------
/README/images/vgt-table.regular.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaksis/vue-good-table/HEAD/README/images/vgt-table.regular.png
--------------------------------------------------------------------------------
/README/images/vgt-table.advanced.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaksis/vue-good-table/HEAD/README/images/vgt-table.advanced.png
--------------------------------------------------------------------------------
/README/images/vgt-table.checkbox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaksis/vue-good-table/HEAD/README/images/vgt-table.checkbox.png
--------------------------------------------------------------------------------
/README/images/vgt-table.condensed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaksis/vue-good-table/HEAD/README/images/vgt-table.condensed.png
--------------------------------------------------------------------------------
/README/images/vgt-table.nocturnal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaksis/vue-good-table/HEAD/README/images/vgt-table.nocturnal.png
--------------------------------------------------------------------------------
/vp-docs/.vuepress/public/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaksis/vue-good-table/HEAD/vp-docs/.vuepress/public/favicon.png
--------------------------------------------------------------------------------
/vp-docs/.vuepress/public/vgt-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaksis/vue-good-table/HEAD/vp-docs/.vuepress/public/vgt-logo.png
--------------------------------------------------------------------------------
/README/images/vgt-table.black-rhino.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaksis/vue-good-table/HEAD/README/images/vgt-table.black-rhino.png
--------------------------------------------------------------------------------
/vp-docs/.vuepress/public/hero-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaksis/vue-good-table/HEAD/vp-docs/.vuepress/public/hero-image.png
--------------------------------------------------------------------------------
/vp-docs/.vuepress/public/vgt-logo-2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaksis/vue-good-table/HEAD/vp-docs/.vuepress/public/vgt-logo-2x.png
--------------------------------------------------------------------------------
/src/styles/_condensed.scss:
--------------------------------------------------------------------------------
1 | .vgt-table{
2 | &.condensed td, &.condensed th.vgt-row-header{
3 | padding: .4em .4em .4em .4em;
4 | }
5 | }
--------------------------------------------------------------------------------
/src/styles/_striped.scss:
--------------------------------------------------------------------------------
1 | .vgt-table{
2 | &.striped tbody tr:nth-of-type(odd) {
3 | background-color: rgba(51, 68, 109, 0.03);
4 | }
5 | }
--------------------------------------------------------------------------------
/vp-docs/.vuepress/dist/vgt-table.regular.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaksis/vue-good-table/HEAD/vp-docs/.vuepress/dist/vgt-table.regular.png
--------------------------------------------------------------------------------
/src/styles/_wrap.scss:
--------------------------------------------------------------------------------
1 | .vgt-wrap{
2 | position: relative;
3 | }
4 | .vgt-fixed-header{
5 | position: absolute;
6 | z-index: 10;
7 | overflow-x: auto;
8 | }
--------------------------------------------------------------------------------
/test/unit/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "mocha": true
4 | },
5 | "globals": {
6 | "expect": true,
7 | "sinon": true
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/styles/_bordered.scss:
--------------------------------------------------------------------------------
1 | .vgt-table{
2 | &.bordered td, &.bordered th {
3 | border: 1px solid $border-color;
4 | }
5 | &.bordered th.vgt-row-header{
6 | border-bottom: 3px solid $border-color;
7 | }
8 | }
--------------------------------------------------------------------------------
/docs/assets/img/search.83621669.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/vp-docs/.vuepress/dist/assets/img/search.83621669.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/vp-docs/.vuepress/dist/assets/js/15.125b08dc.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[15],{195:function(t,n,e){"use strict";e.r(n);var s=e(0),c=Object(s.a)({},function(){var t=this.$createElement;return(this._self._c||t)("div",{staticClass:"content"})},[],!1,null,null,null);n.default=c.exports}}]);
--------------------------------------------------------------------------------
/src/components/types/decimal.js:
--------------------------------------------------------------------------------
1 | import number from './number';
2 |
3 | const decimal = Object.assign({}, number);
4 |
5 | decimal.format = function (v) {
6 | if (v === undefined || v === null) return '';
7 | return parseFloat(Math.round(v * 100) / 100).toFixed(2);
8 | };
9 |
10 | export default decimal;
11 |
--------------------------------------------------------------------------------
/src/components/types/percentage.js:
--------------------------------------------------------------------------------
1 | import number from './number';
2 |
3 | const percentage = Object.assign({}, number);
4 |
5 | percentage.format = function (v) {
6 | if (v === undefined || v === null) return '';
7 | return `${parseFloat(v * 100).toFixed(2)}%`;
8 | };
9 |
10 | export default percentage;
11 |
--------------------------------------------------------------------------------
/vp-docs/guide/style-configuration/sass.md:
--------------------------------------------------------------------------------
1 | # Sass
2 |
3 | Vue-Good-Table's styling is written in Sass. The source files are made available as part of the npm dependency.
4 |
5 | **Vue-Good-Table's root Sass file:**
6 |
7 | ```scss
8 | @import "../node_modules/vue-good-table/src/styles/style.scss";
9 | ```
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/components/types/index.js:
--------------------------------------------------------------------------------
1 | import * as date from './date';
2 | import * as decimal from './decimal';
3 | import * as number from './number';
4 | import * as percentage from './percentage';
5 | import * as boolean from './boolean';
6 |
7 | export default {
8 | date,
9 | decimal,
10 | number,
11 | percentage,
12 | boolean,
13 | };
14 |
--------------------------------------------------------------------------------
/src/styles/nocturnal/_overrides.scss:
--------------------------------------------------------------------------------
1 | $thead-bg-color-1: #2C394F;
2 | $thead-bg-color-2: #2C394F;
3 | $chevron-color: lighten($thead-bg-color-1, 10%);
4 |
5 | $text-color: #C7CED8;
6 | $secondary-text-color: #8290A7 ;
7 | $border-color: #435169;
8 | $input-border-color: $border-color;
9 |
10 | $table-bg: #324057;
11 | $highlight-color: #445168;
--------------------------------------------------------------------------------
/vp-docs/.vuepress/enhanceApp.js:
--------------------------------------------------------------------------------
1 | import VueGoodTable from '../../src';
2 |
3 | export default ({
4 | Vue, // the version of Vue being used in the VuePress app
5 | options, // the options for the root Vue instance
6 | router, // the router instance for the app
7 | siteData, // site metadata
8 | }) => {
9 | // ...apply enhancements to the app
10 | Vue.use(VueGoodTable);
11 | }
--------------------------------------------------------------------------------
/src/styles/_loading.scss:
--------------------------------------------------------------------------------
1 | .vgt-loading{
2 | position: absolute;
3 | width: 100%;
4 | z-index: 10;
5 | margin-top: 117px;
6 | &__content{
7 | background-color: lighten($link-color, 25%);
8 | color: $link-color;
9 | padding: 7px 30px;
10 | border-radius: 3px;
11 | }
12 | }
13 |
14 | .vgt-inner-wrap.is-loading{
15 | opacity: 0.5;
16 | pointer-events: none;
17 | }
--------------------------------------------------------------------------------
/dev/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | vue-good-table
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/dev/main.js:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line import/no-extraneous-dependencies
2 | import Vue from 'vue';
3 | import App from './App.vue';
4 | // import VueGoodTable from '../dist/vue-good-table.esm';
5 | // import '../dist/vue-good-table.css';
6 | import VueGoodTable from '../src';
7 |
8 | Vue.use(VueGoodTable);
9 |
10 | Vue.config.productionTip = false;
11 |
12 | /* eslint-disable no-new */
13 | new Vue({
14 | el: '#app',
15 | render: h => h(App),
16 | });
17 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import VueGoodTable from './components/Table.vue';
2 |
3 | const VueGoodTablePlugin = {
4 | install(Vue, options) {
5 | Vue.component(VueGoodTable.name, VueGoodTable);
6 | },
7 | };
8 |
9 | // Automatic installation if Vue has been added to the global scope.
10 | if (typeof window !== 'undefined' && window.Vue) {
11 | window.Vue.use(VueGoodTablePlugin);
12 | }
13 |
14 | export default VueGoodTablePlugin;
15 | export { VueGoodTable };
16 |
--------------------------------------------------------------------------------
/src/styles/_rtl.scss:
--------------------------------------------------------------------------------
1 | .vgt-wrap.rtl{
2 | direction: rtl;
3 |
4 | .vgt-table{
5 | thead th, &.condensed thead th {
6 | padding-left: 1.5em;
7 | padding-right: .75em;
8 | }
9 | th.sorting:after,
10 | th.sorting-asc:after{
11 | margin-right: 5px;
12 | margin-left: 0px;
13 | }
14 |
15 | th.sortable:after,
16 | th.sortable:before {
17 | right: inherit;
18 | left: 6px;
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/components/utils/constants.js:
--------------------------------------------------------------------------------
1 | const DEFAULT_SORT_TYPE = 'asc';
2 | const SORT_TYPES = {
3 | Ascending: 'asc',
4 | Descending: 'desc',
5 | None: 'none',
6 | };
7 |
8 | const PAGINATION_MODES = {
9 | Pages: 'pages',
10 | Records: 'records',
11 | };
12 | const DEFAULT_ROWS_PER_PAGE_DROPDOWN = [10, 20, 30, 40, 50];
13 |
14 | export {
15 | DEFAULT_SORT_TYPE,
16 | SORT_TYPES,
17 |
18 | PAGINATION_MODES,
19 | DEFAULT_ROWS_PER_PAGE_DROPDOWN,
20 | };
21 |
--------------------------------------------------------------------------------
/test/unit/specs/types/decimal.spec.js:
--------------------------------------------------------------------------------
1 | import decimalType from '@/components/types/decimal'
2 | import { expect } from 'chai'
3 |
4 | describe('decimal type', () => {
5 | describe('format', () => {
6 | it('should format always with two decimals', () => {
7 | expect(decimalType.format('1')).to.equal('1.00')
8 | })
9 |
10 | it('should cut at two decimals', () => {
11 | expect(decimalType.format('3.14159265359')).to.equal('3.14')
12 | })
13 | })
14 | })
15 |
--------------------------------------------------------------------------------
/src/styles/black-rhino/_overrides.scss:
--------------------------------------------------------------------------------
1 | $thead-bg-color-1: #4c5c79;
2 | $thead-bg-color-2: #4e5d7c;
3 |
4 | $chevron-color: lighten($thead-bg-color-1, 10%);
5 |
6 | $text-color: #dae2f0;
7 | $text-color-td: rgb(73, 81, 94);
8 | $text-shadow-color: lighten(#2C394F, 10%);
9 |
10 | $secondary-text-color: rgb(152, 165, 185) ;
11 | $border-color: #435169;
12 | $border-color-td: #bbc5d6;
13 |
14 | $input-border-color: transparent;
15 | $input-bg: #34445f;
16 |
17 | $table-bg: #dfe5ee;
18 | $highlight-color:#fff;
--------------------------------------------------------------------------------
/docs/assets/js/4.751cd6eb.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[4],{449:function(t,e,n){},493:function(t,e,n){"use strict";n(449)},533:function(t,e,n){"use strict";n.r(e);var i={functional:!0,props:{type:{type:String,default:"tip"},text:String,vertical:{type:String,default:"top"}},render:function(t,e){var n=e.props,i=e.slots;return t("span",{class:["badge",n.type],style:{verticalAlign:n.vertical}},n.text||i().default)}},r=(n(493),n(4)),p=Object(r.a)(i,void 0,void 0,!1,null,"15b7b770",null);e.default=p.exports}}]);
--------------------------------------------------------------------------------
/docs/assets/js/5.f9c81e08.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[5],{450:function(e,t,c){},494:function(e,t,c){"use strict";c(450)},531:function(e,t,c){"use strict";c.r(t);var i={name:"CodeBlock",props:{title:{type:String,required:!0},active:{type:Boolean,default:!1}}},n=(c(494),c(4)),s=Object(n.a)(i,(function(){var e=this.$createElement;return(this._self._c||e)("div",{staticClass:"theme-code-block",class:{"theme-code-block__active":this.active}},[this._t("default")],2)}),[],!1,null,"6d04095e",null);t.default=s.exports}}]);
--------------------------------------------------------------------------------
/src/styles/_table.scss:
--------------------------------------------------------------------------------
1 | table.vgt-table{
2 | font-size: 16px;
3 | border-collapse: collapse;
4 | background-color: $table-bg;
5 | width: 100%;
6 | max-width: 100%;
7 | table-layout: auto;
8 | border: 1px solid $border-color;
9 | & td {
10 | padding: .75em .75em .75em .75em;
11 | vertical-align: top;
12 | border-bottom: 1px solid $border-color;
13 | color: $text-color;
14 | }
15 | & tr.clickable {
16 | cursor: pointer;
17 | &:hover{
18 | background-color: $highlight-color;
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/test/unit/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | Vue.config.productionTip = false
4 |
5 | // require all test files (files that ends with .spec.js)
6 | const testsContext = require.context('./specs', true, /\.spec$/)
7 | testsContext.keys().forEach(testsContext)
8 |
9 | // require all src files except main.js for coverage.
10 | // you can also change this to match only the subset of files that
11 | // you want coverage for.
12 | const srcContext = require.context('../../src', true, /^\.\/(?!index(\.js)?$)/)
13 | srcContext.keys().forEach(srcContext)
14 |
--------------------------------------------------------------------------------
/test/unit/specs/types/percentage.spec.js:
--------------------------------------------------------------------------------
1 | import percentageType from '@/components/types/percentage'
2 |
3 | describe('percentage type', () => {
4 | describe('format', () => {
5 | it('should return the percentage formatted answer if passed over 100%', () => {
6 | var x = '2'
7 | expect(percentageType.format(x)).to.equal('200.00%')
8 | })
9 |
10 | it('should return the percentage formatted answer if passed under 50%', () => {
11 | var x = '.5'
12 | expect(percentageType.format(x)).to.equal('50.00%')
13 | })
14 | })
15 | })
16 |
--------------------------------------------------------------------------------
/src/styles/polar-bear/_overrides.scss:
--------------------------------------------------------------------------------
1 | $thead-bg-color-1: #E4EBF3;
2 | $thead-bg-color-2: #E4EBF3;
3 | $thead-bg-color-3: #f7fafc;
4 |
5 | $header-color: darken(#8395aa, 10%);
6 | $text-color: #394567;
7 | $link-color: #5e72e4;
8 | $focus-color: #4D96FB;
9 | $text-color-td: #525f7f;
10 | $text-shadow-color: lighten(#2C394F, 10%);
11 |
12 | $secondary-text-color: rgb(152, 165, 185) ;
13 | $border-color: #e3e8ee;
14 | $border-color-td: #E4EBF3;
15 |
16 | $input-border-color: transparent;
17 | $input-bg: #34445f;
18 |
19 | $table-bg: #FFFFFF;
20 | $highlight-color:#fff;
21 | $white: #FFFFFF;
--------------------------------------------------------------------------------
/vp-docs/.vuepress/theme/layouts/Layout.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/styles/style.scss:
--------------------------------------------------------------------------------
1 | @import './striped';
2 |
3 | // base table styles
4 | @import './variables';
5 | @import './utils';
6 | @import './wrap';
7 | @import './table';
8 | @import './table-th';
9 | @import './input';
10 | @import './loading';
11 |
12 | // table enhancements
13 | @import './bordered';
14 | @import './rtl';
15 | @import './condensed';
16 | @import './compact';
17 |
18 | // controls on top
19 | @import './control-bar';
20 |
21 | // table footer
22 | @import './table-footer';
23 |
24 | //themes
25 | @import './nocturnal/nocturnal';
26 | @import './black-rhino/black-rhino';
27 | @import './polar-bear/polar-bear';
28 |
--------------------------------------------------------------------------------
/.github/issue_template.md:
--------------------------------------------------------------------------------
1 | ### Issue Type (delete the irrelevant ones)
2 |
3 | - [x] Bug
4 | - [x] Enhancement Request
5 | - [x] Question
6 |
7 | ### Specs
8 | What version are you using?
9 |
10 | What browser?
11 |
12 | ### Expected Behavior
13 | What did you expect to happen?
14 |
15 | ### Actual Behavior
16 | What actually happened?
17 |
18 | ### Steps to Reproduce the Problem
19 | Please detail your steps here
20 |
21 | 1.
22 | 1.
23 | 1.
24 |
25 | ### jsfiddle
26 | If you provide a jsfiddle reproducing the issue, it'll be addressed much faster.
27 | you can use [this as base](https://jsfiddle.net/aks9800/57a2a4ce/)
28 |
29 |
--------------------------------------------------------------------------------
/deploy-docs.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | # abort on errors
4 | set -e
5 |
6 | # build
7 | npm run docs:build
8 |
9 | # navigate into the build output directory
10 | cd docs/.vuepress/dist
11 |
12 | # if you are deploying to a custom domain
13 | # echo 'www.example.com' > CNAME
14 |
15 | git init
16 | git add -A
17 | git commit -m 'deploy'
18 |
19 | # if you are deploying to https://.github.io
20 | # git push -f git@github.com:/.github.io.git master
21 |
22 | # if you are deploying to https://.github.io/
23 | git push -f git@github.com:xaksis/vue-good-table.git master:gh-pages
24 |
25 | cd -
--------------------------------------------------------------------------------
/src/components/types/boolean.js:
--------------------------------------------------------------------------------
1 | import def from './default';
2 |
3 | const boolean = Object.assign({}, def);
4 |
5 | boolean.isRight = true;
6 |
7 | boolean.filterPredicate = function (rowval, filter) {
8 | return boolean.compare(rowval, filter) === 0;
9 | };
10 |
11 |
12 | boolean.compare = function (x, y) {
13 | function cook(d) {
14 | if (typeof d === 'boolean') return d ? 1 : 0;
15 | if (typeof d === 'string') return d === 'true' ? 1 : 0;
16 | return -Infinity;
17 | }
18 |
19 | x = cook(x);
20 | y = cook(y);
21 | if (x < y) return -1;
22 | if (x > y) return 1;
23 | return 0;
24 | };
25 |
26 | export default boolean;
27 |
--------------------------------------------------------------------------------
/test/e2e/specs/test.js:
--------------------------------------------------------------------------------
1 | // For authoring Nightwatch tests, see
2 | // http://nightwatchjs.org/guide#usage
3 |
4 | module.exports = {
5 | 'default e2e tests': function (browser) {
6 | // automatically uses dev Server port from /config.index.js
7 | // default: http://localhost:8080
8 | // see nightwatch.conf.js
9 | const devServer = browser.globals.devServerURL
10 |
11 | browser
12 | .url(devServer)
13 | .waitForElementVisible('#app', 5000)
14 | .assert.elementPresent('.hello')
15 | .assert.containsText('h1', 'Welcome to Your Vue.js App')
16 | .assert.elementCount('img', 1)
17 | .end()
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/styles/_input.scss:
--------------------------------------------------------------------------------
1 |
2 | .vgt-input, .vgt-select{
3 | width: 100%;
4 | height: 32px;
5 | line-height: 1;
6 | display: block;
7 | font-size: 14px;
8 | font-weight: normal;
9 | padding: 6px 12px;
10 | color: $text-color;
11 | border-radius: 4px;
12 | box-sizing: border-box;
13 | background-image: none;
14 | background-color: #fff;
15 | border: 1px solid $input-border-color;
16 | transition: border-color .2s cubic-bezier(.645,.045,.355,1);
17 | &::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */
18 | color: $text-color;
19 | opacity: 0.3; /* Firefox */
20 | }
21 | &:focus{
22 | outline: none;
23 | border-color: $link-color;
24 | }
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/src/styles/_variables.scss:
--------------------------------------------------------------------------------
1 |
2 | // grey ramp
3 | $base-grey: #DCDFE6 !default;
4 | $light-grey: #E4E7ED !default;
5 | $lighter-grey: #EBEEF5 !default;
6 | $extra-light: #F2F6FC !default;
7 |
8 | $table-bg: #FFFFFF !default;
9 | $text-color: #606266 !default;
10 | $secondary-text-color: #909399 !default;
11 | $input-border-color: $base-grey !default;
12 | $border-color: $base-grey !default;
13 | $highlight-color: #F1F5FD !default;
14 |
15 | $thead-bg-color-1: #F4F5F8 !default;
16 | $thead-bg-color-2: #F1F3F6 !default;
17 | // $chevron-color: darken($thead-bg-color-1, 12%);
18 | $chevron-color: #606266;
19 |
20 | // link
21 | $link-color: #409eff;
22 | $notify-bg-color: #fdf9e8;
23 | $notify-fg-color: #b38d28;
--------------------------------------------------------------------------------
/docs/assets/js/24.e026c190.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[24],{514:function(t,e,s){"use strict";s.r(e);var n=["There's nothing here.","How did we get here?","That's a Four-Oh-Four.","Looks like we've got some broken links."],o={methods:{getMsg:function(){return n[Math.floor(Math.random()*n.length)]}}},i=s(4),h=Object(i.a)(o,(function(){var t=this.$createElement,e=this._self._c||t;return e("div",{staticClass:"theme-container"},[e("div",{staticClass:"theme-default-content"},[e("h1",[this._v("404")]),this._v(" "),e("blockquote",[this._v(this._s(this.getMsg()))]),this._v(" "),e("RouterLink",{attrs:{to:"/"}},[this._v("\n Take me home.\n ")])],1)])}),[],!1,null,null,null);e.default=h.exports}}]);
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "airbnb",
4 | "plugin:vue/base"
5 | ],
6 | "rules": {
7 | "func-names": ["error", "never"],
8 | "no-shadow": "off",
9 | "no-unused-vars": "off",
10 | "consistent-return": "off",
11 | "no-param-reassign": "off",
12 | "no-plusplus": "off",
13 | "import/no-unresolved": "off",
14 | "import/extensions": "off",
15 | "no-continue": "off",
16 | "comma-dangle": ["error", {
17 | "arrays": "always-multiline",
18 | "objects": "always-multiline",
19 | "imports": "always-multiline",
20 | "exports": "always-multiline",
21 | "functions": "never"
22 | }]
23 | },
24 | "globals": {
25 | "_": false,
26 | "moment": false
27 | }
28 | }
--------------------------------------------------------------------------------
/src/components/types/number.js:
--------------------------------------------------------------------------------
1 | import def from './default';
2 |
3 | const number = Object.assign({}, def);
4 |
5 | number.isRight = true;
6 |
7 | number.filterPredicate = function (rowval, filter) {
8 | return number.compare(rowval, filter) === 0;
9 | };
10 |
11 |
12 | number.compare = function (x, y) {
13 | function cook(d) {
14 | // if d is null or undefined we give it the smallest
15 | // possible value
16 | if (d === undefined || d === null) return -Infinity;
17 | return d.indexOf('.') >= 0 ? parseFloat(d) : parseInt(d, 10);
18 | }
19 |
20 | x = typeof x === 'number' ? x : cook(x);
21 | y = typeof y === 'number' ? y : cook(y);
22 | if (x < y) return -1;
23 | if (x > y) return 1;
24 | return 0;
25 | };
26 |
27 | export default number;
28 |
--------------------------------------------------------------------------------
/vp-docs/guide/style-configuration/README.md:
--------------------------------------------------------------------------------
1 | # Themes
2 |
3 | ## Default
4 | ```html
5 |
8 |
9 | ```
10 |
11 |
12 | ## Polar-bear
13 | ```html
14 |
18 |
19 | ```
20 |
21 |
22 |
23 | ## Black-rhino
24 | ```html
25 |
29 |
30 | ```
31 |
32 |
33 |
34 | ## Nocturnal
35 |
36 | ```html
37 |
41 |
42 | ```
43 |
--------------------------------------------------------------------------------
/bili.config.js:
--------------------------------------------------------------------------------
1 | const { version } = require('./package');
2 |
3 | const banner = `/**
4 | * vue-good-table v${version}
5 | * (c) 2018-present xaksis
6 | * https://github.com/xaksis/vue-good-table
7 | * Released under the MIT License.
8 | */
9 | `;
10 |
11 | module.exports = {
12 | banner,
13 | output: {
14 | fileName: (context, defaultFileName) => {
15 | if (context.format === 'umd' || context.format === 'umd-min') {
16 | return 'vue-good-table[min].js';
17 | }
18 | return 'vue-good-table.[format].js';
19 | },
20 | moduleName: 'vue-good-table',
21 | format: [
22 | 'cjs',
23 | 'es',
24 | 'umd',
25 | 'umd-min',
26 | ],
27 | },
28 | plugins: {
29 | commonjs: true,
30 | vue: {
31 | css: false,
32 | },
33 | },
34 | bundleNodeModules: true,
35 | };
36 |
--------------------------------------------------------------------------------
/vp-docs/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | home: true
3 | heroImage: /hero-image.png
4 | actionText: Get Started →
5 | actionLink: /guide/
6 | footer: MIT Licensed | Copyright © 2018-present xaksis
7 | ---
8 |
9 |
10 |
11 |
Get Started Quickly
12 |
Get features like sorting / column filtering / paging with minimal setup.
13 |
14 |
15 |
Customizable
16 |
Easily customize anything from table cells to column headers.
17 |
18 |
19 |
Advanced Features
20 |
Leverage checkbox table, grouped rows and remote workflow for your table.
21 |
22 |
23 |
24 |
25 |
26 |
27 |
33 |
--------------------------------------------------------------------------------
/src/styles/_utils.scss:
--------------------------------------------------------------------------------
1 | /* Utility styles
2 | ************************************************/
3 | .vgt-right-align{
4 | text-align: right;
5 | }
6 |
7 | .vgt-left-align{
8 | text-align: left;
9 | }
10 |
11 | .vgt-center-align{
12 | text-align: center;
13 | }
14 |
15 | .vgt-pull-left{
16 | float: left !important;
17 | }
18 |
19 | .vgt-pull-right{
20 | float: right !important;
21 | }
22 |
23 | .vgt-clearfix::after {
24 | display: block;
25 | content: "";
26 | clear: both;
27 | }
28 |
29 | .vgt-responsive {
30 | width: 100%;
31 | overflow-x: auto;
32 | position: relative;
33 | }
34 |
35 | .vgt-text-disabled{
36 | color: $secondary-text-color;
37 | }
38 |
39 | .sr-only {
40 | clip: rect(0 0 0 0);
41 | clip-path: inset(50%);
42 | height: 1px;
43 | overflow: hidden;
44 | position: absolute;
45 | white-space: nowrap;
46 | width: 1px;
47 | }
--------------------------------------------------------------------------------
/src/styles/_compact.scss:
--------------------------------------------------------------------------------
1 | /*responsive compactMode*/
2 | @media (max-width: 576px) {
3 | .vgt-compact {
4 | * {
5 | box-sizing: border-box;
6 | }
7 |
8 | tbody,
9 | tr,
10 | td {
11 | display: block;
12 | width: 100%;
13 | }
14 | thead {
15 | display: none;
16 | }
17 | tr {
18 | margin-bottom: 15px;
19 | }
20 | td {
21 | text-align: right;
22 | position: relative;
23 | &:before {
24 | content: attr(data-label);
25 | position: relative;
26 | float: left;
27 | left: 0;
28 | width: 40%;
29 | padding-left: 10px;
30 | font-weight: bold;
31 | text-align: left;
32 | }
33 | }
34 | th.line-numbers {
35 | width: 100% !important;
36 | display: block;
37 | padding: 0.3em 1em !important;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/test/e2e/custom-assertions/elementCount.js:
--------------------------------------------------------------------------------
1 | // A custom Nightwatch assertion.
2 | // the name of the method is the filename.
3 | // can be used in tests like this:
4 | //
5 | // browser.assert.elementCount(selector, count)
6 | //
7 | // for how to write custom assertions see
8 | // http://nightwatchjs.org/guide#writing-custom-assertions
9 | exports.assertion = function (selector, count) {
10 | this.message = 'Testing if element <' + selector + '> has count: ' + count
11 | this.expected = count
12 | this.pass = function (val) {
13 | return val === this.expected
14 | }
15 | this.value = function (res) {
16 | return res.value
17 | }
18 | this.command = function (cb) {
19 | var self = this
20 | return this.api.execute(function (selector) {
21 | return document.querySelectorAll(selector).length
22 | }, [selector], function (res) {
23 | cb.call(self, res)
24 | })
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/docs/assets/js/20.c7c2a7a6.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[20],{446:function(e,t,n){},490:function(e,t,n){"use strict";n(446)},528:function(e,t,n){"use strict";n.r(t);var a={name:"rtl-table",data:function(){return{columns:[{label:"Name",field:"name",filterOptions:{enabled:!1}},{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}]}},computed:{},methods:{},mounted:function(){},components:{}},o=(n(490),n(4)),r=Object(o.a)(a,(function(){var e=this.$createElement,t=this._self._c||e;return t("div",[t("vue-good-table",{attrs:{columns:this.columns,rows:this.rows,rtl:!0}})],1)}),[],!1,null,null,null);t.default=r.exports}}]);
--------------------------------------------------------------------------------
/docs/assets/js/23.8a55ba7a.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[23],{432:function(t,e,s){},476:function(t,e,s){"use strict";s(432)},542:function(t,e,s){"use strict";s.r(e);s(476);var a=s(4),r=Object(a.a)({},(function(){var t=this,e=t.$createElement,s=t._self._c||e;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("div",{staticClass:"features"},[s("div",{staticClass:"feature"},[s("h2",[t._v("Get Started Quickly")]),t._v(" "),s("p",[t._v("Get features like sorting / column filtering / paging with minimal setup.")])]),t._v(" "),s("div",{staticClass:"feature"},[s("h2",[t._v("Customizable")]),t._v(" "),s("p",[t._v("Easily customize anything from table cells to column headers.")])]),t._v(" "),s("div",{staticClass:"feature"},[s("h2",[t._v("Advanced Features")]),t._v(" "),s("p",[t._v("Leverage checkbox table, grouped rows and remote workflow for your table.")])])]),t._v(" "),s("other-projects")],1)}),[],!1,null,null,null);e.default=r.exports}}]);
--------------------------------------------------------------------------------
/docs/assets/js/17.78aa3f39.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[17],{444:function(e,t,n){},488:function(e,t,n){"use strict";n(444)},526:function(e,t,n){"use strict";n.r(t);var a={name:"line-numbers-table",data:function(){return{columns:[{label:"Name",field:"name",filterOptions:{enabled:!1}},{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}]}},computed:{},methods:{},mounted:function(){},components:{}},o=(n(488),n(4)),r=Object(o.a)(a,(function(){var e=this.$createElement,t=this._self._c||e;return t("div",[t("vue-good-table",{attrs:{columns:this.columns,rows:this.rows,lineNumbers:!0}})],1)}),[],!1,null,null,null);t.default=r.exports}}]);
--------------------------------------------------------------------------------
/src/components/types/date.js:
--------------------------------------------------------------------------------
1 | import { format, parse, isValid, compareAsc } from 'date-fns';
2 | import def from './default';
3 |
4 | const date = Object.assign({}, def);
5 |
6 | date.isRight = true;
7 |
8 | date.compare = function (x, y, column) {
9 | function cook(d) {
10 | if (column && column.dateInputFormat) {
11 | return parse(`${d}`, `${column.dateInputFormat}`, new Date());
12 | }
13 | return d;
14 | }
15 | x = cook(x);
16 | y = cook(y);
17 | if (!isValid(x)) {
18 | return -1;
19 | }
20 | if (!isValid(y)) {
21 | return 1;
22 | }
23 | return compareAsc(x, y);
24 | };
25 |
26 | date.format = function (v, column) {
27 | if (v === undefined || v === null) return '';
28 | // convert to date
29 | const date = parse(v, column.dateInputFormat, new Date());
30 | if (isValid(date)) {
31 | return format(date, column.dateOutputFormat);
32 | }
33 | console.error(`Not a valid date: "${v}"`);
34 | return null;
35 | };
36 |
37 | export default date;
38 |
--------------------------------------------------------------------------------
/docs/assets/js/21.2dfef136.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[21],{447:function(e,t,n){},491:function(e,t,n){"use strict";n(447)},529:function(e,t,n){"use strict";n.r(t);var a={name:"search-demo",props:["trigger"],data:function(){return{columns:[{label:"Name",field:"name",filterOptions:{enabled:!1}},{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}]}},computed:{},methods:{},mounted:function(){},components:{}},r=(n(491),n(4)),o=Object(r.a)(a,(function(){var e=this.$createElement,t=this._self._c||e;return t("div",[t("vue-good-table",{attrs:{"search-options":{enabled:!0,trigger:this.trigger},columns:this.columns,rows:this.rows}})],1)}),[],!1,null,null,null);t.default=o.exports}}]);
--------------------------------------------------------------------------------
/docs/assets/js/22.ec06531f.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[22],{448:function(e,t,a){},492:function(e,t,a){"use strict";a(448)},530:function(e,t,a){"use strict";a.r(t);var n={name:"theme-table",props:["theme","styleClasses"],data:function(){return{columns:[{label:"Name",field:"name",filterOptions:{enabled:!0}},{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}]}},computed:{},methods:{},mounted:function(){},components:{}},s=(a(492),a(4)),l=Object(s.a)(n,(function(){var e=this.$createElement,t=this._self._c||e;return t("div",[t("vue-good-table",{attrs:{columns:this.columns,rows:this.rows,styleClass:this.styleClasses,theme:this.theme}})],1)}),[],!1,null,null,null);t.default=l.exports}}]);
--------------------------------------------------------------------------------
/docs/assets/js/38.fc6dd42f.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[38],{549:function(s,t,e){"use strict";e.r(t);var a=e(4),n=Object(a.a)({},(function(){var s=this,t=s.$createElement,e=s._self._c||t;return e("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[e("h1",{attrs:{id:"sass"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#sass"}},[s._v("#")]),s._v(" Sass")]),s._v(" "),e("p",[s._v("Vue-Good-Table's styling is written in Sass. The source files are made available as part of the npm dependency.")]),s._v(" "),e("p",[e("strong",[s._v("Vue-Good-Table's root Sass file:")])]),s._v(" "),e("div",{staticClass:"language-scss extra-class"},[e("pre",{pre:!0,attrs:{class:"language-scss"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("@import")]),s._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[s._v('"../node_modules/vue-good-table/src/styles/style.scss"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])])])}),[],!1,null,null,null);t.default=n.exports}}]);
--------------------------------------------------------------------------------
/vp-docs/.vuepress/theme/components/UserBitAd.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Do you have a UX team? I Would really appreciate their feedback on my new product -
UserBit
6 |
7 |
8 |
9 |
10 |
11 |
29 |
30 |
49 |
--------------------------------------------------------------------------------
/docs/assets/js/16.b0065a94.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[16],{441:function(e,n,t){},485:function(e,n,t){"use strict";t(441)},523:function(e,n,t){"use strict";t.r(n);var o={name:"grouped-table",props:["options"],data:function(){return{columns:[{label:"Name",field:"name"},{label:"Diet",field:"diet",type:"text"},{label:"Count",field:"count",type:"number"}],rows:[{mode:"span",label:"Mammal",children:[{name:"Elephant",diet:"herbivore",count:5},{name:"Cat",diet:"carnivore",count:28}]},{mode:"span",label:"Reptiles",children:[{name:"Snake",diet:"carnivore",count:40},{name:"lizard",diet:"insectivore",count:34}]},{mode:"span",label:"Fish",children:[{name:"Shark",diet:"carnivore",count:2},{name:"koi",diet:"omnivore",count:14}]}]}},computed:{},methods:{},mounted:function(){},components:{}},i=(t(485),t(4)),a=Object(i.a)(o,(function(){var e=this.$createElement,n=this._self._c||e;return n("div",[n("vue-good-table",{attrs:{columns:this.columns,rows:this.rows,"group-options":this.options,"search-options":{enabled:!0}}})],1)}),[],!1,null,null,null);n.default=a.exports}}]);
--------------------------------------------------------------------------------
/vp-docs/.vuepress/dist/assets/js/16.9e087e7c.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[16],{177:function(e,t,a){},183:function(e,t,a){"use strict";var n=a(177);a.n(n).a},204:function(e,t,a){"use strict";a.r(t);var n={name:"theme-table",props:["theme","styleClasses"],data:function(){return{columns:[{label:"Name",field:"name",filterOptions:{enabled:!0}},{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:"201-10-31:9: 35 am",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}]}},computed:{},methods:{},mounted:function(){},components:{}},s=(a(183),a(0)),l=Object(s.a)(n,function(){var e=this.$createElement,t=this._self._c||e;return t("div",[t("vue-good-table",{attrs:{columns:this.columns,rows:this.rows,styleClass:this.styleClasses,theme:this.theme}})],1)},[],!1,null,null,null);t.default=l.exports}}]);
--------------------------------------------------------------------------------
/vp-docs/.vuepress/dist/assets/js/17.0ee802cb.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[17],{178:function(e,n,t){},184:function(e,n,t){"use strict";var o=t(178);t.n(o).a},205:function(e,n,t){"use strict";t.r(n);var o={name:"grouped-table",props:["options"],data:function(){return{columns:[{label:"Name",field:"name"},{label:"Diet",field:"diet",type:"text"},{label:"Count",field:"count",type:"number"}],rows:[{mode:"span",label:"Mammal",children:[{name:"Elephant",diet:"herbivore",count:5},{name:"Cat",diet:"carnivore",count:28}]},{mode:"span",label:"Reptiles",children:[{name:"Snake",diet:"carnivore",count:40},{name:"lizard",diet:"insectivore",count:34}]},{mode:"span",label:"Fish",children:[{name:"Shark",diet:"carnivore",count:2},{name:"koi",diet:"omnivore",count:14}]}]}},computed:{},methods:{},mounted:function(){},components:{}},i=(t(184),t(0)),a=Object(i.a)(o,function(){var e=this.$createElement,n=this._self._c||e;return n("div",[n("vue-good-table",{attrs:{columns:this.columns,rows:this.rows,"group-options":this.options,"search-options":{enabled:!0}}})],1)},[],!1,null,null,null);n.default=a.exports}}]);
--------------------------------------------------------------------------------
/docs/assets/js/8.f51d7e4e.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[8],{433:function(e,t,a){},477:function(e,t,a){"use strict";a(433)},515:function(e,t,a){"use strict";a.r(t);var n={name:"basic-table",props:[],data:function(){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:function(){},components:{}},o=(a(477),a(4)),r=Object(o.a)(n,(function(){var e=this.$createElement,t=this._self._c||e;return t("div",[t("vue-good-table",{attrs:{columns:this.columns,rows:this.rows}})],1)}),[],!1,null,null,null);t.default=r.exports}}]);
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/docs/assets/js/7.3f6cd7fb.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[7],{434:function(t,e,n){},478:function(t,e,n){"use strict";n(434)},516:function(t,e,n){"use strict";n.r(e);var a={name:"action-slot-table",data:function(){return{columns:[{label:"Name",field:"name",filterOptions:{enabled:!1}},{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}]}},computed:{},methods:{},mounted:function(){},components:{}},o=(n(478),n(4)),s=Object(o.a)(a,(function(){var t=this.$createElement,e=this._self._c||t;return e("div",[e("vue-good-table",{attrs:{columns:this.columns,rows:this.rows}},[e("div",{attrs:{slot:"table-actions"},slot:"table-actions"},[e("button",{staticClass:"button"},[this._v("Button 1")]),this._v(" "),e("button",{staticClass:"button"},[this._v("Button 2")])])])],1)}),[],!1,null,null,null);e.default=s.exports}}]);
--------------------------------------------------------------------------------
/test/unit/karma.conf.js:
--------------------------------------------------------------------------------
1 | // This is a karma config file. For more details see
2 | // http://karma-runner.github.io/0.13/config/configuration-file.html
3 | // we are also using it with karma-webpack
4 | // https://github.com/webpack/karma-webpack
5 |
6 | var webpackConfig = require('../../build/webpack.test.conf')
7 |
8 | module.exports = function (config) {
9 | config.set({
10 | // to run in additional browsers:
11 | // 1. install corresponding karma launcher
12 | // http://karma-runner.github.io/0.13/config/browsers.html
13 | // 2. add it to the `browsers` array below.
14 | browsers: ['PhantomJS'],
15 | frameworks: ['mocha', 'sinon-chai', 'phantomjs-shim'],
16 | reporters: ['spec', 'coverage'],
17 | files: ['./index.js'],
18 | preprocessors: {
19 | './index.js': ['webpack', 'sourcemap']
20 | },
21 | webpack: webpackConfig,
22 | webpackMiddleware: {
23 | noInfo: true
24 | },
25 | coverageReporter: {
26 | dir: './coverage',
27 | reporters: [
28 | { type: 'lcov', subdir: '.' },
29 | { type: 'text-summary' }
30 | ]
31 | }
32 | })
33 | }
34 |
--------------------------------------------------------------------------------
/vp-docs/.vuepress/dist/assets/js/21.6ce211a6.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[21],{182:function(e,t,a){},188:function(e,t,a){"use strict";var n=a(182);a.n(n).a},208:function(e,t,a){"use strict";a.r(t);var n={name:"basic-table",props:[],data:function(){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:"201-10-31:9: 35 am",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:function(){},components:{}},r=(a(188),a(0)),o=Object(r.a)(n,function(){var e=this.$createElement,t=this._self._c||e;return t("div",[t("vue-good-table",{attrs:{columns:this.columns,rows:this.rows}})],1)},[],!1,null,null,null);t.default=o.exports}}]);
--------------------------------------------------------------------------------
/docs/assets/js/13.941a2941.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[13],{439:function(e,t,a){},483:function(e,t,a){"use strict";a(439)},521:function(e,t,a){"use strict";a.r(t);var n={name:"fixed-header",props:[],data:function(){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:function(){},components:{}},r=(a(483),a(4)),d=Object(r.a)(n,(function(){var e=this.$createElement,t=this._self._c||e;return t("div",[t("vue-good-table",{attrs:{columns:this.columns,rows:this.rows,"max-height":"200px","fixed-header":!0}})],1)}),[],!1,null,null,null);t.default=d.exports}}]);
--------------------------------------------------------------------------------
/docs/assets/js/19.d6dddf3d.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[19],{445:function(e,t,a){},489:function(e,t,a){"use strict";a(445)},527:function(e,t,a){"use strict";a.r(t);var n={name:"pagination-table",props:["options"],data:function(){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:function(){},components:{}},o=(a(489),a(4)),r=Object(o.a)(n,(function(){var e=this.$createElement,t=this._self._c||e;return t("div",[t("vue-good-table",{attrs:{columns:this.columns,rows:this.rows,"pagination-options":this.options}})],1)}),[],!1,null,null,null);t.default=r.exports}}]);
--------------------------------------------------------------------------------
/docs/assets/js/11.c8a5abb4.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[11],{437:function(e,t,n){},481:function(e,t,n){"use strict";n(437)},519:function(e,t,n){"use strict";n.r(t);var o={name:"custom-row",props:[],data:function(){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}]}},computed:{},methods:{},mounted:function(){},components:{}},a=(n(481),n(4)),r=Object(a.a)(o,(function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",[n("vue-good-table",{attrs:{columns:e.columns,rows:e.rows},scopedSlots:e._u([{key:"table-row",fn:function(t){return["age"==t.column.field?n("span",[n("span",{staticStyle:{"font-weight":"bold",color:"blue"}},[e._v(e._s(t.row.age))])]):n("span",[e._v("\n "+e._s(t.formattedRow[t.column.field])+"\n ")])]}}])})],1)}),[],!1,null,null,null);t.default=r.exports}}]);
--------------------------------------------------------------------------------
/vp-docs/.vuepress/dist/assets/js/19.5eb669bb.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[19],{180:function(e,t,n){},186:function(e,t,n){"use strict";var o=n(180);n.n(o).a},207:function(e,t,n){"use strict";n.r(t);var o={name:"checkbox-table",props:[],data:function(){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:"201-10-31:9: 35 am",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}]}},computed:{},methods:{selectAll:function(e){console.log(e)},toggleSelectRow:function(e){console.log(e)}},mounted:function(){},components:{}},l=(n(186),n(0)),a=Object(l.a)(o,function(){var e=this.$createElement,t=this._self._c||e;return t("div",[t("vue-good-table",{attrs:{columns:this.columns,rows:this.rows,"select-options":{enabled:!0},"search-options":{enabled:!0}},on:{"on-select-all":this.selectAll,"on-row-click":this.toggleSelectRow}})],1)},[],!1,null,null,null);t.default=a.exports}}]);
--------------------------------------------------------------------------------
/docs/assets/js/14.00a22c84.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[14],{440:function(e,n,t){},484:function(e,n,t){"use strict";t(440)},522:function(e,n,t){"use strict";t.r(n);var o={name:"grouped-custom-span",props:["options"],data:function(){return{columns:[{label:"Name",field:"name"},{label:"Diet",field:"diet",type:"text"},{label:"Count",field:"count",type:"number"}],rows:[{mode:"span",label:"Mammal",children:[{name:"Elephant",diet:"herbivore",count:5},{name:"Cat",diet:"carnivore",count:28}]},{mode:"span",label:"Reptiles",children:[{name:"Snake",diet:"carnivore",count:40},{name:"lizard",diet:"insectivore",count:34}]},{mode:"span",label:"Fish",children:[{name:"Shark",diet:"carnivore",count:2},{name:"koi",diet:"omnivore",count:14}]}]}},computed:{},methods:{},mounted:function(){},components:{}},a=(t(484),t(4)),i=Object(a.a)(o,(function(){var e=this,n=e.$createElement,t=e._self._c||n;return t("div",[t("vue-good-table",{attrs:{columns:e.columns,rows:e.rows,"group-options":e.options,"search-options":{enabled:!0}},scopedSlots:e._u([{key:"table-header-row",fn:function(n){return[t("span",{staticClass:"my-fancy-class"},[e._v("\n "+e._s(n.row.label)+"\n ")])]}}])})],1)}),[],!1,null,null,null);n.default=i.exports}}]);
--------------------------------------------------------------------------------
/vp-docs/.vuepress/dist/assets/js/18.57facccb.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[18],{179:function(e,t,n){},185:function(e,t,n){"use strict";var a=n(179);n.n(a).a},206:function(e,t,n){"use strict";n.r(t);var a={name:"custom-row",props:[],data:function(){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:"201-10-31:9: 35 am",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}]}},computed:{},methods:{},mounted:function(){},components:{}},o=(n(185),n(0)),r=Object(o.a)(a,function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",[n("vue-good-table",{attrs:{columns:e.columns,rows:e.rows},scopedSlots:e._u([{key:"table-row",fn:function(t){return["age"==t.column.field?n("span",[n("span",{staticStyle:{"font-weight":"bold",color:"blue"}},[e._v(e._s(t.row.age))])]):n("span",[e._v("\n "+e._s(t.formattedRow[t.column.field])+"\n ")])]}}])})],1)},[],!1,null,null,null);t.default=r.exports}}]);
--------------------------------------------------------------------------------
/test/unit/specs/types/number.spec.js:
--------------------------------------------------------------------------------
1 | import numberType from '@/components/types/number'
2 |
3 | describe('number type', () => {
4 | describe('compare', () => {
5 | it('should return 1 if x > y for integers', () => {
6 | expect(numberType.compare('2', '1')).to.equal(1)
7 | })
8 |
9 | it('should return 1 if x > y for float', () => {
10 | expect(numberType.compare('1.2', '1.1')).to.equal(1)
11 | })
12 |
13 | it('should return 1 if x > y for float', () => {
14 | expect(numberType.compare('1.2', '1.1')).to.equal(1)
15 | })
16 |
17 | it('should return 1 if x > y for float', () => {
18 | expect(numberType.compare(1.2, 1.1)).to.equal(1)
19 | })
20 | })
21 | describe('filterPredicate', () => {
22 | it('should return true only in case of exact equality', () => {
23 | expect(numberType.filterPredicate('1.2', '1.2')).to.equal(true)
24 | })
25 |
26 | it('should return true only in case of numeric equality', () => {
27 | expect(numberType.filterPredicate('1.2', '1.20')).to.equal(true)
28 | })
29 |
30 | it('should return false else', () => {
31 | expect(numberType.filterPredicate('1.2', '12')).to.equal(false)
32 | })
33 | })
34 | })
35 |
--------------------------------------------------------------------------------
/vp-docs/.vuepress/components/other-projects.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
You might also like
4 |
5 |
6 |
7 |
An easy to use and clean VueJS step wizard plugin.
8 |
9 |
10 |
11 |
A light, expandable link and text hover effect library for VueJS.
12 |
13 |
14 |
15 |
Cloud-based platform for UX and Product teams.
16 |
17 |
18 |
19 |
20 |
21 |
39 |
40 |
48 |
--------------------------------------------------------------------------------
/test/e2e/runner.js:
--------------------------------------------------------------------------------
1 | // 1. start the dev server using production config
2 | process.env.NODE_ENV = 'testing'
3 | var server = require('../../build/dev-server.js')
4 |
5 | server.ready.then(() => {
6 | // 2. run the nightwatch test suite against it
7 | // to run in additional browsers:
8 | // 1. add an entry in test/e2e/nightwatch.conf.json under "test_settings"
9 | // 2. add it to the --env flag below
10 | // or override the environment flag, for example: `npm run e2e -- --env chrome,firefox`
11 | // For more information on Nightwatch's config file, see
12 | // http://nightwatchjs.org/guide#settings-file
13 | var opts = process.argv.slice(2)
14 | if (opts.indexOf('--config') === -1) {
15 | opts = opts.concat(['--config', 'test/e2e/nightwatch.conf.js'])
16 | }
17 | if (opts.indexOf('--env') === -1) {
18 | opts = opts.concat(['--env', 'chrome'])
19 | }
20 |
21 | var spawn = require('cross-spawn')
22 | var runner = spawn('./node_modules/.bin/nightwatch', opts, { stdio: 'inherit' })
23 |
24 | runner.on('exit', function (code) {
25 | server.close()
26 | process.exit(code)
27 | })
28 |
29 | runner.on('error', function (err) {
30 | server.close()
31 | throw err
32 | })
33 | })
34 |
--------------------------------------------------------------------------------
/docs/assets/js/18.23bc9f91.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[18],{443:function(t,e,s){},487:function(t,e,s){"use strict";s(443)},525:function(t,e,s){"use strict";s.r(e);var a={name:"other-projects",props:[],data:function(){return{}},computed:{},methods:{},mounted:function(){},components:{}},i=(s(487),s(4)),o=Object(i.a)(a,(function(){var t=this.$createElement;this._self._c;return this._m(0)}),[function(){var t=this,e=t.$createElement,s=t._self._c||e;return s("div",[s("h4",[t._v("You might also like")]),t._v(" "),s("div",{staticClass:"features"},[s("div",{staticClass:"feature"},[s("h2",[s("a",{attrs:{href:"https://github.com/xaksis/vue-good-wizard"}},[t._v("vue-good-wizard")])]),t._v(" "),s("p",[t._v("An easy to use and clean VueJS step wizard plugin.")])]),t._v(" "),s("div",{staticClass:"feature"},[s("h2",[s("a",{attrs:{href:"https://github.com/xaksis/vue-good-links"}},[t._v("vue-good-links")])]),t._v(" "),s("p",[t._v("A light, expandable link and text hover effect library for VueJS.")])]),t._v(" "),s("div",{staticClass:"feature"},[s("h2",[s("a",{attrs:{href:"https://userbitapp.com"}},[t._v("UserBit")])]),t._v(" "),s("p",[t._v("Cloud-based platform for UX and Product teams.")])])])])}],!1,null,"e0df4b64",null);e.default=o.exports}}]);
--------------------------------------------------------------------------------
/test/e2e/nightwatch.conf.js:
--------------------------------------------------------------------------------
1 | require('babel-register')
2 | var config = require('../../config')
3 |
4 | // http://nightwatchjs.org/gettingstarted#settings-file
5 | module.exports = {
6 | src_folders: ['test/e2e/specs'],
7 | output_folder: 'test/e2e/reports',
8 | custom_assertions_path: ['test/e2e/custom-assertions'],
9 |
10 | selenium: {
11 | start_process: true,
12 | server_path: require('selenium-server').path,
13 | host: '127.0.0.1',
14 | port: 4444,
15 | cli_args: {
16 | 'webdriver.chrome.driver': require('chromedriver').path
17 | }
18 | },
19 |
20 | test_settings: {
21 | default: {
22 | selenium_port: 4444,
23 | selenium_host: 'localhost',
24 | silent: true,
25 | globals: {
26 | devServerURL: 'http://localhost:' + (process.env.PORT || config.dev.port)
27 | }
28 | },
29 |
30 | chrome: {
31 | desiredCapabilities: {
32 | browserName: 'chrome',
33 | javascriptEnabled: true,
34 | acceptSslCerts: true
35 | }
36 | },
37 |
38 | firefox: {
39 | desiredCapabilities: {
40 | browserName: 'firefox',
41 | javascriptEnabled: true,
42 | acceptSslCerts: true
43 | }
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/components/types/default.js:
--------------------------------------------------------------------------------
1 | import { diacriticless } from '../utils/diacritics';
2 |
3 | const escapeRegExp = str => str.replace(/[\\^$*+?.()|[\]{}]/g, '\\$&');
4 |
5 | export default {
6 | format(x) {
7 | return x;
8 | },
9 | filterPredicate(rowval, filter, skipDiacritics = false, fromDropdown = false) {
10 | // take care of nulls
11 | if (typeof rowval === 'undefined' || rowval === null) {
12 | return false;
13 | }
14 |
15 | // row value
16 | const rowValue = skipDiacritics
17 | ? String(rowval).toLowerCase()
18 | : diacriticless(escapeRegExp(String(rowval)).toLowerCase());
19 |
20 | // search term
21 | const searchTerm = skipDiacritics
22 | ? filter.toLowerCase()
23 | : diacriticless(escapeRegExp(filter).toLowerCase());
24 |
25 | // comparison
26 | return fromDropdown ? rowValue === searchTerm : (rowValue.indexOf(searchTerm) > -1);
27 | },
28 |
29 | compare(x, y) {
30 | function cook(d) {
31 | if (typeof d === 'undefined' || d === null) return '';
32 | return diacriticless(String(d).toLowerCase());
33 | }
34 | x = cook(x);
35 | y = cook(y);
36 | if (x < y) return -1;
37 | if (x > y) return 1;
38 | return 0;
39 | },
40 | };
41 |
--------------------------------------------------------------------------------
/test/unit/specs/types/date.spec.js:
--------------------------------------------------------------------------------
1 | import dateType from '@/components/types/date'
2 |
3 | describe('date type', () => {
4 | describe('compare', () => {
5 | it('should compare dates correctly', () => {
6 | expect(dateType.compare('20001211', '20001112')).to.equal(1)
7 | })
8 |
9 | it('should compare dates correctly with custom format', () => {
10 | expect(dateType.compare('20001211', '20001112', {inputFormat: 'YYYYDDMM'})).to.equal(-1)
11 | })
12 |
13 | it('should compare null date as epoch', () => {
14 | expect(dateType.compare('20001211', undefined, {inputFormat: 'YYYYDDMM'})).to.equal(1)
15 | })
16 |
17 | it('should compare null date as epoch', () => {
18 | expect(dateType.compare(undefined, '20001211', {inputFormat: 'YYYYDDMM'})).to.equal(-1)
19 | })
20 | })
21 |
22 | describe('format', () => {
23 | it('should format dates correctly', () => {
24 | expect(dateType.format('20001012', {inputFormat: 'YYYYDDMM', outputFormat: 'Do MMM YYYY'})).to.equal('10th Dec 2000')
25 | })
26 |
27 | it('should format dates correctly', () => {
28 | expect(dateType.format('20001012', {inputFormat: 'YYYYMMDD', outputFormat: 'Do MMM YYYY'})).to.equal('12th Oct 2000')
29 | })
30 | })
31 | })
32 |
--------------------------------------------------------------------------------
/docs/assets/js/10.54b5e228.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[10],{436:function(e,t,o){},480:function(e,t,o){"use strict";o(436)},518:function(e,t,o){"use strict";o.r(t);var n={name:"checkbox-table",props:["showSlot"],data:function(){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}]}},computed:{},methods:{selectAll:function(e){console.log(e)},toggleSelectRow:function(e){console.log(e)}},mounted:function(){},components:{}},s=(o(480),o(4)),l=Object(s.a)(n,(function(){var e=this.$createElement,t=this._self._c||e;return t("div",[t("vue-good-table",{attrs:{columns:this.columns,rows:this.rows,"select-options":{enabled:!0},"search-options":{enabled:!0}},on:{"on-selected-rows-change":this.toggleSelectRow}},[this.showSlot?t("div",{attrs:{slot:"selected-row-actions"},slot:"selected-row-actions"},[t("button",[this._v("Action 1")])]):this._e()])],1)}),[],!1,null,null,null);t.default=l.exports}}]);
--------------------------------------------------------------------------------
/docs/assets/js/9.e00df4e4.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[9],{435:function(e,t,n){},479:function(e,t,n){"use strict";n(435)},517:function(e,t,n){"use strict";n.r(t);var a={name:"before-after-columns",props:[],data:function(){return{columns:[{label:"Before",field:"before"},{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"},{label:"After",field:"after"}],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}]}},computed:{},methods:{},mounted:function(){},components:{}},o=(n(479),n(4)),r=Object(o.a)(a,(function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",[n("vue-good-table",{attrs:{columns:e.columns,rows:e.rows},scopedSlots:e._u([{key:"table-row",fn:function(t){return["before"==t.column.field?n("span",[e._v("\n before\n ")]):"after"==t.column.field?n("span",[e._v("\n after\n ")]):n("span",[e._v("\n "+e._s(t.formattedRow[t.column.field])+"\n ")])]}}])})],1)}),[],!1,null,null,null);t.default=r.exports}}]);
--------------------------------------------------------------------------------
/docs/assets/js/12.36cf977b.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[12],{438:function(e,t,n){},482:function(e,t,n){"use strict";n(438)},520:function(e,t,n){"use strict";n.r(t);var a={name:"external-query",props:[],data:function(){return{externalQuery:"",columns:[{label:"Name",field:"name",filterOptions:{enabled:!1}},{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}]}},computed:{},methods:{},mounted:function(){},components:{}},r=(n(482),n(4)),o=Object(r.a)(a,(function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",[e._v("\n External Query "),n("input",{directives:[{name:"model",rawName:"v-model",value:e.externalQuery,expression:"externalQuery"}],attrs:{type:"text"},domProps:{value:e.externalQuery},on:{input:function(t){t.target.composing||(e.externalQuery=t.target.value)}}}),e._v(" "),n("vue-good-table",{attrs:{"search-options":{enabled:!0,externalQuery:e.externalQuery},columns:e.columns,rows:e.rows}})],1)}),[],!1,null,null,null);t.default=o.exports}}]);
--------------------------------------------------------------------------------
/test/unit/specs/types/default.spec.js:
--------------------------------------------------------------------------------
1 | import defaultType from '@/components/types/default'
2 |
3 | describe('default type', () => {
4 | describe('compare', () => {
5 | it('should return -1 if x is before y', () => {
6 | expect(defaultType.compare('abc', 'abd')).to.equal(-1)
7 | })
8 |
9 | it('should return 1 if y is before x', () => {
10 | expect(defaultType.compare('aba', 'aaa')).to.equal(1)
11 | })
12 |
13 | it('should return 0 if y == x', () => {
14 | expect(defaultType.compare('aba', 'aba')).to.equal(0)
15 | })
16 | })
17 | describe('format', () => {
18 | it('should return itself', () => {
19 | var x = 'lorem ipsum
'
20 | expect(defaultType.format(x)).to.equal(x)
21 | })
22 | })
23 | describe('filterPredicate', () => {
24 | it('should return false if values don\'t match', () => {
25 | expect(defaultType.filterPredicate('aBc', 'aBcD')).to.equal(false)
26 | })
27 |
28 | it('should return true if values match', () => {
29 | expect(defaultType.filterPredicate('aBc', 'aBc')).to.equal(true)
30 | })
31 |
32 | it('should return true if values match, even if they are mismatch on case', () => {
33 | expect(defaultType.filterPredicate('aBc', 'AbC')).to.equal(true)
34 | })
35 | })
36 | })
37 |
--------------------------------------------------------------------------------
/vp-docs/.vuepress/dist/assets/js/20.6c61e0f6.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[20],{181:function(e,n,t){},187:function(e,n,t){"use strict";var a=t(181);t.n(a).a},209:function(e,n,t){"use strict";t.r(n);var a={name:"before-after-columns",props:[],data:function(){return{columns:[{label:"Before",field:"before"},{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"},{label:"After",field:"after"}],rows:[{id:1,name:"John",age:20,createdAt:"201-10-31:9: 35 am",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}]}},computed:{},methods:{},mounted:function(){},components:{}},o=(t(187),t(0)),r=Object(o.a)(a,function(){var e=this,n=e.$createElement,t=e._self._c||n;return t("div",[t("vue-good-table",{attrs:{columns:e.columns,rows:e.rows},scopedSlots:e._u([{key:"table-row",fn:function(n){return["before"==n.column.field?t("span",[e._v("\n before\n ")]):"after"==n.column.field?t("span",[e._v("\n after\n ")]):t("span",[e._v("\n "+e._s(n.formattedRow[n.column.field])+"\n ")])]}}])})],1)},[],!1,null,null,null);n.default=r.exports}}]);
--------------------------------------------------------------------------------
/vp-docs/guide/style-configuration/style-classes.md:
--------------------------------------------------------------------------------
1 | # Style Classes
2 |
3 | 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.
4 |
5 | ::: tip NOTE
6 | by default, tables have 'vgt-table striped bordered'
7 | :::
8 |
9 | ## .vgt-table
10 | Base class that initializes all the core styles for the table.
11 | ```vue{4}
12 |
16 |
17 | ```
18 |
19 |
20 | ## .vgt-table .striped
21 | Add row striping in your data table.
22 | ```vue{4}
23 |
27 |
28 | ```
29 |
30 |
31 | ## .vgt-table .bordered
32 | Add borders to columns/rows
33 | ```vue{4}
34 |
38 |
39 | ```
40 |
41 |
42 | ## .vgt-table .condensed
43 | Have lots of rows? use condensed class to get more compact rows.
44 | ```vue{4}
45 |
49 |
50 | ```
51 |
--------------------------------------------------------------------------------
/docs/assets/js/15.2193695d.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[15],{442:function(n,e,t){},486:function(n,e,t){"use strict";t(442)},524:function(n,e,t){"use strict";t.r(e);var o={name:"grouped-custom",props:["options"],data:function(){return{columns:[{label:"Name",field:"name"},{label:"Diet",field:"diet",type:"text"},{label:"Count",field:"count",type:"number"},{label:"Action",field:"action",type:"number"}],rows:[{name:"Mammal",diet:"",count:"",children:[{name:"Elephant",diet:"herbivore",count:5},{name:"Cat",diet:"carnivore",count:28}]},{name:"Reptiles",diet:"",count:"",action:"",children:[{name:"Snake",diet:"carnivore",count:40},{name:"lizard",diet:"insectivore",count:34}]},{name:"Fish",diet:"",count:"",children:[{name:"Shark",diet:"carnivore",count:2},{name:"koi",diet:"omnivore",count:14}]}]}},computed:{},methods:{showAlert:function(n){alert(JSON.stringify(n))}},mounted:function(){},components:{}},i=(t(486),t(4)),c=Object(i.a)(o,(function(){var n=this,e=n.$createElement,t=n._self._c||e;return t("div",[t("vue-good-table",{attrs:{columns:n.columns,rows:n.rows,"group-options":n.options,"search-options":{enabled:!0}},scopedSlots:n._u([{key:"table-header-row",fn:function(e){return["action"==e.column.field?t("span",[t("button",{staticClass:"fancy-btn",on:{click:function(t){return n.showAlert(e)}}},[n._v("Action")])]):t("span",[n._v("\n "+n._s(e.formattedRow[e.column.field])+"\n ")])]}}])})],1)}),[],!1,null,null,null);e.default=c.exports}}]);
--------------------------------------------------------------------------------
/vp-docs/.vuepress/theme/components/CarbonAds.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
42 |
43 |
78 |
--------------------------------------------------------------------------------
/docs/assets/js/6.9355beb5.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[6],{451:function(e,t,o){},495:function(e,t,o){"use strict";o(451)},532:function(e,t,o){"use strict";o.r(t);o(27),o(63),o(89),o(64);var a={name:"CodeGroup",data:function(){return{codeTabs:[],activeCodeTabIndex:-1}},watch:{activeCodeTabIndex:function(e){this.codeTabs.forEach((function(e){e.elm.classList.remove("theme-code-block__active")})),this.codeTabs[e].elm.classList.add("theme-code-block__active")}},mounted:function(){var e=this;this.codeTabs=(this.$slots.default||[]).filter((function(e){return Boolean(e.componentOptions)})).map((function(t,o){return""===t.componentOptions.propsData.active&&(e.activeCodeTabIndex=o),{title:t.componentOptions.propsData.title,elm:t.elm}})),-1===this.activeCodeTabIndex&&this.codeTabs.length>0&&(this.activeCodeTabIndex=0)},methods:{changeCodeTab:function(e){this.activeCodeTabIndex=e}}},c=(o(495),o(4)),n=Object(c.a)(a,(function(){var e=this,t=e.$createElement,o=e._self._c||t;return o("div",{staticClass:"theme-code-group"},[o("div",{staticClass:"theme-code-group__nav"},[o("ul",{staticClass:"theme-code-group__ul"},e._l(e.codeTabs,(function(t,a){return o("li",{key:t.title,staticClass:"theme-code-group__li"},[o("button",{staticClass:"theme-code-group__nav-tab",class:{"theme-code-group__nav-tab-active":a===e.activeCodeTabIndex},on:{click:function(t){return e.changeCodeTab(a)}}},[e._v("\n "+e._s(t.title)+"\n ")])])})),0)]),e._v(" "),e._t("default"),e._v(" "),e.codeTabs.length<1?o("pre",{staticClass:"pre-blank"},[e._v("// Make sure to add code blocks to your code group")]):e._e()],2)}),[],!1,null,"32c2d7ed",null);t.default=n.exports}}]);
--------------------------------------------------------------------------------
/vp-docs/guide/configuration/sort-options.md:
--------------------------------------------------------------------------------
1 | # Sort Options
2 |
3 | Set of options related to table sorting
4 |
5 | ```html
6 |
13 |
14 | ```
15 |
16 | ## enabled
17 |
18 | type: `Boolean (default: true)`
19 |
20 | Enable/disable sorting on table as a whole.
21 | ```html
22 |
28 |
29 | ```
30 |
31 | ## initialSortBy
32 |
33 | ::: tip Update
34 | `initialSortBy` now allows for sort by multiple columns
35 | :::
36 |
37 | type: `Object` or `Array`
38 |
39 | Allows specifying a default sort for the table on wakeup. Both **field** and **type** values are required.
40 | ```html
41 |
48 |
49 | ```
50 |
51 | ## multipleColumns
52 |
53 | type: `Boolean (default: true)`
54 |
55 | 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.
56 |
57 | ```html
58 |
69 |
70 | ```
--------------------------------------------------------------------------------
/vp-docs/.vuepress/components/basic-table.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
59 |
60 |
66 |
--------------------------------------------------------------------------------
/vp-docs/.vuepress/components/rtl-table.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
59 |
60 |
76 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-good-table",
3 | "version": "2.21.11",
4 | "sideEffects": [
5 | "*.vue",
6 | "*.css"
7 | ],
8 | "description": "A simple, clean data table for VueJS (2.x) with essential features like sorting, column filtering, pagination etc",
9 | "main": "dist/vue-good-table.cjs.js",
10 | "module": "dist/vue-good-table.esm.js",
11 | "files": [
12 | "dist",
13 | "src"
14 | ],
15 | "scripts": {
16 | "bundle": "bili",
17 | "dev": "poi --serve",
18 | "docs:dev": "vuepress dev vp-docs",
19 | "docs:build": "vuepress build vp-docs",
20 | "test": "echo \"No test specified\""
21 | },
22 | "repository": "github:xaksis/vue-good-table",
23 | "keywords": [
24 | "vue",
25 | "vuejs",
26 | "table",
27 | "datatable"
28 | ],
29 | "author": {
30 | "name": "xaksis",
31 | "email": "shay@crayonbits.com"
32 | },
33 | "license": "MIT",
34 | "poi": {
35 | "entry": "dev/main.js",
36 | "output": {
37 | "dir": "dev/dist",
38 | "publicUrl": "./",
39 | "html": {
40 | "template": "dev/index.html"
41 | }
42 | }
43 | },
44 | "dependencies": {
45 | "date-fns": "^2.17.0",
46 | "lodash.isequal": "^4.5.0"
47 | },
48 | "devDependencies": {
49 | "@vuepress/plugin-google-analytics": "^1.0.0-rc.1",
50 | "bili": "^4.8.0",
51 | "eslint-config-airbnb": "^18.2.0",
52 | "node-sass": "^4.12.0",
53 | "poi": "^12.7.0",
54 | "rollup-plugin-commonjs": "^10.1.0",
55 | "rollup-plugin-vue": "^5.1.9",
56 | "sass-loader": "^7.1.0",
57 | "vue": "^2.6.10",
58 | "vue-template-compiler": "^2.6.10",
59 | "vuepress": "^1.0.0-rc.1"
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/test/unit/specs/Pagination.spec.js:
--------------------------------------------------------------------------------
1 | import sinon from 'sinon'
2 | import VueGoodPagination from '@/components/Pagination'
3 | import { mount } from 'vue-test-utils'
4 |
5 | describe('VueGoodPagination', () => {
6 | let wrapper, vm
7 | beforeEach(() => {
8 | wrapper = mount(VueGoodPagination, {propsData: {
9 | perPage: 10,
10 | total: 30}
11 | })
12 | vm = wrapper.vm
13 | })
14 | it('should render 2 page buttons', async () => {
15 | await vm.$nextTick()
16 | wrapper.findAll('.page-btn').length.should.equal(2)
17 | wrapper.contains('select').should.be.true
18 | })
19 |
20 | it('should call previousPage when the first button is clicked', async () => {
21 | await vm.$nextTick()
22 | let previousPageStub = sinon.stub(vm, 'previousPage')
23 | wrapper.find('.page-btn:first-child').trigger('click')
24 | previousPageStub.called.should.be.true
25 | })
26 |
27 | it('should call nextPage when the last button is clicked', async () => {
28 | await vm.$nextTick()
29 | let nextPageStub = sinon.stub(vm, 'nextPage')
30 | wrapper.find('.page-btn:last-child').trigger('click')
31 | nextPageStub.called.should.be.true
32 | })
33 |
34 | it('should call pageChanged during nextPage', async () => {
35 | await vm.$nextTick()
36 | let pageChangedStub = sinon.stub(vm, 'pageChanged')
37 | vm.nextPage()
38 | pageChangedStub.called.should.be.true
39 | })
40 |
41 | it('should call pageChanged during previousPage', async () => {
42 | await vm.$nextTick()
43 | vm.nextPage()
44 | let pageChangedStub = sinon.stub(vm, 'pageChanged')
45 | vm.previousPage()
46 | pageChangedStub.called.should.be.true
47 | })
48 | })
49 |
--------------------------------------------------------------------------------
/vp-docs/.vuepress/components/line-numbers-table.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
59 |
60 |
76 |
--------------------------------------------------------------------------------
/vp-docs/.vuepress/components/fixed-header.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
11 |
12 |
61 |
62 |
67 |
--------------------------------------------------------------------------------
/vp-docs/.vuepress/components/custom-row.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 | {{props.row.age}}
9 |
10 |
11 | {{props.formattedRow[props.column.field]}}
12 |
13 |
14 |
15 |
16 |
17 |
18 |
64 |
65 |
70 |
--------------------------------------------------------------------------------
/vp-docs/.vuepress/components/theme-example.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
11 |
12 |
61 |
62 |
78 |
--------------------------------------------------------------------------------
/vp-docs/.vuepress/components/search-demo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
12 |
13 |
14 |
65 |
66 |
82 |
--------------------------------------------------------------------------------
/src/components/VgtGlobalSearch.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
64 |
65 |
68 |
--------------------------------------------------------------------------------
/vp-docs/.vuepress/components/external-query.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | External Query
4 |
11 |
12 |
13 |
14 |
15 |
66 |
67 |
83 |
--------------------------------------------------------------------------------
/vp-docs/.vuepress/components/checkbox-table.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 | Action 1
11 |
12 |
13 |
14 |
15 |
16 |
70 |
71 |
77 |
--------------------------------------------------------------------------------
/src/styles/_control-bar.scss:
--------------------------------------------------------------------------------
1 | .vgt-global-search{
2 | padding: 5px 0px;
3 | display: flex;
4 | flex-wrap: nowrap;
5 | align-items: stretch;
6 | border: 1px solid $border-color;
7 | border-bottom: 0px;
8 | background: linear-gradient($thead-bg-color-1, $thead-bg-color-2);
9 | form {
10 | display: flex;
11 | label {
12 | margin-top: 3px;
13 | }
14 | }
15 | }
16 | .vgt-global-search__input{
17 | position: relative;
18 | padding-left: 40px;
19 | flex-grow: 1;
20 | .input__icon{
21 | position: absolute;
22 | left: 0px;
23 | max-width: 32px;
24 | .magnifying-glass{
25 | margin-top: 3px;
26 | margin-left: 8px;
27 | display: block;
28 | width: 16px;
29 | height: 16px;
30 | border: 2px solid #494949;
31 | position: relative;
32 | border-radius: 50%;
33 | &:before{
34 | content: "";
35 | display: block;
36 | position: absolute;
37 | right: -7px;
38 | bottom: -5px;
39 | background: #494949;
40 | width: 8px;
41 | height: 4px;
42 | border-radius: 2px;
43 | transform: rotate(45deg);
44 | -webkit-transform: rotate(45deg);
45 | -moz-transform: rotate(45deg);
46 | -ms-transform: rotate(45deg);
47 | -o-transform: rotate(45deg);
48 | }
49 | }
50 | }
51 | .vgt-input{
52 | }
53 | }
54 | .vgt-global-search__actions{
55 | margin-left: 10px;
56 | }
57 |
58 | .vgt-selection-info-row{
59 | background: $notify-bg-color;
60 | padding: 5px 16px;
61 | font-size: 13px;
62 | border-top: 1px solid $border-color;
63 | border-left: 1px solid $border-color;
64 | border-right: 1px solid $border-color;
65 | color: lighten($notify-fg-color, 10%);
66 | font-weight: bold;
67 | a{
68 | font-weight: bold;
69 | display: inline-block;
70 | margin-left: 10px;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/vp-docs/.vuepress/components/pagination-table.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
60 |
61 |
77 |
--------------------------------------------------------------------------------
/vp-docs/.vuepress/config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | title: 'vue-good-table',
3 | description: 'A powerful data table plugin for VueJS',
4 | base: '/vue-good-table/',
5 | dest: 'docs',
6 | ga: 'UA-120929110-1',
7 | head: [
8 | ['link', { rel: 'icon', href: '/favicon.png' }]
9 | ],
10 | theme: '@vuepress/vue',
11 | themeConfig: {
12 | repo: 'xaksis/vue-good-table',
13 | logo: '/vgt-logo.png',
14 | lastUpdated: true,
15 | nav: [
16 | { text: 'Home', link: '/' },
17 | { text: 'Guide', link: '/guide/' },
18 | ],
19 | sidebar: {
20 | '/guide/': [
21 | {
22 | title: 'Introduction',
23 | collapsable: false,
24 | children: [
25 | '',
26 | ]
27 | },
28 | {
29 | title: 'Configuration',
30 | collapsable: false,
31 | children: [
32 | '/guide/configuration/',
33 | '/guide/configuration/table-events',
34 | '/guide/configuration/search-options',
35 | '/guide/configuration/sort-options',
36 | '/guide/configuration/pagination-options',
37 | '/guide/configuration/column-options',
38 | '/guide/configuration/column-filter-options',
39 | ]
40 | },
41 | {
42 | title: 'Advanced Configuration',
43 | collapsable: false,
44 | children: [
45 | '/guide/advanced/',
46 | '/guide/advanced/checkbox-table',
47 | '/guide/advanced/grouped-table',
48 | '/guide/advanced/remote-workflow',
49 | ]
50 | },
51 | {
52 | title: 'Style Configuration',
53 | collapsable: false,
54 | children: [
55 | '/guide/style-configuration/',
56 | '/guide/style-configuration/style-classes',
57 | '/guide/style-configuration/sass',
58 | ]
59 | },
60 | ],
61 | },
62 | }
63 | }
--------------------------------------------------------------------------------
/vp-docs/.vuepress/components/before-after-columns.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 | before
9 |
10 |
11 | after
12 |
13 |
14 | {{props.formattedRow[props.column.field]}}
15 |
16 |
17 |
18 |
19 |
20 |
21 |
75 |
76 |
82 |
--------------------------------------------------------------------------------
/vp-docs/.vuepress/components/grouped-table.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
12 |
13 |
14 |
74 |
75 |
91 |
--------------------------------------------------------------------------------
/src/components/utils/sort.js:
--------------------------------------------------------------------------------
1 | import {
2 | DEFAULT_SORT_TYPE,
3 | SORT_TYPES,
4 | } from './constants';
5 |
6 | function getColumnFirstSortType(column) {
7 | return column.firstSortType || DEFAULT_SORT_TYPE;
8 | }
9 |
10 | function getCurrentPrimarySort(sortArray, column) {
11 | return ( sortArray.length === 1 && sortArray[0].field === column.field )
12 | ? sortArray[0].type
13 | : undefined;
14 | }
15 |
16 | function getNextSort(currentSort, column) {
17 | if (SORT_TYPES.Descending === getColumnFirstSortType(column)
18 | && currentSort === SORT_TYPES.Ascending) {
19 | return SORT_TYPES.None
20 | } else if (currentSort === SORT_TYPES.Ascending) {
21 | return SORT_TYPES.Descending;
22 | }
23 | if (SORT_TYPES.Descending === getColumnFirstSortType(column)
24 | && currentSort === SORT_TYPES.Descending) {
25 | return SORT_TYPES.Ascending;
26 | } else if (currentSort === SORT_TYPES.Descending) {
27 | return SORT_TYPES.None;
28 | }
29 |
30 | if (SORT_TYPES.Descending === getColumnFirstSortType(column)
31 | && currentSort === SORT_TYPES.None) {
32 | return SORT_TYPES.Descending;
33 | } else {
34 | return SORT_TYPES.Ascending;
35 | }
36 |
37 | }
38 |
39 | function getIndex(sortArray, column) {
40 | for (let i = 0; i < sortArray.length; i++) {
41 | if (column.field === sortArray[i].field) return i;
42 | }
43 | return -1;
44 | }
45 |
46 | const primarySort = (sortArray, column) => {
47 | const currentPrimarySort = getCurrentPrimarySort(sortArray, column);
48 | const nextPrimarySort = getNextSort(currentPrimarySort, column);
49 | return [{
50 | field: column.field,
51 | type: currentPrimarySort ? nextPrimarySort : getColumnFirstSortType(column),
52 | }];
53 | };
54 |
55 | const secondarySort = (sortArray, column) => {
56 | const index = getIndex(sortArray, column);
57 | if (index === -1) {
58 | sortArray.push({
59 | field: column.field,
60 | type: getColumnFirstSortType(column),
61 | });
62 | } else {
63 | sortArray[index].type = getNextSort(sortArray[index].type, column);
64 | }
65 | return sortArray;
66 | };
67 |
68 | export {
69 | primarySort,
70 | secondarySort,
71 | }
--------------------------------------------------------------------------------
/vp-docs/.vuepress/theme/components/Banner.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Did vue-good-table save you time? Share the Joy!
4 |
Buy me a coffee
5 |
6 |
7 |
8 |
26 |
27 |
--------------------------------------------------------------------------------
/vp-docs/guide/advanced/checkbox-table.md:
--------------------------------------------------------------------------------
1 | # Checkbox Table
2 |
3 | One of the most common customizations in datatables is selectable rows. Creating a checkbox table with **vue-good-table** is easier than ever.
4 |
5 |
6 | ## Configuration
7 |
8 | type: `Object`
9 |
10 | Object containing select options
11 | ```html
12 |
25 | ```
26 |
27 | 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.
28 |
29 | ```js
30 | this.$refs['my-table'].selectedRows;
31 | ```
32 |
33 | ### Example
34 | ```vue
35 |
41 |
42 | ```
43 |
44 |
45 |
46 |
47 | ## Selected row action slot
48 | Once you select a row, an info bar shows up. This bar allows for a customizable slot for your action buttons.
49 |
50 | ### Example
51 |
52 | ```html
53 |
61 |
62 | Action 1
63 |
64 |
65 |
66 | ```
67 |
68 |
69 |
70 | ::: tip Note
71 | You can style the selection info bar by supplying a css class to `selectionInfoClass` property.
72 | :::
--------------------------------------------------------------------------------
/vp-docs/.vuepress/components/action-slot-table.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 | Button 1
8 | Button 2
9 |
10 |
11 |
12 |
13 |
14 |
62 |
63 |
96 |
--------------------------------------------------------------------------------
/vp-docs/.vuepress/dist/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | vue-good-table
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/vp-docs/guide/configuration/column-filter-options.md:
--------------------------------------------------------------------------------
1 | # Column Filter Options
2 |
3 | ## filterOptions
4 |
5 | type `Object`
6 |
7 | A collection of filter specific properties within a column object.
8 |
9 | ```javascript
10 | columns: [
11 | {
12 | label: 'name',
13 | field: 'user_name',
14 | filterOptions: {
15 | styleClass: 'class1', // class to be added to the parent th element
16 | enabled: true, // enable filter for this column
17 | placeholder: 'Filter This Thing', // placeholder for filter input
18 | filterValue: 'Jane', // initial populated value for this filter
19 | filterDropdownItems: [], // dropdown (with selected values) instead of text input
20 | filterFn: this.columnFilterFn, //custom filter function that
21 | trigger: 'enter', //only trigger on enter not on keyup
22 | },
23 | },
24 | // ...
25 | ]
26 | ```
27 |
28 | ## styleClass
29 |
30 | type: `string`
31 | Class to be added to the parent th element. You can specify several classes separated by a space.
32 |
33 | ## enabled
34 |
35 | type: `Boolean`
36 | Switch to enable column filter.
37 |
38 | ## placeholder
39 |
40 | type: `String`
41 | Placeholder to use on the column filter input.
42 |
43 | ## filterValue
44 |
45 | type: `String`
46 | If you want filter to be pre-populated, use this property
47 |
48 | ## trigger
49 |
50 | type: `String (default: '')`
51 | Allows specifying trigger for column filter. Default trigger is keyup. use 'enter' to filter only when enter key is pressed.
52 |
53 | ## filterDropdownItems
54 |
55 | type `Array of strings or Array of objects`
56 |
57 | allows creating a dropdown for filter as opposed to an input
58 |
59 | ```javascript
60 | //array
61 | filterDropdownItems: ['Blue', 'Red', 'Yellow']
62 | //or
63 | filterDropdownItems: [
64 | { value: 'n', text: 'Inactive' },
65 | { value: 'y', text: 'Active' },
66 | { value: 'c', text: 'Check' }
67 | ],
68 | ```
69 |
70 | ## filterFn
71 |
72 | type `Function`
73 |
74 | Custom filter, function of two variables: function(data, filterString), should return true if data matches the filterString, otherwise false
75 |
76 | ```javascript
77 | filterFn: function(data, filterString) {
78 | var x = parseInt(filterString)
79 | return data >= x - 5 && data <= x + 5;
80 | }
81 | // would create a filter matching numbers within 5 of the provided value
82 | ```
83 |
--------------------------------------------------------------------------------
/vp-docs/.vuepress/components/grouped-custom-span.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
12 | {{ props.row.label }}
13 |
14 |
15 |
16 |
17 |
18 |
19 |
79 |
80 |
100 |
--------------------------------------------------------------------------------
/docs/assets/js/3.e88f9927.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[3],{429:function(t,e,n){},430:function(t,e,n){},431:function(t,e,n){},473:function(t,e,n){"use strict";n(429)},474:function(t,e,n){"use strict";n(430)},475:function(t,e,n){"use strict";n(431)},513:function(t,e,n){"use strict";n.r(e);var s=n(496),a={name:"CarbonAds",props:[],data:function(){return{}},watch:{$route:function(t,e){t.path!==e.path&&this.$el.querySelector("#carbonads")&&(this.$el.innerHTML="",this.load())}},computed:{},methods:{load:function(){var t=document.createElement("script");t.id="_carbonads_js",t.src="//cdn.carbonads.com/carbon.js?serve=CK7DC53W&placement=xaksisgithubio",this.$el.appendChild(t)}},mounted:function(){this.load()},components:{}},o=(n(473),n(4)),r=Object(o.a)(a,(function(){var t=this.$createElement;return(this._self._c||t)("div",{staticClass:"carbon-ads"})}),[],!1,null,null,null).exports,i={name:"Banner",props:[],data:function(){return{}},computed:{},methods:{},mounted:function(){},components:{}},c=(n(474),Object(o.a)(i,(function(){var t=this.$createElement;this._self._c;return this._m(0)}),[function(){var t=this.$createElement,e=this._self._c||t;return e("div",{staticClass:"banner-holder"},[e("p",{staticClass:"banner-label"},[this._v("Did "),e("strong",[this._v("vue-good-table")]),this._v(" save you time? Share the Joy!")]),this._v(" "),e("a",{staticClass:"bmc-button",attrs:{target:"_blank",href:"https://www.buymeacoffee.com/68BUXR1d9"}},[e("img",{attrs:{src:"https://www.buymeacoffee.com/assets/img/BMC-btn-logo.svg",alt:"Buy me a coffee"}}),e("span",{staticStyle:{"margin-left":"5px"}},[this._v("Buy me a coffee")])])])}],!1,null,"67e317d2",null).exports),u={name:"UserBitAd",props:[],data:function(){return{}},computed:{},methods:{},mounted:function(){},components:{}},l=(n(475),Object(o.a)(u,(function(){var t=this.$createElement;this._self._c;return this._m(0)}),[function(){var t=this.$createElement,e=this._self._c||t;return e("div",[e("div",{staticClass:"box"},[e("div",{staticClass:"ad-box"},[this._v("\n Do you have a UX team? I Would really appreciate their feedback on my new product - "),e("a",{attrs:{target:"_blank",rel:"noopener noreferrer",href:"https://userbitapp.com"}},[this._v("UserBit")])])])])}],!1,null,"4fb0bc70",null).exports),d={components:{ParentLayout:s.a,CarbonAds:r,Banner:c,UserBitAd:l}},h=Object(o.a)(d,(function(){var t=this.$createElement,e=this._self._c||t;return e("ParentLayout",[e("carbon-ads",{attrs:{slot:"sidebar-top"},slot:"sidebar-top"}),this._v(" "),e("user-bit-ad",{attrs:{slot:"page-top"},slot:"page-top"})],1)}),[],!1,null,null,null);e.default=h.exports}}]);
--------------------------------------------------------------------------------
/vp-docs/guide/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Getting Started
3 |
4 | ## Installation
5 |
6 | Install with npm:
7 |
8 | ```bash
9 | npm install --save vue-good-table
10 | ```
11 |
12 | Import globally in app:
13 |
14 | ```javascript
15 | import VueGoodTablePlugin from 'vue-good-table';
16 |
17 | // import the styles
18 | import 'vue-good-table/dist/vue-good-table.css'
19 |
20 | Vue.use(VueGoodTablePlugin);
21 | ```
22 |
23 | **or** you can import into your component:
24 | ```js
25 | // import the styles
26 | import 'vue-good-table/dist/vue-good-table.css'
27 | import { VueGoodTable } from 'vue-good-table';
28 |
29 | // add to component
30 | components: {
31 | VueGoodTable,
32 | }
33 | ```
34 |
35 |
36 | ## Basic Example
37 |
38 |
39 |
40 | ```vue
41 |
42 |
43 |
46 |
47 |
48 |
49 |
89 | ```
90 |
91 | ## Usage with Nuxt.js
92 |
93 | Create your own plugin by creating a file called `vue-good-table.js` inside your Nuxt `plugins` folder. Shoud look something like this:
94 |
95 | ```
96 | import Vue from 'vue'
97 | import VueGoodTablePlugin from 'vue-good-table';
98 |
99 | // import the styles
100 | import 'vue-good-table/dist/vue-good-table.css'
101 |
102 | Vue.use(VueGoodTablePlugin);
103 | ```
104 |
105 | As you can see, the only difference from the normal installation is that we need to reference Vue using `import Vue from 'vue'`.
106 |
107 | Next we need to declare the plugin inside your `nuxt.config.js` like so:
108 |
109 | ```
110 | plugins: [
111 | { src: '~/plugins/vue-good-table', ssr: false }
112 | ],
113 | ```
114 |
115 | This should now work as expected.
--------------------------------------------------------------------------------
/vp-docs/.vuepress/components/grouped-custom.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
12 | Action
13 |
14 |
15 | {{props.formattedRow[props.column.field]}}
16 |
17 |
18 |
19 |
20 |
21 |
22 |
94 |
95 |
125 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Standards
8 |
9 | Examples of behavior that contributes to creating a positive environment include:
10 |
11 | * Using welcoming and inclusive language
12 | * Being respectful of differing viewpoints and experiences
13 | * Gracefully accepting constructive criticism
14 | * Focusing on what is best for the community
15 | * Showing empathy towards other community members
16 |
17 | Examples of unacceptable behavior by participants include:
18 |
19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances
20 | * Trolling, insulting/derogatory comments, and personal or political attacks
21 | * Public or private harassment
22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission
23 | * Other conduct which could reasonably be considered inappropriate in a professional setting
24 |
25 | ## Our Responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28 |
29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30 |
31 | ## Scope
32 |
33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34 |
35 | ## Enforcement
36 |
37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at anand.cooper@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38 |
39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40 |
41 | ## Attribution
42 |
43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44 |
45 | [homepage]: http://contributor-covenant.org
46 | [version]: http://contributor-covenant.org/version/1/4/
47 |
--------------------------------------------------------------------------------
/src/styles/_table-th.scss:
--------------------------------------------------------------------------------
1 | $sort-chevron-width: 5px;
2 |
3 | .vgt-table{
4 | & th{
5 | padding: .75em 1.5em .75em .75em;
6 | vertical-align: middle;
7 | position: relative;
8 | &.sortable{
9 | button {
10 | -webkit-appearance: none;
11 | -moz-appearance: none;
12 | appearance: none;
13 | background: transparent;
14 | border: none;
15 | position: absolute;
16 | top: 0;
17 | left: 0;
18 | width: 100%;
19 | height: 100%;
20 | &:focus{
21 | outline: none;
22 | }
23 | &:after{
24 | content: '';
25 | position: absolute;
26 | height: 0px;
27 | width: 0px;
28 | right: 6px;
29 | top: 50%;
30 | margin-top: -7px;
31 | border-left: $sort-chevron-width solid transparent;
32 | border-right: $sort-chevron-width solid transparent;
33 | border-bottom: $sort-chevron-width solid $chevron-color;
34 | }
35 | &:before{
36 | content: '';
37 | position: absolute;
38 | height: 0px;
39 | width: 0px;
40 | right: 6px;
41 | top: 50%;
42 | margin-bottom: -7px;
43 | border-left: $sort-chevron-width solid transparent;
44 | border-right: $sort-chevron-width solid transparent;
45 | border-top: $sort-chevron-width solid $chevron-color;
46 | }
47 | }
48 | }
49 | }
50 | & th.line-numbers, & th.vgt-checkbox-col {
51 | padding: 0 .75em 0 .75em;
52 | color: $text-color;
53 | border-right: 1px solid $border-color;
54 | word-wrap: break-word;
55 | width: 25px;
56 | text-align: center;
57 | background: linear-gradient($thead-bg-color-1, $thead-bg-color-2);
58 | }
59 | & th.filter-th {
60 | padding: .75em .75em .75em .75em;
61 | }
62 |
63 | th.vgt-row-header{
64 | border-bottom: 2px solid $border-color;
65 | border-top: 2px solid $border-color;
66 | background-color: lighten($border-color, 10%);
67 | .triangle {
68 | width: 24px;
69 | height: 24px;
70 | border-radius: 15%;
71 | position: relative;
72 | margin: 0px 8px;
73 | &:after {
74 | content: '';
75 | position: absolute;
76 | display: block;
77 | left: 50%;
78 | top: 50%;
79 | margin-top: -6px;
80 | border-top: 6px solid transparent;
81 | border-bottom: 6px solid transparent;
82 | border-left: 6px solid $text-color;
83 | margin-left: -3px;
84 | transition: 0.3s ease transform;
85 | }
86 | &.expand:after {
87 | transform: rotate(90deg);
88 | }
89 | }
90 | }
91 |
92 | thead th{
93 | color: $text-color;
94 | vertical-align: bottom;
95 | border-bottom: 1px solid $border-color;
96 | padding-right: 1.5em;
97 | background: linear-gradient($thead-bg-color-1, $thead-bg-color-2);
98 | &.vgt-checkbox-col{
99 | vertical-align: middle;
100 | }
101 | &.sorting-asc button {
102 | &:after{
103 | border-bottom: $sort-chevron-width solid $link-color;
104 | }
105 | }
106 | &.sorting-desc button {
107 | &:before{
108 | border-top: $sort-chevron-width solid $link-color;
109 | }
110 | }
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/vp-docs/guide/configuration/search-options.md:
--------------------------------------------------------------------------------
1 | # Search Options
2 |
3 | Vue-good-table supports two ways of filtering the table.
4 | 1. A global search that searches through all records in the table
5 | 1. [Column filters](/guide/configuration/column-filter-options.md) that filter based on a given column
6 |
7 | This section talks about how to configure global search options.
8 |
9 | ```html
10 |
22 |
23 | ```
24 |
25 | ## enabled
26 |
27 | type: `Boolean (default: false)`
28 |
29 |
30 | Allows a single search input for the whole table
31 |
32 | ::: warning
33 | Enabling this option disables column filters
34 | :::
35 | ```html
36 |
42 |
43 | ```
44 |
45 |
46 | ## trigger
47 |
48 | type: `String (default: '')`
49 |
50 | Allows you to specify if you want search to trigger on 'enter' event of the input. By **default table searches on key-up**.
51 |
52 | ```html
53 |
60 |
61 | ```
62 |
63 |
64 | ## skipDiacritics
65 |
66 | type: `boolean (default: false)`
67 |
68 | 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.
69 |
70 | ```html
71 |
78 |
79 | ```
80 |
81 | ## searchFn
82 |
83 | type: `Function`
84 |
85 | Allows you to specify your own search function for the global search
86 |
87 | ```html
88 |
95 |
96 | ```
97 | ```javascript
98 | // in js
99 | methods: {
100 | myFunc(row, col, cellValue, searchTerm){
101 | return cellValue === 'my value';
102 | },
103 | }
104 | ```
105 |
106 | ## placeholder
107 |
108 | type: `String (default: 'Search Table')`
109 |
110 | Text for global search input place holder
111 | ```html
112 |
119 |
120 | ```
121 |
122 | ## externalQuery
123 |
124 | type: `String`
125 |
126 |
127 | If you want to use your own input for searching the table, you can use this property
128 |
129 | ```html
130 |
131 |
138 |
139 | ```
140 | ```javascript
141 | // and in data
142 | data(){
143 | return {
144 | searchTerm: '',
145 | // rows, columns etc...
146 | };
147 | }
148 | ```
149 |
150 |
--------------------------------------------------------------------------------
/src/components/pagination/VgtPaginationPageInfo.vue:
--------------------------------------------------------------------------------
1 |
2 |
27 |
28 |
29 |
130 |
131 |
134 |
--------------------------------------------------------------------------------
/docs/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | vue-good-table
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/test/unit/specs/Table.spec.js:
--------------------------------------------------------------------------------
1 | import sinon from 'sinon'
2 | import { mount } from 'vue-test-utils'
3 | import VueGoodTable from '@/components/Table.vue'
4 |
5 | const columns = [
6 | {
7 | label: 'Name',
8 | field: 'name'
9 | },
10 | {
11 | label: 'Age',
12 | field: 'age',
13 | type: 'number'
14 | }
15 | ]
16 | const rows = [
17 | {name: 'John', age: '20'},
18 | {name: 'Jane', age: '24'},
19 | {name: 'Susan', age: '16'},
20 | {name: 'Chris', age: '55'},
21 | {name: 'Dan', age: '40'},
22 | {name: 'John', age: '20'},
23 | {name: 'Jane', age: '24'},
24 | {name: 'Susan', age: '16'},
25 | {name: 'Chris', age: '55'},
26 | {name: 'Dan', age: '40'}
27 | ]
28 |
29 | describe('Table.vue', () => {
30 | let wrapper, vm
31 | beforeEach(() => {
32 | wrapper = mount(VueGoodTable, {
33 | attachToDocument: true,
34 | propsData: {
35 | rows: rows,
36 | columns: columns
37 | }
38 | })
39 | vm = wrapper.vm
40 | })
41 | it('should render correct contents', (done) => {
42 | vm.$nextTick(() => {
43 | let tableRows = wrapper.findAll('tbody tr')
44 | tableRows.length.should.equal(rows.length)
45 | done()
46 | })
47 | })
48 |
49 | describe('global search', () => {
50 | it('should render less records', async () => {
51 | wrapper = mount(VueGoodTable, {propsData: {
52 | globalSearch: true,
53 | rows: rows,
54 | columns: columns}})
55 | await wrapper.vm.$nextTick()
56 | var searchElt = wrapper.find('.global-search-input')
57 | searchElt.element.value = 'jo'
58 | searchElt.trigger('input')
59 | await wrapper.vm.$nextTick()
60 | let tableRows = wrapper.findAll('tbody tr')
61 | tableRows.length.should.be.below(rows.length)
62 | })
63 | })
64 |
65 | describe('sort', () => {
66 | let originalCompare
67 | beforeEach(() => {
68 | originalCompare = wrapper.vm.$data.dataTypes.number.compare
69 | })
70 |
71 | afterEach(() => {
72 | wrapper.vm.$data.dataTypes.number.compare = originalCompare
73 | })
74 |
75 | it('should call compare once per combination (touch each value at least once)', (done) => {
76 | var compareSpy = sinon.stub()
77 | vm.$data.dataTypes.number.compare = compareSpy
78 | vm.$nextTick(() => {
79 | vm.sort(1)
80 | vm.$nextTick(() => {
81 | compareSpy.callCount.should.be.above(rows.length - 2)
82 | done()
83 | })
84 | })
85 | })
86 |
87 | it('should sort on the default by default', async () => {
88 | vm = mount(VueGoodTable, {propsData: {rows: rows, columns: columns, defaultSortBy: {field: 'age'}}}).vm
89 | await vm.$nextTick()
90 | vm.sortColumn.should.equal(1)
91 | })
92 |
93 | it('should call sort if click on first header item', (done) => {
94 | let sortSpy = sinon.stub(vm, 'sort')
95 | vm.$nextTick(() => {
96 | vm.$el.querySelector('thead th').click()
97 | vm.$nextTick(() => {
98 | sortSpy.calledWith(0).should.be.true
99 | done()
100 | })
101 | })
102 | })
103 |
104 | it('should call sort if click on second header item', async () => {
105 | let sortSpy = sinon.stub(vm, 'sort')
106 | await vm.$nextTick()
107 | vm.$el.querySelector('thead th:nth-child(2)').click()
108 | await vm.$nextTick()
109 | sortSpy.calledWith(1).should.be.true
110 | })
111 | })
112 |
113 | describe('filter', () => {
114 | it('should remove some rows when filtering', async () => {
115 | columns[0].filterable = true
116 | const wrapper = mount(VueGoodTable, {propsData: {rows: rows, columns: columns, paginated: false}})
117 | const vm = wrapper.vm
118 | await vm.$nextTick()
119 | var searchElt = wrapper.find('input[type=text]')
120 | searchElt.element.value = 'jo'
121 | searchElt.trigger('input')
122 | await vm.$nextTick()
123 | setTimeout(() => {
124 | wrapper.findAll('tbody tr').length.should.be.below(rows.length).and.above(1)
125 | }, 420)
126 | })
127 | })
128 | })
129 |
--------------------------------------------------------------------------------
/src/components/VgtHeaderRow.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
32 |
33 |
36 |
52 |
72 |
73 |
74 |
75 |
144 |
145 |
148 |
--------------------------------------------------------------------------------
/dev/grouped-table.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | Expand All
4 | Collapse All
5 |
32 |
40 |
41 |
42 |
43 |
44 |
141 |
142 |
147 |
--------------------------------------------------------------------------------
/src/styles/nocturnal/nocturnal.scss:
--------------------------------------------------------------------------------
1 | @import './overrides';
2 | // suggested by wifey
3 | .vgt-table.nocturnal{
4 | border: 1px solid $border-color;
5 | background-color: $table-bg;
6 |
7 | & tr.clickable {
8 | &:hover{
9 | background-color: $highlight-color;
10 | }
11 | }
12 |
13 | // td
14 | & td {
15 | border-bottom: 1px solid $border-color;
16 | color: $text-color;
17 | }
18 |
19 | //th
20 | & th.line-numbers, & th.vgt-checkbox-col {
21 | color: $text-color;
22 | border-right: 1px solid $border-color;
23 | background: linear-gradient($thead-bg-color-1, $thead-bg-color-2);
24 | }
25 | thead th{
26 | color: $text-color;
27 | border-bottom: 1px solid $border-color;
28 | background: linear-gradient($thead-bg-color-1, $thead-bg-color-2);
29 | &.sortable {
30 | // color: lighten($text-color, 15%);
31 | &:before{
32 | border-top-color: $chevron-color;
33 | }
34 | &:after{
35 | border-bottom-color: $chevron-color;
36 | }
37 | &.sorting-asc{
38 | color: white;
39 | &:after{
40 | border-bottom-color: $link-color;
41 | }
42 | }
43 | &.sorting-desc {
44 | color: white;
45 | &:before{
46 | border-top-color: $link-color;
47 | }
48 | }
49 | }
50 | }
51 |
52 | //bordered
53 | &.bordered td, &.bordered th {
54 | border: 1px solid $border-color;
55 | }
56 |
57 | //input
58 | .vgt-input, .vgt-select{
59 | color: $text-color;
60 | background-color: darken($thead-bg-color-2, 5%);
61 | border: 1px solid $input-border-color;
62 | &::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */
63 | color: $text-color;
64 | opacity: 0.3; /* Firefox */
65 | }
66 | }
67 | }
68 |
69 | .vgt-wrap.nocturnal{
70 | .vgt-wrap__footer{
71 | color: $text-color;
72 | border: 1px solid $border-color;
73 | background: linear-gradient($thead-bg-color-1, $thead-bg-color-2);
74 | .footer__row-count{
75 | position: relative;
76 | &__label{
77 | color: $secondary-text-color;
78 | }
79 | &__select{
80 | color: $text-color;
81 | background: darken($thead-bg-color-2, 5%);
82 | border: none;
83 | -webkit-appearance: none;
84 | -moz-appearance: none;
85 | appearance: none;
86 | padding-right: 15px;
87 | padding-left: 10px;
88 | border-radius: 3px;
89 | text-align: center;
90 | &:focus{
91 | border-color: $link-color;
92 | }
93 | }
94 | &::after{
95 | content: '';
96 | display: block;
97 | position: absolute;
98 | height: 0px;
99 | width: 0px;
100 | right: 6px;
101 | top: 50%;
102 | margin-top: -1px;
103 | border-top: 6px solid $text-color;
104 | border-left: 6px solid transparent;
105 | border-right: 6px solid transparent;
106 | border-bottom: none;
107 | pointer-events: none
108 | }
109 | }
110 | .footer__navigation{
111 | &__page-btn{
112 | color: $text-color;
113 | &.disabled,
114 | &.disabled:hover {
115 | .chevron.left:after{
116 | border-right-color: $text-color;
117 | }
118 | .chevron.right:after{
119 | border-left-color: $text-color;
120 | }
121 | }
122 | }
123 | &__info, &__page-info{
124 | color: $secondary-text-color;
125 | }
126 | }
127 | }
128 |
129 | // control bar
130 | .vgt-global-search{
131 | border: 1px solid $border-color;
132 | background: linear-gradient($thead-bg-color-1, $thead-bg-color-2);
133 | }
134 | .vgt-global-search__input{
135 | .input__icon{
136 | .magnifying-glass{
137 | border: 2px solid darken($border-color, 2%);
138 | &:before{
139 | background: darken($border-color, 2%);
140 | }
141 | }
142 | }
143 | .vgt-input, .vgt-select{
144 | color: $text-color;
145 | background-color: darken($thead-bg-color-2, 5%);
146 | border: 1px solid $input-border-color;
147 | &::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */
148 | color: $text-color;
149 | opacity: 0.3; /* Firefox */
150 | }
151 | }
152 | }
153 | }
--------------------------------------------------------------------------------
/src/styles/black-rhino/black-rhino.scss:
--------------------------------------------------------------------------------
1 | @import './overrides';
2 | // suggested by wifey
3 | .vgt-table.black-rhino{
4 | border: 1px solid $border-color;
5 | background-color: $table-bg;
6 |
7 | & tr.clickable {
8 | &:hover{
9 | background-color: $highlight-color;
10 | }
11 | }
12 |
13 | // td
14 | & td {
15 | border-bottom: 1px solid $border-color-td;
16 | color: $text-color-td;
17 | }
18 |
19 | //th
20 | & th.line-numbers, & th.vgt-checkbox-col {
21 | color: $text-color;
22 | border-right: 1px solid $border-color;
23 | background: linear-gradient($thead-bg-color-1, $thead-bg-color-2);
24 | }
25 | thead th{
26 | color: $text-color;
27 | text-shadow: 1px 1px $text-shadow-color;
28 | border-bottom: 1px solid $border-color;
29 | background: linear-gradient($thead-bg-color-1, $thead-bg-color-2);
30 | &.sortable {
31 | // color: lighten($text-color, 15%);
32 | &:before{
33 | border-top-color: $chevron-color;
34 | }
35 | &:after{
36 | border-bottom-color: $chevron-color;
37 | }
38 | &.sorting-asc{
39 | color: white;
40 | &:after{
41 | border-bottom-color: $link-color;
42 | }
43 | }
44 | &.sorting-desc {
45 | &:before{
46 | border-top-color: $link-color;
47 | }
48 | }
49 | }
50 | }
51 |
52 | //bordered
53 | &.bordered td {
54 | border: 1px solid $border-color-td;
55 | }
56 |
57 | &.bordered th {
58 | border: 1px solid $border-color;
59 | }
60 |
61 | //input
62 | .vgt-input, .vgt-select{
63 | color: $text-color;
64 | background-color: $input-bg;
65 | border: 1px solid $input-border-color;
66 | &::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */
67 | color: $text-color;
68 | opacity: 0.3; /* Firefox */
69 | }
70 | }
71 | }
72 |
73 | .vgt-wrap.black-rhino{
74 | .vgt-wrap__footer{
75 | color: $text-color;
76 | border: 1px solid $border-color;
77 | background: linear-gradient($thead-bg-color-1, $thead-bg-color-2);
78 | .footer__row-count{
79 | position: relative;
80 | padding-right: 3px;
81 | &__label{
82 | color: $secondary-text-color;
83 | }
84 | &__select{
85 | color: $text-color-td;
86 | background: $input-bg;
87 | border: none;
88 | -webkit-appearance: none;
89 | -moz-appearance: none;
90 | appearance: none;
91 | padding-right: 15px;
92 | padding-left: 5px;
93 | border-radius: 3px;
94 | &::-ms-expand{
95 | display: none;
96 | }
97 | &:focus{
98 | border-color: $link-color;
99 | }
100 | }
101 | &::after{
102 | content: '';
103 | display: block;
104 | position: absolute;
105 | height: 0px;
106 | width: 0px;
107 | right: 6px;
108 | top: 50%;
109 | margin-top: -1px;
110 | border-top: 6px solid $text-color-td;
111 | border-left: 6px solid transparent;
112 | border-right: 6px solid transparent;
113 | border-bottom: none;
114 | pointer-events: none
115 | }
116 | }
117 | .footer__navigation{
118 | &__page-btn{
119 | color: $text-color;
120 | &.disabled,
121 | &.disabled:hover {
122 | .chevron.left:after{
123 | border-right-color: $text-color;
124 | }
125 | .chevron.right:after{
126 | border-left-color: $text-color;
127 | }
128 | }
129 | }
130 | &__info, &__page-info{
131 | color: $text-color;
132 | }
133 | }
134 | }
135 |
136 | // control bar
137 | .vgt-global-search{
138 | border: 1px solid $border-color;
139 | background: linear-gradient($thead-bg-color-1, $thead-bg-color-2);
140 | }
141 | .vgt-global-search__input{
142 | .input__icon{
143 | .magnifying-glass{
144 | border: 2px solid darken($border-color, 2%);
145 | &:before{
146 | background: darken($border-color, 2%);
147 | }
148 | }
149 | }
150 | .vgt-input, .vgt-select{
151 | color: $text-color;
152 | background-color: darken($thead-bg-color-2, 5%);
153 | border: 1px solid $input-border-color;
154 | &::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */
155 | color: $text-color;
156 | opacity: 0.3; /* Firefox */
157 | }
158 | }
159 | }
160 | }
--------------------------------------------------------------------------------
/src/styles/_table-footer.scss:
--------------------------------------------------------------------------------
1 | $footer-font-size: 1.1rem;
2 |
3 | .vgt-wrap__actions-footer{
4 | border: 1px solid $border-color;
5 | }
6 | .vgt-wrap__footer{
7 | color: $text-color;
8 | font-size: $footer-font-size;
9 | padding: 1em;
10 | border: 1px solid $border-color;
11 | background: linear-gradient($thead-bg-color-1, $thead-bg-color-2);
12 | .footer__row-count{
13 | position: relative;
14 | padding-right: 3px;
15 | &__label, &__select{
16 | display: inline-block;
17 | vertical-align: middle;
18 | }
19 | &__label{
20 | font-size: $footer-font-size;
21 | }
22 | &__select{
23 | font-size: $footer-font-size;
24 | background-color: transparent;
25 | width: auto;
26 | padding: 0;
27 | border: 0;
28 | border-radius: 0;
29 | height: auto;
30 | margin-left: 8px;
31 | color: $text-color;
32 | font-weight: bold;
33 | -webkit-appearance: none;
34 | -moz-appearance: none;
35 | appearance: none;
36 | padding-right: 15px;
37 | padding-left: 5px;
38 | &::-ms-expand{
39 | display: none;
40 | }
41 | &:focus{
42 | outline: none;
43 | border-color: $link-color;
44 | }
45 | }
46 | &::after{
47 | content: '';
48 | display: block;
49 | position: absolute;
50 | height: 0px;
51 | width: 0px;
52 | right: 6px;
53 | top: 50%;
54 | margin-top: -1px;
55 | border-top: 6px solid $text-color;
56 | border-left: 6px solid transparent;
57 | border-right: 6px solid transparent;
58 | border-bottom: none;
59 | pointer-events: none
60 | }
61 | }
62 | .footer__navigation{
63 | > button:first-of-type {
64 | margin-right: 16px;
65 | }
66 | font-size: $footer-font-size;
67 | &__page-btn, &__info, &__page-info{
68 | display: inline-block;
69 | vertical-align: middle;
70 | color: $secondary-text-color;
71 | }
72 | &__page-btn{
73 | -webkit-appearance: none;
74 | -moz-appearance: none;
75 | appearance: none;
76 | background: transparent;
77 | border: none;
78 | text-decoration: none;
79 | color: $text-color;
80 | font-weight: bold;
81 | white-space:nowrap;
82 | vertical-align: middle;
83 | &:hover{
84 | cursor: pointer;
85 | }
86 | &.disabled,
87 | &.disabled:hover {
88 | opacity: 0.5;
89 | cursor: not-allowed;
90 | .chevron.left:after{
91 | border-right-color: $text-color;
92 | }
93 | .chevron.right:after{
94 | border-left-color: $text-color;
95 | }
96 | }
97 | span{
98 | display: inline-block;
99 | vertical-align: middle;
100 | font-size: $footer-font-size;
101 | }
102 | .chevron{
103 | width: 24px;
104 | height: 24px;
105 | border-radius: 15%;
106 | position: relative;
107 | margin: 0;
108 | display: inline-block;
109 | vertical-align: middle;
110 | &:after{
111 | content: '';
112 | position: absolute;
113 | display: block;
114 | left: 50%;
115 | top: 50%;
116 | margin-top: -6px;
117 | border-top: 6px solid transparent;
118 | border-bottom: 6px solid transparent;
119 | }
120 | &.left::after{
121 | border-right: 6px solid $link-color;
122 | margin-left: -3px;
123 | }
124 |
125 | &.right::after{
126 | border-left: 6px solid $link-color;
127 | margin-left: -3px;
128 | }
129 | }
130 | }
131 | &__info, &__page-info{
132 | display: inline-block;
133 | margin: 0px 16px;
134 | }
135 | &__page-info{
136 | span{
137 | display: inline-block;
138 | vertical-align: middle;
139 | }
140 | &__current-entry{
141 | width: 30px;
142 | text-align: center;
143 | vertical-align: middle;
144 | display: inline-block;
145 | margin: 0px 10px;
146 | font-weight: bold;
147 | }
148 | }
149 |
150 |
151 | }
152 | }
153 |
154 | @media only screen and (max-width: 750px) {
155 | /* on small screens hide the info */
156 | .vgt-wrap__footer .footer__navigation__info{
157 | display: none;
158 | }
159 | .vgt-wrap__footer .footer__navigation__page-btn{
160 | margin-left: 16px;
161 | }
162 | }
--------------------------------------------------------------------------------
/vp-docs/guide/configuration/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | sidebarDepth: 3
3 | ---
4 |
5 | # Table Options
6 |
7 | These options relate to the table as a whole
8 |
9 | ## columns
10 |
11 | type: `Array`
12 |
13 | Array containing objects that describe table columns. The column object itself can contain many [configurable properties](/guide/configuration/column-options.md).
14 | ```javascript
15 | [
16 | {
17 | label: 'Name',
18 | field: 'name',
19 | }
20 | //...
21 | ]
22 | ```
23 |
24 | ## rows
25 |
26 | type: `Array`
27 |
28 | Array containing row objects. Each row object contains data that will be displayed in the table row.
29 | ```javascript
30 | [
31 | {
32 | id:1,
33 | name:"John",
34 | age:20
35 | },
36 | //...
37 | ]
38 | ```
39 |
40 | ::: tip
41 | for **grouped rows**, you need a nested format. Refer to [Grouped Table](/guide/advanced/grouped-table.md) for examples.
42 | :::
43 |
44 | ## max-height
45 |
46 | type: `String`
47 | Set a maximum height for table body
48 |
49 | ```vue
50 |
54 |
55 | ```
56 |
57 | ## fixed-header
58 |
59 | type: `Boolean (default: false)`
60 | fix header so it stays in view as you scroll the table.
61 |
62 | ```vue
63 |
68 |
69 | ```
70 |
71 |
72 | ::: tip
73 | Fixed header should probably be used with max-height
74 | :::
75 |
76 |
77 | ## line-numbers
78 |
79 | type: `Boolean (default: false)`
80 | Show line number for each row
81 | ```html
82 |
86 |
87 | ```
88 |
89 |
90 | ## row-style-class
91 |
92 | type: `String` or `Function`
93 |
94 | property to assign a class to rows. This can either be a string representing a css class-name or a function.
95 |
96 | ```vue
97 |
101 |
102 | ```
103 |
104 | ```js
105 | methods: {
106 | rowStyleClassFn(row) {
107 | return row.age > 18 ? 'green' : 'red';
108 | },
109 | }
110 | ```
111 |
112 |
113 | ## rtl
114 |
115 | type: `Boolean (default: false)`
116 |
117 | Enable Right-To-Left layout for the table
118 | ```html
119 |
123 |
124 | ```
125 |
126 |
127 | ## Table Actions Slot
128 | 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.
129 |
130 | ::: tip Note
131 | You don't have to have global search enabled to use this slot.
132 | :::
133 |
134 | ```html
135 |
138 |
139 | This will show up on the top right of the table.
140 |
141 |
142 | ```
143 |
144 |
145 |
146 | ## Table Actions Footer Slot
147 |
148 | If you want a space for your buttons between pagination and the table. This is the slot you use.
149 |
150 | ```html
151 |
154 |
155 | This will show up on the bottom of the table.
156 |
157 |
158 | ```
159 |
160 | ## Empty state slot
161 | You can provide html for empty state slot as well. Example:
162 |
163 | ```html
164 |
167 |
168 | This will show up when there are no rows
169 |
170 |
171 | ```
172 |
173 | ## mode
174 |
175 | type: `String`
176 |
177 | Set mode=`remote` to allow sorting/filtering etc to be powered by server side instead of client side.
178 |
179 | for a detailed workflow example check out [Server Side Workflow](/guide/advanced/remote-workflow.md)
180 |
181 | ```html
182 |
186 |
187 | ```
188 |
189 | ## totalRecords
190 |
191 | type: `Number`
192 | ::: tip
193 | totalRecords is only useful for remote mode. When server controls pagination the table needs to know how many total rows exist.
194 | :::
195 |
196 | total number of rows that exist given a table/filter. refer to [remote workflow](/guide/advanced/remote-workflow.md) for more details
197 |
198 | ## compactMode
199 |
200 | type: `Boolean (default: false)`
201 |
202 | Enable mobile-friendly List view on small devices (screenSize below 576px)
203 | ```html
204 |
208 |
209 | ```
210 |
--------------------------------------------------------------------------------
/src/styles/polar-bear/polar-bear.scss:
--------------------------------------------------------------------------------
1 | @import './overrides';
2 | // suggested by wifey
3 | .vgt-inner-wrap{
4 | border-radius: 0.25rem;
5 | // box-shadow: 0 1px 3px rgba(50,50,93,.15), 0 1px 0 rgba(0,0,0,.02);
6 | box-shadow: 0 1px 3px 0 rgba(50,50,93,.1), 0 1px 2px 0 rgba(50,50,93,.06);
7 | }
8 | .vgt-table.polar-bear{
9 | border-spacing: 0;
10 | border-collapse: separate;
11 | font-size: 1rem;
12 | background-color: $white;
13 | border: 1px solid $border-color;
14 | border-bottom: none;
15 | border-radius: 0.25rem;
16 | // td
17 | & td {
18 | padding: 1em .75em 1em .75em;
19 | border-bottom: 1px solid $border-color-td;
20 | color: $text-color-td;
21 | &.vgt-right-align{
22 | text-align: right;
23 | }
24 | }
25 |
26 | //th
27 | & th.line-numbers, & th.vgt-checkbox-col {
28 | color: $text-color;
29 | border-right: 1px solid $border-color;
30 | background: $thead-bg-color-3;
31 | }
32 | thead th{
33 | color: $header-color;
34 | font-weight: 600;
35 | // text-shadow: 1px 1px $text-shadow-color;
36 | border-bottom: 1px solid $border-color;
37 | background: $thead-bg-color-3;
38 | &.sorting-asc, &.sorting-desc {
39 | color: $link-color;
40 | }
41 | &.sorting-desc{
42 | &:before{
43 | border-top: 5px solid lighten($link-color, 5%);
44 | }
45 | }
46 | &.sorting-asc{
47 | &:after{
48 | border-bottom: 5px solid lighten($link-color, 5%);
49 | }
50 | }
51 |
52 | .vgt-input, .vgt-select{
53 | height: 2.75em;
54 | box-shadow: 0 1px 2px 0 rgba(0,0,0,.05);
55 | border: 1px solid $border-color-td;
56 | }
57 |
58 | .vgt-input:focus, .vgt-select:focus {
59 | outline: 0;
60 | border-color: lighten($focus-color, 25%);
61 | }
62 | }
63 | thead tr:first-child{
64 | th:first-child{
65 | border-top-left-radius: 0.25rem;
66 | }
67 | th:last-child{
68 | border-top-right-radius: 0.25rem;
69 | }
70 | }
71 |
72 | //bordered
73 | &.bordered td {
74 | border: 1px solid $border-color;
75 | background: $white;
76 | }
77 |
78 | &.bordered th {
79 | // border: none;
80 | border: 1px solid $border-color;
81 | }
82 | }
83 |
84 | .vgt-wrap.polar-bear{
85 | .vgt-wrap__footer{
86 | color: $text-color;
87 | border: 1px solid $border-color;
88 | border-bottom: 0px;
89 | border-top: 0px;
90 | background: linear-gradient($thead-bg-color-3, $thead-bg-color-3);
91 | .footer__row-count{
92 | position: relative;
93 | padding-right: 3px;
94 | &__label{
95 | color: $secondary-text-color;
96 | }
97 | &__select{
98 | text-align: center;
99 | color: $text-color-td;
100 | background: $table-bg;
101 | border: none;
102 | -webkit-appearance: none;
103 | -moz-appearance: none;
104 | appearance: none;
105 | padding: 5px;
106 | padding-right: 30px;
107 | border-radius: 3px;
108 | box-shadow: 0 1px 2px 0 rgba(0,0,0,.05);
109 | border: 1px solid $border-color-td;
110 | &::-ms-expand{
111 | display: none;
112 | }
113 | &:focus{
114 | border-color: $link-color;
115 | }
116 | }
117 | &::after{
118 | content: '';
119 | display: block;
120 | position: absolute;
121 | height: 0px;
122 | width: 0px;
123 | right: 15px;
124 | top: 50%;
125 | margin-top: -3px;
126 | border-top: 6px solid $text-color-td;
127 | border-left: 6px solid transparent;
128 | border-right: 6px solid transparent;
129 | border-bottom: none;
130 | pointer-events: none
131 | }
132 | }
133 | .footer__navigation{
134 | &__page-btn{
135 | color: $text-color;
136 | &.disabled,
137 | &.disabled:hover {
138 | .chevron.left:after{
139 | border-right-color: $text-color;
140 | }
141 | .chevron.right:after{
142 | border-left-color: $text-color;
143 | }
144 | }
145 | }
146 | &__info, &__page-info{
147 | color: $text-color;
148 | }
149 | }
150 | }
151 |
152 | // control bar
153 | .vgt-global-search{
154 | border: 1px solid $border-color;
155 | border-bottom: 0px;
156 | border-top-left-radius: 3px;
157 | border-top-right-radius: 3px;
158 | background: $thead-bg-color-3;
159 | }
160 | .vgt-global-search__input{
161 | .input__icon{
162 | .magnifying-glass{
163 | border: 2px solid darken($border-color, 2%);
164 | &:before{
165 | background: darken($border-color, 2%);
166 | }
167 | }
168 | }
169 | .vgt-input, .vgt-select{
170 | height: 2.75em;
171 | box-shadow: 0 1px 2px 0 rgba(0,0,0,.05);
172 | border: 1px solid $border-color-td;
173 | &::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */
174 | color: $text-color;
175 | opacity: 0.3; /* Firefox */
176 | }
177 | }
178 | }
179 | }
--------------------------------------------------------------------------------
/vp-docs/.vuepress/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | vue-good-table
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/vp-docs/guide/advanced/remote-workflow.md:
--------------------------------------------------------------------------------
1 | # Server Side Table
2 |
3 | ## Why Remote Mode?
4 |
5 | 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.
6 |
7 | 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.
8 |
9 | Following is a workflow you can use to get a server powered vue-good-table instance:
10 |
11 | ## Prep Work
12 | ### What do we send to server?
13 |
14 | 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:
15 |
16 | ```js
17 | serverParams: {
18 | // a map of column filters example: {name: 'john', age: '20'}
19 | columnFilters: {
20 | },
21 | sort: [
22 | {
23 | field: '', // example: 'name'
24 | type: '' // 'asc' or 'desc'
25 | }
26 | ],
27 |
28 | page: 1, // what page I want to show
29 | perPage: 10 // how many items I'm showing per page
30 | }
31 | ```
32 | With the above information, server should be able to generate the relevant rows to send back.
33 |
34 | ### What does the server send back?
35 | Two things are required for the server to send back
36 | 1. **relevant rows** - set of rows for the current page, matching the current filter and sort.
37 | 2. **totalRecords** - number of total records matching the params we sent (not just the current page). This is required for the pagination to work correctly.
38 |
39 | ## Set mode to remote
40 |
41 | ```html
42 |
50 | ```
51 | this tells VGT to not do client side paging/sorting/filtering
52 |
53 | ## Provide handlers for user events
54 |
55 | Now instead of doing the above client side, each user interaction will generate events. So lets provide handlers for those events:
56 | ```html
57 |
70 | ```
71 |
72 | ... in data
73 | ```javascript
74 | data() {
75 | return {
76 | isLoading: false,
77 | columns: [
78 | //...
79 | ],
80 | rows: [],
81 | totalRecords: 0,
82 | serverParams: {
83 | columnFilters: {
84 | },
85 | sort: [
86 | {
87 | field: '',
88 | type: ''
89 | }
90 | ],
91 | page: 1,
92 | perPage: 10
93 | }
94 | };
95 | },
96 | ```
97 |
98 | ... handlers
99 |
100 | ```javascript
101 | methods: {
102 | updateParams(newProps) {
103 | this.serverParams = Object.assign({}, this.serverParams, newProps);
104 | },
105 |
106 | onPageChange(params) {
107 | this.updateParams({page: params.currentPage});
108 | this.loadItems();
109 | },
110 |
111 | onPerPageChange(params) {
112 | this.updateParams({perPage: params.currentPerPage});
113 | this.loadItems();
114 | },
115 |
116 | onSortChange(params) {
117 | this.updateParams({
118 | sort: [{
119 | type: params.sortType,
120 | field: this.columns[params.columnIndex].field,
121 | }],
122 | });
123 | this.loadItems();
124 | },
125 |
126 | onColumnFilter(params) {
127 | this.updateParams(params);
128 | this.loadItems();
129 | }
130 |
131 | // load items is what brings back the rows from server
132 | loadItems() {
133 | getFromServer(this.serverParams).then(response => {
134 | this.totalRecords = response.totalRecords;
135 | this.rows = response.rows;
136 | });
137 | }
138 | }
139 | ```
140 |
141 | ## So, what is happening?
142 | 1. Everytime the user interacts with the table, an appropriate event is emitted.
143 | 1. Along with this, VGT knows that this event will now result in fetching things from the backend. So it starts a loading screen.
144 | 1. In the handler of that event, we first update the `serverParams` and then send a request to the backend.
145 | 1. When we get the response back, we update both the totalRecords and the rows data objects.
146 | 1. Row object's update signifies to VGT that the loading event is now done, and VGT shows the new rows on the table.
147 |
148 | ::: tip
149 | If you want to show loading notification manually, you can do so using table's `:isLoading.sync="isLoading"` property.
150 | :::
151 |
152 | ::: tip
153 | to style the loading dom, you can use the slot - `loadingContent`
154 | :::
155 |
156 | ## Conclusion
157 | So that wasn't too bad. You now have VGT that's powered completely by your backend server.
158 |
159 |
--------------------------------------------------------------------------------
/vp-docs/.vuepress/dist/assets/js/2.bc66dc77.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[2],{191:function(t,a,s){"use strict";s.r(a);var n=s(0),e=Object(n.a)({},function(){var t=this.$createElement,a=this._self._c||t;return a("div",{staticClass:"content"},[this._m(0),this._m(1),this._m(2),a("theme-example"),this._m(3),this._m(4),a("theme-example",{attrs:{theme:"black-rhino"}}),this._m(5),this._m(6),a("theme-example",{attrs:{theme:"nocturnal"}})],1)},[function(){var t=this.$createElement,a=this._self._c||t;return a("h1",{attrs:{id:"themes"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#themes","aria-hidden":"true"}},[this._v("#")]),this._v(" Themes")])},function(){var t=this.$createElement,a=this._self._c||t;return a("h2",{attrs:{id:"default"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#default","aria-hidden":"true"}},[this._v("#")]),this._v(" Default")])},function(){var t=this,a=t.$createElement,s=t._self._c||a;return s("div",{staticClass:"language-html extra-class"},[s("pre",{pre:!0,attrs:{class:"language-html"}},[s("code",[s("span",{attrs:{class:"token tag"}},[s("span",{attrs:{class:"token tag"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("<")]),t._v("vue-good-table")]),t._v("\n "),s("span",{attrs:{class:"token attr-name"}},[t._v(":columns")]),s("span",{attrs:{class:"token attr-value"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("=")]),s("span",{attrs:{class:"token punctuation"}},[t._v('"')]),t._v("columns"),s("span",{attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),s("span",{attrs:{class:"token attr-name"}},[t._v(":rows")]),s("span",{attrs:{class:"token attr-value"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("=")]),s("span",{attrs:{class:"token punctuation"}},[t._v('"')]),t._v("rows"),s("span",{attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n"),s("span",{attrs:{class:"token tag"}},[s("span",{attrs:{class:"token tag"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("")]),t._v("vue-good-table")]),s("span",{attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n")])])])},function(){var t=this.$createElement,a=this._self._c||t;return a("h2",{attrs:{id:"black-rhino"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#black-rhino","aria-hidden":"true"}},[this._v("#")]),this._v(" Black-rhino")])},function(){var t=this,a=t.$createElement,s=t._self._c||a;return s("div",{staticClass:"language-html extra-class"},[s("pre",{pre:!0,attrs:{class:"language-html"}},[s("code",[s("span",{attrs:{class:"token tag"}},[s("span",{attrs:{class:"token tag"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("<")]),t._v("vue-good-table")]),t._v("\n "),s("span",{attrs:{class:"token attr-name"}},[t._v(":columns")]),s("span",{attrs:{class:"token attr-value"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("=")]),s("span",{attrs:{class:"token punctuation"}},[t._v('"')]),t._v("columns"),s("span",{attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),s("span",{attrs:{class:"token attr-name"}},[t._v(":rows")]),s("span",{attrs:{class:"token attr-value"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("=")]),s("span",{attrs:{class:"token punctuation"}},[t._v('"')]),t._v("rows"),s("span",{attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),s("span",{attrs:{class:"token attr-name"}},[t._v("theme")]),s("span",{attrs:{class:"token attr-value"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("=")]),s("span",{attrs:{class:"token punctuation"}},[t._v('"')]),t._v("black-rhino"),s("span",{attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n"),s("span",{attrs:{class:"token tag"}},[s("span",{attrs:{class:"token tag"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("")]),t._v("vue-good-table")]),s("span",{attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n")])])])},function(){var t=this.$createElement,a=this._self._c||t;return a("h2",{attrs:{id:"nocturnal"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#nocturnal","aria-hidden":"true"}},[this._v("#")]),this._v(" Nocturnal")])},function(){var t=this,a=t.$createElement,s=t._self._c||a;return s("div",{staticClass:"language-html extra-class"},[s("pre",{pre:!0,attrs:{class:"language-html"}},[s("code",[s("span",{attrs:{class:"token tag"}},[s("span",{attrs:{class:"token tag"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("<")]),t._v("vue-good-table")]),t._v("\n "),s("span",{attrs:{class:"token attr-name"}},[t._v(":columns")]),s("span",{attrs:{class:"token attr-value"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("=")]),s("span",{attrs:{class:"token punctuation"}},[t._v('"')]),t._v("columns"),s("span",{attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),s("span",{attrs:{class:"token attr-name"}},[t._v(":rows")]),s("span",{attrs:{class:"token attr-value"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("=")]),s("span",{attrs:{class:"token punctuation"}},[t._v('"')]),t._v("rows"),s("span",{attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),s("span",{attrs:{class:"token attr-name"}},[t._v("theme")]),s("span",{attrs:{class:"token attr-value"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("=")]),s("span",{attrs:{class:"token punctuation"}},[t._v('"')]),t._v("nocturnal"),s("span",{attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n"),s("span",{attrs:{class:"token tag"}},[s("span",{attrs:{class:"token tag"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("")]),t._v("vue-good-table")]),s("span",{attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n")])])])}],!1,null,null,null);a.default=e.exports}}]);
--------------------------------------------------------------------------------
/vp-docs/guide/advanced/grouped-table.md:
--------------------------------------------------------------------------------
1 | # Grouped Table
2 |
3 | To create grouped rows, you need two things.
4 |
5 | #### 1. Add group-options to table component
6 |
7 | ```html
8 |
15 |
16 | ```
17 |
18 | #### 2. Make sure the rows are formatted correctly. Grouped rows need to be nested within header rows containing data rows in their children property. For example:
19 |
20 | ```js
21 | rows: [
22 | {
23 | mode: 'span', // span means this header will span all columns
24 | label: 'Mammal', // this is the label that'll be used for the header
25 | html: false, // if this is true, label will be rendered as html
26 | children: [
27 | { name: 'Elephant', diet: 'herbivore', count: 5 },
28 | { name: 'Cat', diet: 'carnivore', count: 28 }
29 | ]
30 | }
31 | ];
32 | ```
33 |
34 |
35 |
36 | #### 3. Sometimes, you might want a summary row instead of a header row. For example, if you want to show total count for your group
37 |
38 | ```javascript
39 | rows: [
40 | {
41 | name: 'Mammals Total', // this is the label that'll be used for the header
42 | diet: undefined,
43 | count: '', // total count will be displayed here
44 | children: [
45 | { name: 'Elephant', diet: 'herbivore', count: 5 },
46 | { name: 'Cat', diet: 'carnivore', count: 28 }
47 | ]
48 | }
49 | ];
50 | ```
51 |
52 | #### 4. If you want the header/summary row to show up at the bottom of the group, you can specify that in the group-options property of the table.
53 |
54 | ```html
55 |
63 |
64 | ```
65 |
66 |
67 |
68 | #### 5. What if you wanted to add a total count in summary rows?
69 |
70 | 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.
71 |
72 | ```js
73 | // in columns
74 | {
75 | label: 'Count',
76 | field: 'count',
77 | headerField: this.sumCount,
78 | type: 'number',
79 | },
80 |
81 | // in methods we define sumCount
82 | methods: {
83 | sumCount: function (rowObj) {
84 | console.log(rowObj);
85 | let sum = 0;
86 | for (let i = 0; i < rowObj.children.length; i++) {
87 | sum += rowObj.children[i].count;
88 | }
89 | return sum;
90 | },
91 | },
92 |
93 | ```
94 |
95 | ## Customizing Header Row
96 |
97 | If you want more control over what the header row looks like, you can use slots the same way you [customize rows](/guide/advanced/#custom-row-template). For example if you want to add a button in the header row or something, this would be the way to do it.
98 |
99 | ### When mode is 'span'
100 |
101 | In this case, the header row spans across all columns
102 |
103 | ```vue
104 |
112 |
113 |
114 | {{ props.row.label }}
115 |
116 |
117 |
118 | ```
119 |
120 |
121 |
122 | ### When mode is not 'span'
123 |
124 | In this case header row expects a value for each column
125 |
126 | ```vue
127 |
135 |
136 |
137 | Action
138 |
139 |
140 | {{ props.formattedRow[props.column.field] }}
141 |
142 |
143 |
144 | ```
145 |
146 |
147 |
148 | ::: tip
149 |
150 | - The original row object can be accessed via `props.row`
151 | - The column object can be accessed via `props.column`
152 | - You can access the formatted row data (for example - formatted date) via `props.formattedRow`
153 | :::
154 |
155 | ## Collapsable Rows
156 |
157 | To allow the row to collapse and expand you can use the groupOption "collapsable". You can either pass in a boolean or a number.
158 | If `collapsable` is set to `true` then it will default to making the first column collapsable. Alternatively, you can specify the column index number.
159 | If you only add new rows to your table at the end, then the expanded or collapsed state of your rows will be maintained.
160 | 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.
161 | The expanded and collapsed state will then be maintained.
162 | ```html
163 |
173 |
174 | ```
175 | To expand/collapse all you can use the method called `expandAll` or `collapseAll`.
176 | ```js
177 | this.$refs.myCustomTable.expandAll();
178 | this.$refs.myCustomTable.collapseAll();
179 | ```
180 |
181 | * **Live Demo:** https://jsfiddle.net/nb6fcqs7
182 |
183 |
--------------------------------------------------------------------------------
/vp-docs/guide/configuration/table-events.md:
--------------------------------------------------------------------------------
1 | # Table Events
2 |
3 | ## @on-row-click
4 | event emitted on table row click
5 | ```html
6 |
10 | ```
11 | ```javascript
12 | methods: {
13 | onRowClick(params) {
14 | // params.row - row object
15 | // params.pageIndex - index of this row on the current page.
16 | // params.selected - if selection is enabled this argument
17 | // indicates selected or not
18 | // params.event - click event
19 | }
20 | }
21 | ```
22 |
23 | ## @on-row-dblclick
24 | event emitted on table row click
25 | ```html
26 |
30 | ```
31 | ```javascript
32 | methods: {
33 | onRowDoubleClick(params) {
34 | // params.row - row object
35 | // params.pageIndex - index of this row on the current page.
36 | // params.selected - if selection is enabled this argument
37 | // indicates selected or not
38 | // params.event - click event
39 | }
40 | }
41 | ```
42 |
43 | ## @on-cell-click
44 | event emitted on table cell click
45 | ```html
46 |
50 | ```
51 | ```javascript
52 | methods: {
53 | onCellClick(params) {
54 | // params.row - row object
55 | // params.column - column object
56 | // params.rowIndex - index of this row on the current page.
57 | // params.event - click event
58 | }
59 | }
60 | ```
61 |
62 | ## @on-row-mouseenter
63 | event emitted on row mouseenter
64 | ```html
65 |
69 | ```
70 | ```javascript
71 | methods: {
72 | onRowMouseover(params) {
73 | // params.row - row object
74 | // params.pageIndex - index of this row on the current page.
75 | }
76 | }
77 | ```
78 |
79 | ## @on-row-mouseleave
80 | event emitted on table row mouseleave
81 | ```html
82 |
86 | ```
87 | ```javascript
88 | methods: {
89 | onRowMouseleave(row, pageIndex) {
90 | // row - row object
91 | // pageIndex - index of this row on the current page.
92 | }
93 | }
94 | ```
95 |
96 | ## @on-search
97 | event emitted on global search (when global search is enabled)
98 | ```html
99 |
103 | ```
104 | ```javascript
105 | methods: {
106 | onSearch(params) {
107 | // params.searchTerm - term being searched for
108 | // params.rowCount - number of rows that match search
109 | }
110 | }
111 | ```
112 |
113 | ## @on-page-change
114 | event emitted on pagination page change (when pagination is enabled)
115 | ```html
116 |
120 | ```
121 | ```javascript
122 | methods: {
123 | onPageChange(params) {
124 | // params.currentPage - current page that pagination is at
125 | // params.prevPage - previous page
126 | // params.currentPerPage - number of items per page
127 | // params.total - total number of items in the table
128 | }
129 | }
130 | ```
131 |
132 | ## @on-per-page-change
133 | event emitted on per page dropdown change (when pagination is enabled)
134 | ```html
135 |
139 | ```
140 | ```javascript
141 | methods: {
142 | onPageChange(params) {
143 | // params.currentPage - current page that pagination is at
144 | // params.currentPerPage - number of items per page
145 | // params.total - total number of items in the table
146 | }
147 | }
148 | ```
149 |
150 | ## @on-sort-change
151 | event emitted on sort change.
152 | ::: tip
153 | vue-good-table now supports sorting by multiple columns, so the params
154 | is an array.
155 | :::
156 |
157 | ```html
158 |
162 | ```
163 | ```javascript
164 | methods: {
165 | onSortChange(params) {
166 | // params[0].sortType - ascending or descending
167 | // params[0].columnIndex - index of column being sorted
168 | }
169 | }
170 | ```
171 |
172 |
173 | ## @on-column-filter
174 | event emitted when column is filtered (only emitted for remote mode)
175 | ```html
176 |
180 | ```
181 | ```javascript
182 | methods: {
183 | onColumnFilter(params) {
184 | // params.columnFilters - filter values for each column in the following format:
185 | // {field1: 'filterTerm', field3: 'filterTerm2')
186 | }
187 | }
188 | ```
189 |
190 | ## @on-select-all
191 | event emitted when all is selected (only emitted for checkbox tables)
192 | ```html
193 |
198 | ```
199 | ```javascript
200 | methods: {
201 | onSelectAll(params) {
202 | // params.selected - whether the select-all checkbox is checked or unchecked
203 | // params.selectedRows - all rows that are selected (this page)
204 | }
205 | }
206 | ```
207 |
208 | ## @on-selected-rows-change
209 | event emitted whenever selection is changed (on checkbox tables)
210 | ```html
211 |
216 | ```
217 | ```javascript
218 | methods: {
219 | selectionChanged(params) {
220 | // params.selectedRows - all rows that are selected (this page)
221 | }
222 | }
223 | ```
--------------------------------------------------------------------------------
/vp-docs/.vuepress/dist/assets/js/4.df9755ec.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[4],{193:function(t,a,s){"use strict";s.r(a);var n=s(0),e=Object(n.a)({},function(){this.$createElement;this._self._c;return this._m(0)},[function(){var t=this,a=t.$createElement,s=t._self._c||a;return s("div",{staticClass:"content"},[s("h1",{attrs:{id:"sort-options"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#sort-options","aria-hidden":"true"}},[t._v("#")]),t._v(" Sort Options")]),s("p",[t._v("Set of options related to table sorting")]),s("div",{staticClass:"language-html extra-class"},[s("pre",{pre:!0,attrs:{class:"language-html"}},[s("code",[s("span",{attrs:{class:"token tag"}},[s("span",{attrs:{class:"token tag"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("<")]),t._v("vue-good-table")]),t._v("\n "),s("span",{attrs:{class:"token attr-name"}},[t._v(":columns")]),s("span",{attrs:{class:"token attr-value"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("=")]),s("span",{attrs:{class:"token punctuation"}},[t._v('"')]),t._v("columns"),s("span",{attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),s("span",{attrs:{class:"token attr-name"}},[t._v(":rows")]),s("span",{attrs:{class:"token attr-value"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("=")]),s("span",{attrs:{class:"token punctuation"}},[t._v('"')]),t._v("rows"),s("span",{attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),s("span",{attrs:{class:"token attr-name"}},[t._v(":sort-options")]),s("span",{attrs:{class:"token attr-value"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("=")]),s("span",{attrs:{class:"token punctuation"}},[t._v('"')]),t._v("{\n enabled: true,\n initialSortBy: {field: "),s("span",{attrs:{class:"token punctuation"}},[t._v("'")]),t._v("name"),s("span",{attrs:{class:"token punctuation"}},[t._v("'")]),t._v(", type: "),s("span",{attrs:{class:"token punctuation"}},[t._v("'")]),t._v("asc"),s("span",{attrs:{class:"token punctuation"}},[t._v("'")]),t._v("}\n }"),s("span",{attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n"),s("span",{attrs:{class:"token tag"}},[s("span",{attrs:{class:"token tag"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("")]),t._v("vue-good-table")]),s("span",{attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n")])])]),s("h2",{attrs:{id:"enabled"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#enabled","aria-hidden":"true"}},[t._v("#")]),t._v(" enabled")]),s("p",[t._v("type: "),s("code",[t._v("Boolean (default: true)")])]),s("p",[t._v("Enable/disable sorting on table as a whole.")]),s("div",{staticClass:"language-html extra-class"},[s("pre",{pre:!0,attrs:{class:"language-html"}},[s("code",[s("span",{attrs:{class:"token tag"}},[s("span",{attrs:{class:"token tag"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("<")]),t._v("vue-good-table")]),t._v("\n "),s("span",{attrs:{class:"token attr-name"}},[t._v(":columns")]),s("span",{attrs:{class:"token attr-value"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("=")]),s("span",{attrs:{class:"token punctuation"}},[t._v('"')]),t._v("columns"),s("span",{attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),s("span",{attrs:{class:"token attr-name"}},[t._v(":rows")]),s("span",{attrs:{class:"token attr-value"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("=")]),s("span",{attrs:{class:"token punctuation"}},[t._v('"')]),t._v("rows"),s("span",{attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),s("span",{attrs:{class:"token attr-name"}},[t._v(":sort-options")]),s("span",{attrs:{class:"token attr-value"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("=")]),s("span",{attrs:{class:"token punctuation"}},[t._v('"')]),t._v("{\n enabled: true,\n }"),s("span",{attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n"),s("span",{attrs:{class:"token tag"}},[s("span",{attrs:{class:"token tag"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("")]),t._v("vue-good-table")]),s("span",{attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n")])])]),s("h2",{attrs:{id:"initialsortby"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#initialsortby","aria-hidden":"true"}},[t._v("#")]),t._v(" initialSortBy")]),s("p",[t._v("type: "),s("code",[t._v("Object")])]),s("p",[t._v("Allows specifying a default sort for the table on wakeup")]),s("div",{staticClass:"language-html extra-class"},[s("pre",{pre:!0,attrs:{class:"language-html"}},[s("code",[s("span",{attrs:{class:"token tag"}},[s("span",{attrs:{class:"token tag"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("<")]),t._v("vue-good-table")]),t._v("\n "),s("span",{attrs:{class:"token attr-name"}},[t._v(":columns")]),s("span",{attrs:{class:"token attr-value"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("=")]),s("span",{attrs:{class:"token punctuation"}},[t._v('"')]),t._v("columns"),s("span",{attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),s("span",{attrs:{class:"token attr-name"}},[t._v(":rows")]),s("span",{attrs:{class:"token attr-value"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("=")]),s("span",{attrs:{class:"token punctuation"}},[t._v('"')]),t._v("rows"),s("span",{attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),s("span",{attrs:{class:"token attr-name"}},[t._v(":sort-options")]),s("span",{attrs:{class:"token attr-value"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("=")]),s("span",{attrs:{class:"token punctuation"}},[t._v('"')]),t._v("{\n enabled: true,\n initialSortBy: {field: "),s("span",{attrs:{class:"token punctuation"}},[t._v("'")]),t._v("name"),s("span",{attrs:{class:"token punctuation"}},[t._v("'")]),t._v(", type: "),s("span",{attrs:{class:"token punctuation"}},[t._v("'")]),t._v("asc"),s("span",{attrs:{class:"token punctuation"}},[t._v("'")]),t._v("}\n }"),s("span",{attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n"),s("span",{attrs:{class:"token tag"}},[s("span",{attrs:{class:"token tag"}},[s("span",{attrs:{class:"token punctuation"}},[t._v("")]),t._v("vue-good-table")]),s("span",{attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n")])])])])}],!1,null,null,null);a.default=e.exports}}]);
--------------------------------------------------------------------------------