Skip to content

Commit

Permalink
fix(b-table, b-table-lite, b-tbody): fix delegated event handlers whe…
Browse files Browse the repository at this point in the history
…n transition + minor adjustment to row `key` generation (fixes #4370) (#4372)
  • Loading branch information
tmorehouse committed Nov 11, 2019
1 parent f54ca29 commit 030a3d8
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 17 deletions.
9 changes: 4 additions & 5 deletions src/components/table/helpers/mixin-tbody-row.js
Expand Up @@ -205,12 +205,12 @@ export default {
// rows index within the tbody.
// See: https://github.com/bootstrap-vue/bootstrap-vue/issues/2410
const primaryKey = this.primaryKey
const hasPkValue = primaryKey && !isUndefinedOrNull(item[primaryKey])
const rowKey = hasPkValue ? toString(item[primaryKey]) : String(rowIndex)
const primaryKeyValue = toString(get(item, primaryKey)) || null
const rowKey = primaryKeyValue || String(rowIndex)

// If primary key is provided, use it to generate a unique ID on each tbody > tr
// In the format of '{tableId}__row_{primaryKeyValue}'
const rowId = hasPkValue ? this.safeId(`_row_${item[primaryKey]}`) : null
const rowId = primaryKeyValue ? this.safeId(`_row_${primaryKeyValue}`) : null

// Selectable classes and attributes
const selectableClasses = this.selectableRowClasses ? this.selectableRowClasses(rowIndex) : {}
Expand All @@ -233,8 +233,7 @@ export default {
attrs: {
id: rowId,
tabindex: hasRowClickHandler ? '0' : null,
'data-pk': rowId ? String(item[primaryKey]) : null,
// Should this be `aria-details` instead?
'data-pk': primaryKeyValue || null,
'aria-details': detailsId,
'aria-owns': detailsId,
'aria-rowindex': ariaRowIndex,
Expand Down
7 changes: 5 additions & 2 deletions src/components/table/helpers/mixin-tbody.js
@@ -1,5 +1,5 @@
import KeyCodes from '../../../utils/key-codes'
import { arrayIncludes } from '../../../utils/array'
import { arrayIncludes, from as arrayFrom } from '../../../utils/array'
import { closest, isElement } from '../../../utils/dom'
import { props as tbodyProps, BTbody } from '../tbody'
import filterEvent from './filter-event'
Expand All @@ -23,11 +23,14 @@ export default {
// Returns all the item TR elements (excludes detail and spacer rows)
// `this.$refs.itemRows` is an array of item TR components/elements
// Rows should all be B-TR components, but we map to TR elements
// Also note that `this.$refs.itemRows` may not always be in document order
const tbody = this.$refs.tbody.$el || this.$refs.tbody
const trs = (this.$refs.itemRows || []).map(tr => tr.$el || tr)
// TODO: This may take time for tables many rows, so we may want to cache
// the result of this during each render cycle on a non-reactive
// property. We clear out the cache as each render starts, and
// populate it on first access of this method if null
return (this.$refs.itemRows || []).map(tr => tr.$el || tr)
return arrayFrom(tbody.children).filter(tr => arrayIncludes(trs, tr))
},
getTbodyTrIndex(el) {
// Returns index of a particular TBODY item TR
Expand Down
24 changes: 14 additions & 10 deletions src/components/table/tbody.js
Expand Up @@ -71,21 +71,25 @@ export const BTbody = /*#__PURE__*/ Vue.extend({
},
tbodyProps() {
return this.tbodyTransitionProps ? { ...this.tbodyTransitionProps, tag: 'tbody' } : {}
},
tbodyListeners() {
const handlers = this.tbodyTransitionHandlers || {}
return { ...this.$listeners, ...handlers }
}
},
render(h) {
const data = {
props: this.tbodyProps,
attrs: this.tbodyAttrs
}
if (this.isTransitionGroup) {
// We use native listeners if a transition group
// for any delegated events
data.on = this.tbodyTransitionHandlers || {}
data.nativeOn = this.$listeners || {}
} else {
// Otherwise we place any listeners on the tbody element
data.on = this.$listeners || {}
}
return h(
this.isTransitionGroup ? 'transition-group' : 'tbody',
{
props: this.tbodyProps,
attrs: this.tbodyAttrs,
// Pass down any listeners
on: this.tbodyListeners
},
data,
this.normalizeSlot('default', {})
)
}
Expand Down

0 comments on commit 030a3d8

Please sign in to comment.