diff --git a/src/components/table/README.md b/src/components/table/README.md
index 663e449006d..b784193c098 100644
--- a/src/components/table/README.md
+++ b/src/components/table/README.md
@@ -233,25 +233,26 @@ formatting, etc). Only columns (keys) that appear in the fields array will be sh
The following field properties are recognized:
-| Property | Type | Description |
-| ------------------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `key` | String | The key for selecting data from the record in the items array. Required when setting the `fields` via an array of objects. |
-| `label` | String | Appears in the columns table header (and footer if `foot-clone` is set). Defaults to the field's key (in humanized format) if not provided. It's possible to use empty labels by assigning an empty string `""` but be sure you also set `headerTitle` to provide non-sighted users a hint about the column contents. |
-| `headerTitle` | String | Text to place on the fields header `
` field `` cell. If custom attributes per cell are required, a callback function can be specified instead. The function will be called as `thAttr( value, key, item, type )` and it may return an `Object`. |
+| `isRowHeader` | Boolean | When set to `true`, the field's item data cell will be rendered with ` | ` rather than the default of ` | `. |
+| `stickyColumn` | Boolean | NEW in 2.0.0-rc.28 When set to `true`, and the table in in [responsive](#responsive-tables) mode or has [sticky headers](#sticky-headers), will cause the column to become fixed to the left when the table's horizontal scrollbar is scrolled. See [Sticky columns](#sticky-columns) for more details |
**Notes:**
diff --git a/src/components/table/helpers/mixin-tbody-row.js b/src/components/table/helpers/mixin-tbody-row.js
index a0f155ae2a0..784d8132277 100644
--- a/src/components/table/helpers/mixin-tbody-row.js
+++ b/src/components/table/helpers/mixin-tbody-row.js
@@ -33,6 +33,19 @@ export default {
}
return defValue
},
+ getThValues(item, key, thValue, type, defValue) {
+ const parent = this.$parent
+ if (thValue) {
+ const value = get(item, key, '')
+ if (isFunction(thValue)) {
+ return thValue(value, key, item, type)
+ } else if (isString(thValue) && isFunction(parent[thValue])) {
+ return parent[thValue](value, key, item, type)
+ }
+ return thValue
+ }
+ return defValue
+ },
// Method to get the value for a field
getFormattedValue(item, field) {
const key = field.key
@@ -169,7 +182,9 @@ export default {
},
attrs: {
'aria-colindex': String(colIndex + 1),
- ...this.getTdValues(item, key, field.tdAttr, {})
+ ...(field.isRowHeader
+ ? this.getThValues(item, key, field.thAttr, 'row', {})
+ : this.getTdValues(item, key, field.tdAttr, {}))
}
}
const slotScope = {
diff --git a/src/components/table/helpers/mixin-thead.js b/src/components/table/helpers/mixin-thead.js
index 5468d520451..d6bdddb4f1b 100644
--- a/src/components/table/helpers/mixin-thead.js
+++ b/src/components/table/helpers/mixin-thead.js
@@ -95,6 +95,7 @@ export default {
title: field.headerTitle || null,
'aria-colindex': String(colIndex + 1),
'aria-label': ariaLabel,
+ ...this.getThValues(null, field.key, field.thAttr, isFoot ? 'foot' : 'head', {}),
...sortAttrs
},
on: handlers
diff --git a/src/components/table/index.d.ts b/src/components/table/index.d.ts
index 5483ce42cdd..7269c60d5fd 100644
--- a/src/components/table/index.d.ts
+++ b/src/components/table/index.d.ts
@@ -151,6 +151,7 @@ export interface BvTableField {
thStyle?: any
variant?: BvTableVariant | string
tdAttr?: any | ((value: any, key: string, item: any) => any)
+ thAttr?: any | ((value: any, key: string, item: any, type: string) => any)
isRowHeader?: boolean
}
diff --git a/src/components/table/table-lite.spec.js b/src/components/table/table-lite.spec.js
index 5a16dd1c2b9..98417c5e0fb 100644
--- a/src/components/table/table-lite.spec.js
+++ b/src/components/table/table-lite.spec.js
@@ -589,6 +589,61 @@ describe('table-lite', () => {
wrapper.destroy()
})
+ it('item field thAttr works', async () => {
+ const Parent = {
+ methods: {
+ parentThAttrs(value, key, item, type) {
+ return { 'data-type': type }
+ }
+ }
+ }
+
+ const wrapper = mount(BTableLite, {
+ parentComponent: Parent,
+ propsData: {
+ items: [{ a: 1, b: 2, c: 3 }],
+ fields: [
+ { key: 'a', thAttr: { 'data-foo': 'bar' } },
+ { key: 'b', thAttr: 'parentThAttrs', isRowHeader: true },
+ {
+ key: 'c',
+ thAttr: (v, k, i, t) => {
+ return { 'data-type': t }
+ }
+ }
+ ]
+ }
+ })
+
+ expect(wrapper).toBeDefined()
+ expect(wrapper.findAll('thead > tr').length).toBe(1)
+ expect(wrapper.findAll('thead > tr > th').length).toBe(3)
+ expect(wrapper.findAll('tbody > tr').length).toBe(1)
+ expect(wrapper.findAll('tbody > tr > td').length).toBe(2)
+ expect(wrapper.findAll('tbody > tr > th').length).toBe(1)
+
+ const $headerThs = wrapper.findAll('thead > tr > th')
+ expect($headerThs.at(0).attributes('data-foo')).toBe('bar')
+ expect($headerThs.at(0).attributes('data-type')).not.toBeDefined()
+ expect($headerThs.at(0).classes().length).toBe(0)
+
+ expect($headerThs.at(1).attributes('data-foo')).not.toBeDefined()
+ expect($headerThs.at(1).attributes('data-type')).toBe('head')
+ expect($headerThs.at(1).classes().length).toBe(0)
+
+ expect($headerThs.at(2).attributes('data-foo')).not.toBeDefined()
+ expect($headerThs.at(2).attributes('data-type')).toBe('head')
+ expect($headerThs.at(2).classes().length).toBe(0)
+
+ const $bodyThs = wrapper.findAll('tbody > tr > th')
+
+ expect($bodyThs.at(0).attributes('data-foo')).not.toBeDefined()
+ expect($bodyThs.at(0).attributes('data-type')).toBe('row')
+ expect($bodyThs.at(0).classes().length).toBe(0)
+
+ wrapper.destroy()
+ })
+
it('item field formatter as function works', async () => {
const wrapper = mount(BTableLite, {
propsData: {
diff --git a/src/components/table/table.spec.js b/src/components/table/table.spec.js
index 1bd90bb63e1..332ef0a7e6a 100644
--- a/src/components/table/table.spec.js
+++ b/src/components/table/table.spec.js
@@ -632,4 +632,59 @@ describe('table', () => {
wrapper.destroy()
})
+
+ it('item field thAttr works', async () => {
+ const Parent = {
+ methods: {
+ parentThAttrs(value, key, item, type) {
+ return { 'data-type': type }
+ }
+ }
+ }
+
+ const wrapper = mount(BTable, {
+ parentComponent: Parent,
+ propsData: {
+ items: [{ a: 1, b: 2, c: 3 }],
+ fields: [
+ { key: 'a', thAttr: { 'data-foo': 'bar' } },
+ { key: 'b', thAttr: 'parentThAttrs', isRowHeader: true },
+ {
+ key: 'c',
+ thAttr: (v, k, i, t) => {
+ return { 'data-type': t }
+ }
+ }
+ ]
+ }
+ })
+
+ expect(wrapper).toBeDefined()
+ expect(wrapper.findAll('thead > tr').length).toBe(1)
+ expect(wrapper.findAll('thead > tr > th').length).toBe(3)
+ expect(wrapper.findAll('tbody > tr').length).toBe(1)
+ expect(wrapper.findAll('tbody > tr > td').length).toBe(2)
+ expect(wrapper.findAll('tbody > tr > th').length).toBe(1)
+
+ const $headerThs = wrapper.findAll('thead > tr > th')
+ expect($headerThs.at(0).attributes('data-foo')).toBe('bar')
+ expect($headerThs.at(0).attributes('data-type')).not.toBeDefined()
+ expect($headerThs.at(0).classes().length).toBe(0)
+
+ expect($headerThs.at(1).attributes('data-foo')).not.toBeDefined()
+ expect($headerThs.at(1).attributes('data-type')).toBe('head')
+ expect($headerThs.at(1).classes().length).toBe(0)
+
+ expect($headerThs.at(2).attributes('data-foo')).not.toBeDefined()
+ expect($headerThs.at(2).attributes('data-type')).toBe('head')
+ expect($headerThs.at(2).classes().length).toBe(0)
+
+ const $bodyThs = wrapper.findAll('tbody > tr > th')
+
+ expect($bodyThs.at(0).attributes('data-foo')).not.toBeDefined()
+ expect($bodyThs.at(0).attributes('data-type')).toBe('row')
+ expect($bodyThs.at(0).classes().length).toBe(0)
+
+ wrapper.destroy()
+ })
})
|