Permalink
Browse files

feat(table): add field data formatter prop (#739)

* 1. Add new prop to field - formatter, to allow custom formatting via callback function
2. Add api-url prop to pass to callback item provider function
3. Move sortBy and sortDesc props to Props instead Data, to allow define custom sorting on mount
4. Some refactor
5. edit (Doc) Add formatter using info and examples
  • Loading branch information...
mosinve committed Aug 4, 2017
1 parent 919344b commit 9da94a6a72c2527c01624a3d459a0c38520a8b96
Showing with 158 additions and 114 deletions.
  1. +1 −9 .eslintrc.js
  2. +31 −3 docs/components/table/README.md
  3. +0 −1 examples/table/demo.html
  4. +25 −20 examples/table/demo.js
  5. +101 −81 lib/components/table.vue
@@ -77,10 +77,6 @@ module.exports = {
'eqeqeq': 'off',
'func-call-spacing': 'error',
'func-name-matching': 'error',
'func-names': [
'error',
'never'
],
'func-style': 'error',
'generator-star-spacing': 'error',
'global-require': 'off',
@@ -109,7 +105,6 @@ module.exports = {
'lines-around-directive': 'error',
'max-depth': 'error',
'max-len': 'off',
'max-lines': 'error',
'max-nested-callbacks': 'error',
'max-params': ['error', 4],
'max-statements': 'off',
@@ -203,7 +198,6 @@ module.exports = {
'no-trailing-spaces': 'off',
'no-undef-init': 'error',
'no-undefined': 'warn',
'no-underscore-dangle': 'error',
'no-unmodified-loop-condition': 'error',
'no-unneeded-ternary': 'error',
'no-unused-expressions': ['error', {'allowShortCircuit': true, 'allowTernary': true}],
@@ -242,8 +236,6 @@ module.exports = {
'prefer-numeric-literals': 'error',
'prefer-promise-reject-errors': 'error',
'prefer-reflect': 'off',
'prefer-rest-params': 'error',
'prefer-spread': 'error',
'prefer-template': 'off',
'quote-props': 'off',
'quotes': 'off',
@@ -285,4 +277,4 @@ module.exports = {
'never'
]
}
};
};
@@ -127,7 +127,8 @@ Example format:
{
name: {
label: 'Person Full name',
sortable: true
sortable: true,
formatter: 'personFullName'
},
age: {
label: 'Person age',
@@ -147,6 +148,7 @@ Supported field properties:
| `thClass` | String or Array | Class name (or array of class names) to add to header/footer `<th>` cell
| `tdClass` | String or Array | Class name (or array of class names) to add to data `<td>` cells in the column
| `thStyle` | Object | JavaScript object representing CSS styles you would like to apply to the table field `<th>`
| `formatter` | String or Function | A formatter callback function, can be used instead of slots for real table fields (i.e. fields, that have corresponding data at items array)
Notes:
- Field properties, if not present, default to null unless otherwise stated above.
@@ -156,6 +158,7 @@ Notes:
in the Vue.js guide.
- Any additional properties added to the field objects will be left intact - so you can access
them via the named scoped slots for custom data, header, and footer rendering.
- by design, slots and formatter are **mutually exclusive**. Ie. if formatter defined at field props, then slot will not be used even if it defined for this field.
### Items (record data)
`items` are real table data record objects in array format. Example format:
@@ -223,8 +226,10 @@ See the **"Using Items Provider functions"** section below for more details.
### Custom Data Rendering
Custom rendering for each data field in a row is possible using
[scoped slots](http://vuejs.org/v2/guide/components.html#Scoped-Slots).
Custom rendering for each data field in a row is possible using either
[scoped slots](http://vuejs.org/v2/guide/components.html#Scoped-Slots) or formatter callback function.
####Slots
If you want to add an extra field which does not exist in the records,
just add it to the `fields` array. Example:
@@ -310,6 +315,29 @@ event:
<b-btn size="sm" @click.stop="details(cell.item,cell.index,$event.target)">Details</b-btn>
</template>
```
#### Formatter callback
Other option to make custom field output is to use formatter callback function.
To enable this field's property `formatter` is used. Value of this property may be
String or function reference. In case of String value, function must be defined at parent component's methods,
to provide formatter as `Function`, it must be declared at global scope (window or as global mixin at Vue).
Example:
```js
{
name: {
label: 'Person Full name',
sortable: true,
formatter: 'personFullName'
},
age: {
label: 'Person age',
sortable: false,
fomatter: personAge
}
}
```
### Header/Footer Custom Rendering
It is also possible to provide custom rendering for the tables `thead` and
@@ -124,5 +124,4 @@ <h2>Provider Test Table</h2>
<b-btn size="sm" @click.stop="details(data.item)">Details</b-btn>
</template>
</b-table>
</div>
@@ -8,7 +8,8 @@ window.app = new Vue({
},
age: {
label: 'Person age',
sortable: true
sortable: true,
formatter: 'formatAge'
},
isActive: {
label: 'is Active'
@@ -79,13 +80,14 @@ window.app = new Vue({
},
computed: {
provider() {
// we are usig provider wrappers here to trigger a reload
if (this.providerType === 'promise') {
return this._promiseProvider;
} else if (this.providerType === 'callback') {
return this._callbackProvider;
} else {
return this._arrayProvider;
// we are using provider wrappers here to trigger a reload
switch (this.providerType){
case 'promise':
return this._promiseProvider;
case 'callback':
return this._callbackProvider;
default:
return this._arrayProvider;
}
}
},
@@ -105,19 +107,22 @@ window.app = new Vue({
},
_provider(ctx, cb) {
const items = this.items.slice();
if (this.providerType === 'callback') {
setTimeout(() => {
cb(items);
}, 1)
return;
} else if (this.providerType === 'promise') {
const p = new Promise(resolve => setTimeout(resolve, 1));
return p.then(() => {
return items;
});
} else {
return items;
switch (this.providerType){
case 'callback':
setTimeout(() => {cb(items);}, 1)
return;
case 'promise':
const p = new Promise(resolve => setTimeout(resolve, 1));
return p.then(() => {
return items;
});
default:
return items;
}
},
formatAge(value){
return `${value} years old`;
}
}
});
Oops, something went wrong.

0 comments on commit 9da94a6

Please sign in to comment.