Bootstrap Vue Dynamic table templating

15,980

Solution 1

Here's a jsfiddle showing dynamic columns with a b-table: https://jsfiddle.net/nardnob/wvk6fxgt/

new Vue({
	el: "#app",
	data: {
   fields: [{
     key: "id",
     label: "Id",
     colType: "span"
   }, {
     key: "name",
     label: "Name",
     colType: "button"
   }, {
     key: "uhh",
     label: "uhh..",
     colType: "idk"
   }],
   items: [{
   	id: 0,
    name: "Test 0"
   }, {
   	id: 1,
    name: "Test 1"
   }, {
   	id: 2,
    name: "Test 2"
   }]
	}
});
<div id="app">
  <b-table :items="items" :fields="fields">
    <template v-for="(field, index) in fields" :slot="field.key" slot-scope="data">
      <div v-if="field.colType === 'button'">
        <h5>{{data.item.name}}</h5>
        <b-button>Am Button</b-button>
      </div>
      <div v-else-if="field.colType === 'span'">
        <h5>{{data.item.name}}</h5>
        <span>Am Span</span>
      </div>
      <div v-else>
        <h5>{{data.item.name}}</h5>
        Am Confused
      </div>
    </template>
  </b-table>
</div>

Solution 2

If you're using version 2.0.0 or newer of bootstrap-vue you need to change the slot names as they've changed, and the old vue slot has also been deprecated in favor for v-slot.

I changed the accepted answers fiddle to work with the new naming and v-slot

new Vue({
  el: "#app",
  data: {
    fields: [{
      key: "id",
      label: "Id",
      colType: "span"
    }, {
      key: "name",
      label: "Name",
      colType: "button"
    }, {
      key: "uhh",
      label: "uhh..",
      colType: "idk"
    }],
    items: [{
      id: 0,
      name: "Test 0"
    }, {
      id: 1,
      name: "Test 1"
    }, {
      id: 2,
      name: "Test 2"
    }]
  }
});
<link href="https://unpkg.com/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://unpkg.com/[email protected]/dist/bootstrap-vue.css" rel="stylesheet" />

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<script src="https://unpkg.com/[email protected]/dist/bootstrap-vue.js"></script>


<div id="app">
  <b-table :items="items" :fields="fields">
    <template v-for="(field, index) in fields" v-slot:[`cell(${field.key})`]="data">
      <div v-if="field.colType === 'button'">
        <h5>{{data.item.name}}</h5>
        <b-button>Am Button</b-button>
      </div>
      <div v-else-if="field.colType === 'span'">
        <h5>{{data.item.name}}</h5>
        <span>Am Span</span>
      </div>
      <div v-else>
        <h5>{{data.item.name}}</h5>
        Am Confused
      </div>
    </template>
  </b-table>
</div>
Share:
15,980
nebulousGirl
Author by

nebulousGirl

Updated on June 22, 2022

Comments

  • nebulousGirl
    nebulousGirl almost 2 years

    I am working with Bootstrap Vue JS table component to create a datatable: https://bootstrap-vue.js.org/docs/components/table

    I am new to VueJS and am uncertain on how to approach this problem which makes searching for a solution even more complicated.

    I use an API endpoint to return JSON data:

    {
       "options":{
          "filter":false
       },
       "fields":[
          {
             "key":"id",
             "label":"Id",
             "editLink":false,
             "display":true,
             "sortable":true,
             "class":"shrink"
          },
          {
             "key":"name",
             "label":"Name",
             "editLink":true,
             "display":true,
             "sortable":true
          }
       ],
       "data":[ ]
    }
    

    Here is my table template:

    <b-table striped hover bordered foot-clone class="table-sm"
       :items="users" :fields="displayedFields" :per-page="perPage" :current-page="currentPage" :filter="filter"
       @filtered="onFiltered"
       >
       <template v-for="(field, index) in fields">
          <template slot="{{field.key}}" slot-scope="row" v-if="field.editLink">
             <router-link :to="'/user/' + row.item.id" v-bind:key="index"></router-link>
          </template>
       </template>
       <template slot="status" slot-scope="row">
          <toggle-button :width="36" :height="18" v-model="row.status" :labels="false" :colors="{checked: '#00FF00', unchecked: '#FF0000', disabled: '#CCCCCC'}"/>
       </template>
    
    </b-table>
    

    The first template tag is an attempt from a wild guess. I want to be able to conditionally select a table for a column from the fields config. You can see in my attempt that I want to put a RouterLink when the field's config editLink is true.

    How can I get this done?

  • Radek Svítil
    Radek Svítil over 4 years
    Unfortunatelly, it seem this does not work - stopped working after some update? Only explicitly named fields are rendered.
  • Matty J
    Matty J over 4 years
    Working JSFiddle (bootstrap-vue.js set to version at time of this answer): jsfiddle.net/judh95fp/1