Skip to content

Commit

Permalink
feat(table): add field data formatter prop (#739)
Browse files Browse the repository at this point in the history
* 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 9da94a6
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 114 deletions.
10 changes: 1 addition & 9 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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',
Expand Down Expand Up @@ -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}],
Expand Down Expand Up @@ -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',
Expand Down Expand Up @@ -285,4 +277,4 @@ module.exports = {
'never'
]
}
};
};
34 changes: 31 additions & 3 deletions docs/components/table/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ Example format:
{
name: {
label: 'Person Full name',
sortable: true
sortable: true,
formatter: 'personFullName'
},
age: {
label: 'Person age',
Expand All @@ -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.
Expand All @@ -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:
Expand Down Expand Up @@ -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:

Expand Down Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion examples/table/demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -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>
45 changes: 25 additions & 20 deletions examples/table/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ window.app = new Vue({
},
age: {
label: 'Person age',
sortable: true
sortable: true,
formatter: 'formatAge'
},
isActive: {
label: 'is Active'
Expand Down Expand Up @@ -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;
}
}
},
Expand All @@ -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`;
}
}
});
Expand Down
Loading

0 comments on commit 9da94a6

Please sign in to comment.