Toggle sidebar from Vue method?

Viewed 8427

In a <b-table> I would like to create an action on each items so I have a button:

<b-table :items="data" :fields="fields">
  <template v-slot:cell(actions)="data">
    <b-button v-on:click="doIt(data.index)">Do It</b-button>
  </template>
</b-table>

Then I have a Form in a sidebar

<b-sidebar id="do-it-form" title="Do it" right>
...
</b-sidebar>

In my methods I would like to respond to the action:

methods: {
    doIt(id) {
        sidebar.form.id = id
        sidebar.show().onSubmit(() => {
           axio...
           refresh(<b-table>)
        })
    }
}

Of course, this last part is not valid. On Bootstrap Vue manual I didn't find how to interact from Vue to Bootstrap components. Any clue?

3 Answers

You can emit an event on $root, which can be used to toggle the sidebar. The second parameter being the id of the sidebar you wish to open. this.$root.$emit('bv::toggle::collapse', 'my-sidebar-id')

<b-collapse> and <b-sidebar> listens for the same event, which is why it says collapse in the event.

new Vue({
  el: '#app',
  methods: {
    openSidebar() {
      this.$root.$emit('bv::toggle::collapse', 'my-sidebar')
    }
  }
})
<link href="https://unpkg.com/bootstrap@4.5.2/dist/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://unpkg.com/bootstrap-vue@2.17.1/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/bootstrap-vue@2.17.1/dist/bootstrap-vue.js"></script>

<div id="app">
  <b-sidebar id="my-sidebar" right>
    My sidebar
  </b-sidebar>

  <b-btn @click="openSidebar">
    Open sidebar
  </b-btn>
</div>

Alternatively you can bind a boolean property to the v-model on the sidebar and set the boolean to true when you want to open the sidebar.

new Vue({
  el: '#app',
  data() {
    return {
      isSidebarOpen: false
    }
  },
  methods: {
    openSidebar() {
      this.isSidebarOpen = true
    }
  }
})
<link href="https://unpkg.com/bootstrap@4.5.2/dist/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://unpkg.com/bootstrap-vue@2.17.1/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/bootstrap-vue@2.17.1/dist/bootstrap-vue.js"></script>

<div id="app">
  <b-sidebar v-model="isSidebarOpen" right>
    My sidebar
  </b-sidebar>

  <b-btn @click="openSidebar">
    Open sidebar
  </b-btn>
</div>

Also, you can use one of the sidebar built-in public methods show, hide or toggle. All you need is add a reference to your sidebar

<b-sidebar ref="mySidebar" id="do-it-form">
...
</b-sidebar>

and then in any of your methods where/when it's needed, you can simply call any of them

this.$refs.mysidebar.show();
this.$refs.mysidebar.hide();
this.$refs.mysidebar.toggle();

You can also just assign a boolean value to the visible prop on the b-sidebar component and toggle the boolean value as you like.

<b-sidebar ref="mySidebar" id="do-it-form" :visible="showSidebar">
...
</b-sidebar>

And toggling it:

data: {
   showSidebar: false, //starts off invisible
},
methods: {
   toggleSidebar(){
      this.showSidebar = !this.showSidebar
   }
}

This approach at first glance is not the best in an approach where you have other components updating the sidebar visiblity. This use case is for situations when all updates to the sidebar visibility are made from a central store by using a central boolean value.

e.g.

const state = {
  showSidebar: null
}

const mutations: {
  toggleSidebar(state, payload){
     if (payload) { //payload incase you want to force a value and not just toggle
            state.showSidebar = payload;
     } else {
            state.showSidebar = !state.showSidebar;
     }
  }
}

And in your components:

computed: {
   showSidebar(){
     return this.$store.state.showSidebar
   }, //starts off invisible
},
methods: {
   toggleSidebar(){
      this.$store.commit("toggleSidebar");
   }
}

Your updated sidebar component would look like this:

<b-sidebar ref="mySidebar" id="do-it-form" :visible="showSidebar" @change="updateSidebar">
...
</b-sidebar>

And the method:

methods: {
   updateSidebar(value){
      this.$store.commit("toggleSidebar", value);
   }
}
Related