# Building A Bootstrap-Vue table columns picker

Jan 7, 2021

Recently I’ve been using bootstrap-vue and found it a joy to build UI components with Vue.

One thing I needed was a <btable> columns picker. I had a table with lots of columns, and don’t want to show all columns at once. User can customize the views themselves with this old-style UI.

The design is to have a columns picker like the one shown below. Users can choose which columns to show on the table.

Editing the table columns is a one-off task. Doing so shouldn’t need to leave the current page. After the configuration step, users can see the updated table. At the end, I made it as a modal.

I used the <b-modal> together with <b-select>.

The core part of the code is like below:

<template>
<b-modal
:id="id"
size="lg"
centered
title="Columns Picker"
:static="true"
@show="showCurrentColumnConfigs"
@ok="applyColumnConfigs">
<template #default="">
<b-container>
<b-row cols="11">
<b-col cols="5">
<b-form-group
label="Select multiple columns to show"
label-for="selected-hidden-columns"
>
<b-form-select
id="selected-hidden-columns"
v-model="modal.selectedHiddenColumns"
:options="modal.hiddenColumns"
multiple
:select-size="20"
/>
</b-form-group>
</b-col>
<b-col cols="1">
<b-button-group vertical class="mt-5">
<!-- ... render button icons here  -->
</b-button-group>
</b-col>
<b-col cols="5">
<b-form-group
label="Shown"
label-for="selected-shown-columns"
>
<b-form-select
id="selected-shown-columns"
v-model="modal.selectedShownColumns"
:options="modal.shownColumns"
multiple
:select-size="20"
/>
</b-form-group>
</b-col>
</b-row>
</b-container>
</template>
<template #modal-footer="{ ok, cancel }">
<b-container>
<b-row align-h="center">
<b-button
@click="ok()"
class="mr-4"
:disabled="modal.shownColumns.length === 0">
Apply
</b-button>
<b-button @click="cancel()">
Cancel
</b-button>
</b-row>
</b-container>
</template>
</b-modal>
</template>


To use this component, you can do:

<template>
<div>
<b-button variant="primary" class="mb-2" v-b-modal.columns-config-modal>
Show Columns Picker
</b-button>
<BTableColumnsPicker
:allColumns="allColumns()"
:currentColumns="columns"
:id="'columns-config-modal'"
@apply="applyColumnConfigs"
/>
<b-table
id="dataList"
striped
bordered
hover
:items="items"
:fields="columns"
>
</b-table>
</div>
</template>


Some explanations:

• The component is a special <b-modal> that we can trigger with a button.
• The component takes in two column arrays which represent:
• the current columns
• all the available columns for picking
• Modal has two built-in custom events @show and @ok that we can listen and prepare rendering the two columns selectors
• When users click the apply button, the widget emits an @apply event and the parent component can handle it accordingly.
• To make the component test friendly, I added :static="true" to the b-modal. This renders the modal content in-place in the DOM instead of appending it to the body. With this, the jest test can examine the content and make assertions.
• The current UI uses two multi-select components from bootstrap. And it doesn’t support reordering the selection easily. If you need reordering, consider using the two-list vue-draggable.

The rest of the logic is available in this repo.

P.S. I tried to follow the instructions and publish this as an NPM package. But I didn’t get the bootstrap-vue dependency to work nicely with rollup. If you have done it before or have thoughts, feel free to drop me a note!

Share: