Skip to content
This repository was archived by the owner on Oct 24, 2018. It is now read-only.

Commit

Permalink
Add slot support for footer (#73)
Browse files Browse the repository at this point in the history
* Add slot support for footer

Add test for `tfoot` slot
Minor lint cleanup

* Pass row data information as `tfoot` slot scope

Update documentation and demo examples with `tfoot` slot usage.

Note: with later versions of `vue` we'll need to change the attribute
name from `scope` to `slot-scope`
samtsai authored and sebastiandedeyne committed Nov 2, 2017
1 parent 3ee0d82 commit 2896fed
Showing 9 changed files with 1,463 additions and 1,446 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -2,6 +2,9 @@

All notable changes to `vue-table-component` will be documented in this file

## 1.7.0 - 2017-10-26
- Added named slot `tfoot` to display table footer information, receives row data as scoped properties

## 1.6.1 - 2017-09-25
- Fixed a bug that didn't rerender the table when a column was changed

59 changes: 58 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -226,7 +226,7 @@ Alternatively you can pass a function to the `formatter` prop. Here's an example
export default {
methods: {
formatter(value, rowProperties) {
return `Hi, I am ${value}`;
return `Hi, I am ${value}`;
},
},
}
@@ -235,6 +235,63 @@ export default {

This will display values `Hi, I am John` and `Hi, I am Paul`.

## Adding table footer `<tfoot>` information

Sometimes it can be useful to add information to the bottom of the table like summary data.
A slot named `tfoot` is available and it receives all of the `rows` data to do calculations on the fly or you can show data directly from whatever is available in the parent scope.

```html
<table-component
:data="[{ firstName: 'John', songs: 72 },{ firstName: 'Paul', songs: 70 }]">
<table-column show="firstName" label="First name"></table-column>
<table-column show="songs" label="Songs" data-type="numeric"></table-column>
<template slot="tfoot" scope="{ rows }">
<tr>
<th>Total Songs:</th>
<th>{{ rows.reduce((sum, value) => { return sum + value.data.songs; }, 0) }}</th>
<th>&nbsp;</th>
<th>&nbsp;</th>
</tr>
</template>
</table-component>
```

OR

```vue
<template>
<table-component
:data="tableData">
<table-column show="firstName" label="First name"></table-column>
<table-column show="songs" label="Songs" data-type="numeric"></table-column>
<template slot="tfoot">
<tr>
<th>Total Songs:</th>
<th>{{ totalSongs }}</th>
</tr>
</template>
</table-component>
</template>
<script>
export default {
computed: {
totalSongs () {
return this.tableData.reduce(sum, value => {
return sum + value.songs;
}, 0);
}
},
data () {
return {
tableData: [{ firstName: 'John', songs: 72 },{ firstName: 'Paul', songs: 70 }]
}
}
}
</script>
```

Note: `rows` slot scope data includes more information gathered by the Table Component (e.g. `columns`) and `rows.data` is where the original `data` information is located.

## Changelog

Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.
29 changes: 25 additions & 4 deletions __tests__/components/table-component/TableComponent.test.js
Original file line number Diff line number Diff line change
@@ -84,6 +84,27 @@ describe('TableComponent', () => {
expect(document.body.innerHTML).toMatchSnapshot();
});

it('supports a named slot to display a tfoot section', async () => {
document.body.innerHTML = `
<div id="app">
<table-component
:data="[{ firstName: 'John' },{ firstName: 'Paul' }]">
<table-column show="firstName" label="First name"></table-column>
<template slot="tfoot" scope="{ rows }">
<tr>
<td>Name count:</td>
<td>{{ rows.length }}</td>
</tr>
</template>
</table-component>
</div>
`;

await createVm();

expect(document.body.innerHTML).toMatchSnapshot();
});

it('has an prop to disable the filter', async () => {
document.body.innerHTML = `
<div id="app">
@@ -189,7 +210,7 @@ describe('TableComponent', () => {
it('can accept a function to fetch the data', async () => {
const serverResponse = () => {
return {
data: [{firstName: 'John'}, {id: 2, firstName: 'Paul'}],
data: [{ firstName: 'John' }, { id: 2, firstName: 'Paul' }],
};
};

@@ -213,7 +234,7 @@ describe('TableComponent', () => {
it('can render pagination when the server responds with pagination data', async () => {
const serverResponse = () => {
return {
data: [{firstName: 'John'}, {id: 2, firstName: 'Paul'}],
data: [{ firstName: 'John' }, { id: 2, firstName: 'Paul' }],

pagination: {
totalPages: 4,
@@ -240,9 +261,9 @@ describe('TableComponent', () => {
});

it('clicking a link in the pagination will rerender the table', async () => {
const serverResponse = ({page}) => {
const serverResponse = ({ page }) => {
return {
data: [{firstName: `John ${page}`}, {id: 2, firstName: `Paul ${page}`}],
data: [{ firstName: `John ${page}` }, { id: 2, firstName: `Paul ${page}` }],

pagination: {
totalPages: 4,
Original file line number Diff line number Diff line change
@@ -48,6 +48,8 @@ exports[`TableComponent accepts a function to format values 1`] = `
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
@@ -102,6 +104,8 @@ exports[`TableComponent can accept a function to fetch the data 1`] = `
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
@@ -156,6 +160,8 @@ exports[`TableComponent can add extra classes to the table, the cells and the he
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
@@ -204,6 +210,8 @@ exports[`TableComponent can display a custom message when filtering results in n
</thead>
<tbody class="table-component__table__body">
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<div class="table-component__message">
@@ -254,6 +262,8 @@ exports[`TableComponent can display a custom placeholder in the filter field 1`]
</thead>
<tbody class="table-component__table__body">
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<div class="table-component__message">
@@ -310,6 +320,8 @@ exports[`TableComponent can display nested properties 1`] = `
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
@@ -364,6 +376,8 @@ exports[`TableComponent can mount 1`] = `
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
@@ -418,6 +432,8 @@ exports[`TableComponent can render pagination when the server responds with pagi
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
@@ -495,6 +511,8 @@ exports[`TableComponent can update columns 1`] = `
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
@@ -549,6 +567,8 @@ exports[`TableComponent can update columns 2`] = `
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
@@ -603,6 +623,8 @@ exports[`TableComponent clicking a link in the pagination will rerender the tabl
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
@@ -680,6 +702,8 @@ exports[`TableComponent clicking a link in the pagination will rerender the tabl
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
@@ -752,6 +776,8 @@ exports[`TableComponent has an prop to disable the caption 1`] = `
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
@@ -800,6 +826,72 @@ exports[`TableComponent has an prop to disable the filter 1`] = `
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
<div style="display: none;">
<!---->
</div>
<!---->
</div>
</div>
`;
exports[`TableComponent supports a named slot to display a tfoot section 1`] = `
<div id="app">
<div class="table-component">
<div class="table-component__filter">
<input type="text"
placeholder="Filter table…"
class="table-component__filter__field"
>
<!---->
</div>
<div class="table-component__table-wrapper">
<table class="table-component__table">
<caption role="alert"
aria-live="polite"
class="table-component__table__caption"
>
Table not sorted
</caption>
<thead class="table-component__table__head">
<tr>
<th role="columnheader"
scope="col"
aria-sort="none"
class="table-component__th table-component__th--sort"
>
First name
</th>
</tr>
</thead>
<tbody class="table-component__table__body">
<tr>
<td>
John
</td>
</tr>
<tr>
<td>
Paul
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>
Name count:
</td>
<td>
2
</td>
</tr>
</tfoot>
</table>
</div>
<!---->
@@ -854,6 +946,8 @@ exports[`TableComponent supports a scoped slot inside the table column 1`] = `
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
@@ -902,6 +996,8 @@ exports[`TableComponent will use the property name as a column heading if label
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
@@ -949,6 +1045,8 @@ exports[`TableComponent won't use the property name as a column heading if label
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
Original file line number Diff line number Diff line change
@@ -53,6 +53,8 @@ exports[`Filterable tableComponent can add a custom html class on the filter inp
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
@@ -116,6 +118,8 @@ exports[`Filterable tableComponent can filter data 1`] = `
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
@@ -170,6 +174,8 @@ exports[`Filterable tableComponent can filter on another property 1`] = `
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
@@ -230,6 +236,8 @@ exports[`Filterable tableComponent hides the filter when no columns are filterab
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
@@ -285,6 +293,8 @@ exports[`Filterable tableComponent will display a message if there are no matchi
</thead>
<tbody class="table-component__table__body">
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<div class="table-component__message">
@@ -351,6 +361,8 @@ exports[`Filterable tableComponent will filter data in a case-insensitive way 1`
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
@@ -407,6 +419,8 @@ exports[`Filterable tableComponent will not use columns that are not filterable
</thead>
<tbody class="table-component__table__body">
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<div class="table-component__message">
Original file line number Diff line number Diff line change
@@ -72,6 +72,8 @@ exports[`Sortable tableComponent can sort on another column 1`] = `
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
@@ -177,6 +179,8 @@ exports[`Sortable tableComponent can sort the data with by a specific column 1`]
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
@@ -283,6 +287,8 @@ exports[`Sortable tableComponent can sort the data with by a specific column in
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
@@ -389,6 +395,8 @@ exports[`Sortable tableComponent can sort the data with by another specific colu
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
@@ -495,6 +503,8 @@ exports[`Sortable tableComponent it will change the sort order when clicking the
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
@@ -601,6 +611,8 @@ exports[`Sortable tableComponent will not sort data when clicking a non-sortable
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
@@ -707,6 +719,8 @@ exports[`Sortable tableComponent will not sort on a column that is not sortable
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
@@ -813,6 +827,8 @@ exports[`Sortable tableComponent will sort the data ascendingly if the header of
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
@@ -915,6 +931,8 @@ exports[`Sortable tableComponent wont break if a sortable column has no data 1`]
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
<!---->
2,673 changes: 1,233 additions & 1,440 deletions docs/build/app.js

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions docs/index.html
Original file line number Diff line number Diff line change
@@ -153,6 +153,16 @@ <h1 class="page-title">
</a>
</template>
</table-column>
<template slot="tfoot" scope="{ rows }">
<tr>
<th>&nbsp;</th>
<th>&nbsp;</th>
<th>Total Songs:</th>
<th>{{ rows.reduce((sum, value) => { return sum + value.data.songs; }, 0) }}</th>
<th>&nbsp;</th>
<th>&nbsp;</th>
</tr>
</template>
</table-component>

<section class="page-about">
5 changes: 4 additions & 1 deletion src/components/TableComponent.vue
Original file line number Diff line number Diff line change
@@ -38,6 +38,9 @@
:columns="columns"
></table-row>
</tbody>
<tfoot>
<slot name="tfoot" :rows="rows"></slot>
</tfoot>
</table>
</div>

@@ -74,7 +77,7 @@
},
props: {
data: {default: () => [], type: [Array, Function]},
data: { default: () => [], type: [Array, Function] },
showFilter: { default: true },
showCaption: { default: true },

0 comments on commit 2896fed

Please sign in to comment.