Search code examples
vue.jsbootstrap-vue

how to control bootstrapvue b-table trClass by boolean


I am using a b-table from BootstrapVue. However Each row have a button and when i click the button i want to change the row background to another color, i find tbody-tr-class can control but that can not allow the button control

The Changes and noChange is scss name

<b-table :sticky-header="true"
             responsive
             :fields="fields" :items="items" :no-border-collapse="true"
    :tbody-tr-class = "this.changeColor!=false ? 'Changes' : 'noChange'"
    >
      <!--      ref="selectable"-->
      <!--      select-mode="single"-->
      <!--      selectable-->
      <template v-slot:cell(\r)="row">
        <b-dropdown toggle-class="dropdown" size="lg" variant="link" text="..." no-caret>
          <b-dropdown-item @click="onClickButton1(row.item)">buttonName</b-dropdown-item>
        </b-dropdown>
      </template>
    </b-table>
  

methods

data(){
    return{
       changeColor:false;
    }
}
methods:{
    onClickButton1(item){
        this.changeColor = true;
        console.log(item)
    }
}

Solution

  • Since you want the color to change on a row to row basis. You can pass a method to the tbody-tr-class prop. This method will be evaluated per row, and also receives the item for the row as an argument.

    This means you can set a boolean flag on your item (hasChanged in the example), which will control whether that row should have a different color or not.

    What you return from the function, will be added to that rows classes. In the example i use the class object syntax, but you can also return a string or an array containing the classes.

    I'm using $set to add the hasChanged property to our item, to ensure that it's reactive. Why that's needed is described here.

    new Vue({
      el: '#app',
      data() {
        return {
          fields: ['first_name', 'last_name', 'actions'],
          items: [{
              first_name: 'Dickerson',
              last_name: 'Macdonald'
            },
            {
              first_name: 'Larsen',
              last_name: 'Shaw'
            },
            {
              first_name: 'Geneva',
              last_name: 'Wilson'
            },
            {
              first_name: 'Jami',
              last_name: 'Carney'
            }
          ]
        }
      },
      methods: {
        toggleColor(item) {
          this.$set(item, 'hasChanged', !item['hasChanged'])
        },
        getTrClass(item) {
          return {
            changes: item['hasChanged']
          }
        }
      }
    })
    .changes {
      background-color: red;
    }
    <link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap@4.5.3/dist/css/bootstrap.min.css" />
    
    <script src="//unpkg.com/vue@2.6.12/dist/vue.min.js"></script>
    <script src="//unpkg.com/bootstrap-vue@2.21.2/dist/bootstrap-vue.min.js"></script>
    
    <div id="app">
      <b-table :fields="fields" :items="items" :tbody-tr-class="getTrClass">
        <template #cell(actions)="{ item }">
          <b-btn @click="toggleColor(item)">Toggle Color</b-btn>
        </template>
      </b-table>
    </div>