Permalink
Browse files

feat(table): support custom attributes per table cell in a column (#1760

)
  • Loading branch information...
emanuelmutschlechner authored and pi0 committed Apr 27, 2018
1 parent 1ce1a20 commit fc083e563360bc447674953d9c957ede573dd229
@@ -279,7 +279,7 @@ The following field properties are recognized:
| `thClass` | String or Array | Class name (or array of class names) to add to `<thead>`/`<tfoot>` heading `<th>` cell.
| `thStyle` | Object | JavaScript object representing CSS styles you would like to apply to the table `<thead>`/`<tfoot>` field `<th>`.
| `variant` | String | Apply contextual class to all the `<th>` **and** `<td>` in the column - `active`, `success`, `info`, `warning`, `danger` (these variants map to classes `thead-${variant}`, `table-${variant}`, or `bg-${variant}` accordingly).
| `tdAttr` | Object | JavaScript object representing additional attributes to apply to the `<tbody>` field `td` cell.
| `tdAttr` | Object or Function | JavaScript object representing additional attributes to apply to the `<tbody>` field `<td>` cell. If custom attributes per cell are required, a callback function can be specified instead.
| `isRowHeader` | Boolean | When set to `true`, the field's item data cell will be rendered with `<th>` rather than the default of `<td>`.
>**Notes:**
@@ -5,7 +5,8 @@ window.app = new Vue({
name: {
label: 'Person Full name',
sortable: true,
tdClass: 'bg-primary'
tdClass: 'bg-primary',
tdAttr: {title: 'Person Full name'}
},
age: {
label: 'Person age',
@@ -15,11 +16,13 @@ window.app = new Vue({
},
isActive: {
label: 'is Active',
tdClass: (value, key, item) => { return 'bg-danger' }
tdClass: (value, key, item) => { return 'bg-danger' },
tdAttr: (value, key, item) => { return {title: 'is Active'} }
},
actions: {
label: 'Actions',
tdClass: 'formatCell'
tdClass: 'formatCell',
tdAttr: 'formatCellAttrs'
}
},
currentPage: 1,
@@ -138,6 +141,9 @@ window.app = new Vue({
},
formatCell (value, key, item) {
return ['bg-primary', 'text-light']
},
formatCellAttrs (value, key, item) {
return {title: 'Actions'}
}
}
})
@@ -192,10 +192,9 @@ export default {
const data = {
key: `row-${rowIndex}-cell-${colIndex}`,
class: this.tdClasses(field, item),
attrs: field.tdAttr || {},
attrs: this.tdAttrs(field, item, colIndex),
domProps: {}
}
data.attrs['aria-colindex'] = String(colIndex + 1)
let childNodes
if ($scoped[field.key]) {
childNodes = [
@@ -223,15 +222,6 @@ export default {
childNodes = formatted
}
}
if (this.isStacked) {
// Generate the "header cell" label content in stacked mode
data.attrs['data-label'] = field.label
if (field.isRowHeader) {
data.attrs['role'] = 'rowheader'
} else {
data.attrs['role'] = 'cell'
}
}
// Render either a td or th cell
return h(field.isRowHeader ? 'th' : 'td', data, childNodes)
})
@@ -864,7 +854,6 @@ export default {
]
},
tdClasses (field, item) {
const t = this
let cellVariant = ''
if (item._cellVariants && item._cellVariants[field.key]) {
cellVariant = `${this.dark ? 'bg' : 'table'}-${
@@ -877,9 +866,23 @@ export default {
: '',
cellVariant,
field.class ? field.class : '',
t.getTdClasses(item, field)
this.getTdValues(item, field.key, field.tdClass, '')
]
},
tdAttrs (field, item, colIndex) {
let attrs = {}
attrs['aria-colindex'] = String(colIndex + 1)
if (this.isStacked) {
// Generate the "header cell" label content in stacked mode
attrs['data-label'] = field.label
if (field.isRowHeader) {
attrs['role'] = 'rowheader'
} else {
attrs['role'] = 'cell'
}
}
return assign({}, attrs, this.getTdValues(item, field.key, field.tdAttr, {}))
},
rowClasses (item) {
return [
item._rowVariant
@@ -982,21 +985,19 @@ export default {
this._providerSetLocal(data)
}
},
getTdClasses (item, field) {
const key = field.key
const tdClass = field.tdClass
getTdValues (item, key, tdValue, defValue) {
const parent = this.$parent
if (tdClass) {
if (typeof tdClass === 'function') {
if (tdValue) {
if (typeof tdValue === 'function') {
let value = get(item, key)
return tdClass(value, key, item)
} else if (typeof tdClass === 'string' && typeof parent[tdClass] === 'function') {
return tdValue(value, key, item)
} else if (typeof tdValue === 'string' && typeof parent[tdValue] === 'function') {
let value = get(item, key)
return parent[tdClass](value, key, item)
return parent[tdValue](value, key, item)
}
return tdClass
return tdValue
}
return ''
return defValue
},
getFormattedValue (item, field) {
const key = field.key
@@ -733,6 +733,18 @@ describe('table', async () => {
tr.children[3].classList.contains('bg-primary') &&
tr.children[3].classList.contains('text-light'))
.toBe(true)
expect(Boolean(tr.children[0]) &&
Boolean(tr.children[0].attributes) &&
tr.children[0].getAttribute('title') === 'Person Full name')
.toBe(true)
expect(Boolean(tr.children[2]) &&
Boolean(tr.children[2].attributes) &&
tr.children[2].getAttribute('title') === 'is Active')
.toBe(true)
expect(Boolean(tr.children[3]) &&
Boolean(tr.children[3].attributes) &&
tr.children[3].getAttribute('title') === 'Actions')
.toBe(true)
}
})
})

0 comments on commit fc083e5

Please sign in to comment.