Home > other >  How to programmatically change tabs using IBM Carbon Design System with Vue
How to programmatically change tabs using IBM Carbon Design System with Vue

Time:09-13

I need help programmatically changing Carbon/vue tabs. In the 1st tab (0), I want to be able click a button and bring the user to the 4th tab (3). In the template section I have the following:

<cv-tabs selected="1" aria-label="Tab navigation" ref="tabs" id="nav-tab">
    <cv-tab label="GETTING STARTED">
        ...
        <cv-button @click="changeTab">Go to JRS Navigator</cv-button>
    </cv-tab>
    <cv-tab label="TAXONOMY BASICS">
        ...
    </cv-tab>
    <cv-tab label="MANAGER GUIDANCE">
        ...
    </cv-tab>
    <cv-tab label="JRS NAVIGATOR">
        ... where I want the button to take me ...
    </cv-tab>
</cv-tabs>

In the methods section, I define changeTab(). This pulls the cv-tabs VueComponent based on the ref="tabs", setting selected(3) does NOT switch the tabs, it only changes the selected tab to be the 4th tab (3) JRS NAVIGATOR (I.e., 4th tab has the blue bar under it), but the tab’s content is still the first tab (GETTING STARTED).

methods: {
    changeTab(){
        this.$refs.tabs.selected(3)
    },
    ...
}

Any ideas?

CodePudding user response:

Using functions of the ref element is directly manipulating the DOM. This is not a guaranteed safe way to interact with Vue components which may have some logic for tracking internal state that controls how they should be rendered. You'll have to go about it in a more Vue-like way.

As seen in the docs (which are, admittedly, not great), CvTab has a selected prop. This prop when set to true will set that tab as the active tab... but changing it manually will not automatically set other tabs to false. You will need to manage an array of true/false values that bind to each of these tab's selected props which will then allow you to change them manually using a method that takes as an input the tab value you want to change to. There is also a tab-selected event that is emitted any time a new tab is selected which must also be used to enure the array values stay correct when clicking the tabs.

<cv-tabs @tab-selected="actionSelected">
    <cv-tab id="tab-1" label="Tab link 1" :selected="tabs[0]">
        Sample tab panel content 1
        <cv-button @click="changeTab(3)">Go to tab 4</cv-button>
    </cv-tab>
    <cv-tab id="tab-2" label="Tab link 2" :selected="tabs[1]">
        Sample tab panel content 2
    </cv-tab>
    ...
data() {
    return {
      tabs: [true, false, false, ...],
    };
},
methods: {
    actionSelected(tabNumber) {
      this.tabs.forEach((t, index) => {
        if (index === tabNumber) {
          this.$set(this.tabs, index, true);
        } else {
          this.$set(this.tabs, index, false);
        }
      });
    },
    changeTab(tabNumber) {
      this.$set(this.tabs, tabNumber, true);
    },
},

Here is also a codesandbox demonstrating the above code

Would've been a lot simpler if Carbon devs had supplied a v-model on CvTabs to keep track of and change the active tab, but unfortunately this more complicated way is the only way I can think of to do what you want.

  • Related