I have a table header that looks like this:
I'm trying to recreate this table in bootstrap-vue. The raw HTML looks like this (simplified):
<table>
<thead>
<tr>
<th></th>
<th colspan="4">Group 1</th>
<th colspan="4">Group 2</th>
<!--etc-->
</tr>
<tr>
<th>Field</th>
<th>Median</th>
<!-- etc -->
</tr>
</thead>
<tbody><!-- actual data --></tbody>
</table>
The core b-table code will create the 2nd row easily/automatically. I'm trying to figure out how to jam the 1st row in there. As a little kicker, I need to be able to control the contents of the two group names (i.e. if they change a control somewhere, "Group 1" becomes "Group Foo").
I made a playground for anyone that needs a starting point for helping figure this out: https://codesandbox.io/s/p56y3y2lnx The goal in there would be to programmically add a 1st row that includes the group1name
and spans the width of the table in one colspan.
As of version v2.0.0-rc.14 (released 2019-03-08) you can now add additional rows above the header using the slot thead-top
.
For your example, you would place the following code inside of the b-table
tag:
<template slot="thead-top" slot-scope="data">
<tr>
<th></th>
<th colspan="3">Group 1</th>
<th colspan="4">Group 2</th>
<th colspan="4"></th>
</tr>
</template>
Here's a reference to the new feature: https://bootstrap-vue.js.org/docs/components/table/#adding-additional-rows-to-the-header
I was unable to find a clean way to achieve the results I wanted, so I ended up with something more hacky.
On b-table
you can add an input
event, so I did that to know when the table was finished loading.
HTML:
<b-table @input="tableLoaded" ref="table"></b-table>
then in my methods:
tableLoaded() {
if (!this.$refs.table) {
return;
}
var headers = this.$refs.table.$el.querySelectorAll('thead tr');
if (headers.length > 1) {
return;//nothing to do, header row already created
}
var topHeader = document.createElement('tr');
topHeader.innerHTML =
'<th></th>'+
'<th colspan="3">Group 1</th>'+
'<th colspan="4">Group 2</th>'+
'<th colspan="4"></th>';
headers[0].parentNode.insertBefore(topHeader, headers[0]);
}
I'd be happy to accept a cleaner solution.