Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat(b-table, b-table-lite): add new scoped slot custom-foot to allow user to create their own table footer (closes #3960) #4027

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Sep 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions src/components/table/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1168,6 +1168,28 @@ Slot `thead-top` can be optionally scoped, receiving an object with the followin
| `selectAllRows` | Method | Select all rows (applicable if the table is in [`selectable`](#row-select-support) mode |
| `clearSelected` | Method | Unselect all rows (applicable if the table is in [`selectable`](#row-select-support) mode |

### Creating a custom footer

If you need greater layout control of the content of the `<tfoot>`, you can use the optionally
scoped slot `custom-foot` to provide your own rows and cells. Use BootstrapVue's
[table helper sub-components](#table-helper-components) `<b-tr>`, `<b-th>`, and `<b-td>` to generate
your custom footer layout.

Slot `custom-foot` can be optionally scoped, receiving an object with the following properties:

| Property | Type | Description |
| --------- | ------ | ------------------------------------------------------------------------------------------ |
| `columns` | Number | The number of columns in the rendered table |
| `fields` | Array | Array of field definition objects (normalized to the array of objects format) |
| `items` | Array | Array of the currently _displayed_ items records - after filtering, sorting and pagination |

**Notes:**

- The `custom-foot` slot will **not** be rendered if the `foot-clone` prop has been set.
- `head-clicked` events are not be emitted when clicking on `custom-foot` cells.
- Sorting and sorting icons are not available for cells in the `custom-foot` slot.
- The custom footer will not be shown when the table is in visually stacked mode.

## Custom empty and emptyfiltered rendering via slots

Aside from using `empty-text`, `empty-filtered-text`, `empty-html`, and `empty-filtered-html`, it is
Expand Down Expand Up @@ -2654,8 +2676,8 @@ helper components. `TableSimplePlugin` is available as a top level named export.
## Table helper components

BootstrapVue provides additional helper child components when using `<b-table-simple>`, or the named
slots `top-row`, `bottom-row`, and `thead-top` (all of which accept table child elements). The
helper components are as follows:
slots `top-row`, `bottom-row`, `thead-top`, and `custom-foot` (all of which accept table child
elements). The helper components are as follows:

- `b-tbody` (`<b-table-simple>` only)
- `b-thead` (`<b-table-simple>` only)
Expand Down
25 changes: 22 additions & 3 deletions src/components/table/helpers/mixin-tfoot.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { getComponentConfig } from '../../../utils/config'
import { BTfoot } from '../tfoot'

export default {
props: {
Expand All @@ -20,11 +21,29 @@ export default {
}
},
methods: {
renderTfoot() {
renderTFootCustom() {
const h = this.$createElement

if (this.hasNormalizedSlot('custom-foot')) {
return h(
BTfoot,
{
key: 'bv-tfoot-custom',
class: this.tfootClass || null,
props: { footVariant: this.footVariant || this.headVariant || null }
},
this.normalizeSlot('custom-foot', {
items: this.computedItems.slice(),
fields: this.computedFields.slice(),
columns: this.computedFields.length
})
)
} else {
return h()
}
},
renderTfoot() {
// Passing true to renderThead will make it render a tfoot
return this.footClone ? this.renderThead(true) : h()
return this.footClone ? this.renderThead(true) : this.renderTFootCustom()
}
}
}
20 changes: 14 additions & 6 deletions src/components/table/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@
},
{
"event": "head-clicked",
"description": "Emitted when a header or footer cell is clicked.",
"description": "Emitted when a header or footer cell is clicked. Not applicable for 'custom-foot' slot.",
"args": [
{
"arg": "key",
Expand Down Expand Up @@ -250,15 +250,19 @@
},
{
"name": "thead-top",
"description": "Slot above the column headers in the `thead` element for user-supplied rows (optionally scoped: columns - number of TDs to provide, fields - array of field definition objects)"
"description": "Slot above the column headers in the `thead` element for user-supplied B-TR's with B-TH/B-TD (optionally scoped: columns - number of TDs to provide, fields - array of field definition objects)"
},
{
"name": "top-row",
"description": "Fixed top row slot for user supplied TD cells (Optionally scoped: columns - number of TDs to provide, fields - array of field definition objects)"
"description": "Fixed top row slot for user supplied B-TD cells (Optionally scoped: columns - number of B-TDs to provide, fields - array of field definition objects)"
},
{
"name": "bottom-row",
"description": "Fixed bottom row slot for user supplied TD cells (Optionally Scoped: columns - number of TDs to provide, fields - array of field definition objects)"
"description": "Fixed bottom row slot for user supplied B-TD cells (Optionally Scoped: columns - number of B-TDs to provide, fields - array of field definition objects)"
},
{
"name": "custom-foot",
"description": "Custom footer content slot for user supplied B-TR, B-TH, B-TD (Optionally Scoped: columns - number columns, fields - array of field definition objects, items - array of currently displayed row items)"
}
]
},
Expand Down Expand Up @@ -375,7 +379,7 @@
},
{
"event": "head-clicked",
"description": "Emitted when a header or footer cell is clicked.",
"description": "Emitted when a header or footer cell is clicked. Not applicable for 'custom-foot' slot.",
"args": [
{
"arg": "key",
Expand Down Expand Up @@ -435,7 +439,11 @@
},
{
"name": "thead-top",
"description": "Slot above the column headers in the `thead` element for user-supplied rows (optionally scoped: columns - number of TDs to provide, fields - array of field definition objects)"
"description": "Slot above the column headers in the `thead` element for user-supplied B-TR with B-TH/B-TD (optionally scoped: columns - number of TDs to provide, fields - array of field definition objects)"
},
{
"name": "custom-foot",
"description": "Custom footer content slot for user supplied B-TR's with B-TH/B-TD (Optionally Scoped: columns - number columns, fields - array of field definition objects, items - array of currently displayed row items)"
}
]
},
Expand Down
91 changes: 91 additions & 0 deletions src/components/table/table-tfoot-custom.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { mount } from '@vue/test-utils'
import { BTable } from './table'

const testItems = [{ a: 1, b: 2, c: 3 }]
const testFields = [{ key: 'a', label: 'A' }, { key: 'b', label: 'B' }, { key: 'c', label: 'C' }]

describe('table > custom tfoot slot', () => {
it('should not render tfoot by default', async () => {
const wrapper = mount(BTable, {
propsData: {
fields: testFields,
items: testItems,
footClone: false
}
})
expect(wrapper).toBeDefined()
expect(wrapper.is('table')).toBe(true)
expect(wrapper.find('thead').exists()).toBe(true)
expect(wrapper.find('tbody').exists()).toBe(true)
expect(wrapper.find('tfoot').exists()).toBe(false)

wrapper.destroy()
})

it('should render custom-foot slot inside b-tfoot', async () => {
const wrapper = mount(BTable, {
propsData: {
fields: testFields,
items: testItems,
footClone: false
},
slots: {
'custom-foot': '<tr><td colspan="3">CUSTOM-FOOTER</td></tr>'
}
})
expect(wrapper).toBeDefined()
expect(wrapper.is('table')).toBe(true)
expect(wrapper.find('thead').exists()).toBe(true)
expect(wrapper.find('tbody').exists()).toBe(true)
expect(wrapper.find('tfoot').exists()).toBe(true)
expect(wrapper.find('tfoot').text()).toContain('CUSTOM-FOOTER')
expect(wrapper.find('tfoot').classes().length).toBe(0)

wrapper.destroy()
})

it('should not render custom-foot slot when foot-clone is true', async () => {
const wrapper = mount(BTable, {
propsData: {
fields: testFields,
items: testItems,
footClone: true
},
slots: {
'custom-foot': '<tr><td colspan="3">CUSTOM-FOOTER</td></tr>'
}
})
expect(wrapper).toBeDefined()
expect(wrapper.is('table')).toBe(true)
expect(wrapper.find('thead').exists()).toBe(true)
expect(wrapper.find('tbody').exists()).toBe(true)
expect(wrapper.find('tfoot').exists()).toBe(true)
expect(wrapper.find('tfoot').text()).not.toContain('CUSTOM-FOOTER')

wrapper.destroy()
})

it('should have foot-variant on custom-foot slot', async () => {
const wrapper = mount(BTable, {
propsData: {
fields: testFields,
items: testItems,
footClone: false,
footVariant: 'dark'
},
slots: {
'custom-foot': '<tr><td colspan="3">CUSTOM-FOOTER</td></tr>'
}
})
expect(wrapper).toBeDefined()
expect(wrapper.is('table')).toBe(true)
expect(wrapper.find('thead').exists()).toBe(true)
expect(wrapper.find('tbody').exists()).toBe(true)
expect(wrapper.find('tfoot').exists()).toBe(true)
expect(wrapper.find('tfoot').text()).toContain('CUSTOM-FOOTER')
expect(wrapper.find('tfoot').classes()).toContain('thead-dark')
expect(wrapper.find('tfoot').classes().length).toBe(1)

wrapper.destroy()
})
})