Display state in Bootstrap-vue Collapse with an arrow indicating visibility

I am currently using Bootstrap-vue and have implemented a simple collapse component to toggle the visibility of content. My goal now is to find a way to incorporate an arrow icon in the toggle button that can signify the state of the collapse: pointing down when the content is open, and pointing sideways when it is closed.

I came across a solution on Stack Overflow for Bootstrap 4, but I encountered challenges adapting it to Bootstrap-vue due to differences in the markup elements. With the given markup below, how can I go about adding the collapse state arrow?

<div>
  <b-btn v-b-toggle.collapse3 class="m-1">Toggle Collapse</b-btn>
  <b-collapse visible id="collapse3">
     <b-card> some content </b-card>
  </b-collapse>
</div>

Answer №1

After considering Riddhi's response, I came up with my final solution:

<b-btn block href="#" v-b-toggle.accordion1 variant="secondary">
   Time Period
     <span class="when-opened">
         <font-awesome-icon icon="chevron-down" />
     </span>
     <span class="when-closed">
         <font-awesome-icon icon="chevron-right" />
     </span>
</b-btn>

<b-collapse id="accordion1" role="tabpanel">
   <!-- some content -->
</b-collapse>

Furthermore, I applied additional CSS styling:

<style scoped>
...
    .collapsed > .when-opened,
    :not(.collapsed) > .when-closed {
        display: none;
    }

...
</style>

To complete the setup, I followed the instructions for installing and importing Font Awesome packages from this link and this link. In my main.js file, the import code looked like this:

import Vue from 'vue'
...
import { library } from '@fortawesome/fontawesome-svg-core'
import { faChevronRight, faChevronDown } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'

library.add(faChevronRight, faChevronDown);

Vue.component('font-awesome-icon', FontAwesomeIcon);
...

Answer №2

Sample HTML code:

     <b-btn v-b-toggle.myDropdown>
          <span class="when-opened">
<i class="fa fa-angle-down" aria-hidden="true"></i></span>
          <span class="when-closed">
    <i class="fa fa-angle-up" aria-hidden="true"></i></span>
          My Dropdown
        </b-btn>
        <b-dropdown id="myDropdown">
          <!-- dropdown content goes here -->
        </b-dropdown>

Demo Custom CSS:

.closed > .when-opened,
:not(.closed) > .when-closed {
  display: none;
}

By utilizing the provided CSS classes, you can replicate this behavior in your project.

Answer №3

When you want to customize the behavior of changing the status using the event this.$root.$on, take a look at this documentation:

Here's a simple example for you :)

Vue.use(BootstrapVue);
new Vue({
  el: '#app',
  data() {
      // collapsed holds the current status
      return { collapsed: false };
    },
    mounted() {
     // Triggered when collapse changes its state
     this.$root.$on(
      'bv::collapse::state',
       (id, collapsed) => {
        if (id === "my-collapse") {
          this.collapsed = collapsed;
        }
      });
    },
    computed: {
      btnVariant: function () {
        return this.collapsed?
          'danger' : 'info'
      },
      btnTxt:  function () {
        return this.collapsed?
           '🡇 Show ' : '🡅 Hide';
      }
    }
});
<link
 type="text/css"
 rel="stylesheet"  href="https://unpkg.com/bootstrap/dist/css/bootstrap.min.css"
/>
<link
  type="text/css"
  rel="stylesheet"
  href="https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.css"
/>

<!-- Required scripts -->
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.js"></script>


<div id="app">
  <b-button
    v-b-toggle:my-collapse
    :variant="btnVariant">
    {{ btnTxt }} - Collapse
  </b-button>
  <b-collapse id="my-collapse">
    Lorem ipsum dolor sit amet...
  </b-collapse>
</div>

Best of luck! :)

Answer №4

An even more seamless solution would be to simply utilize v-model instead of relying on CSS for determining the UI state.

<b-collapse v-model="openState" id="collapse3">
  <b-card> some content </b-card>
</b-collapse>

This change will result in:

<b-collapse v-model="openState" id="collapse3">
  <b-card> some content </b-card>
</b-collapse>

You can choose to initialize openState as true within the data section or define its value in the mounted or created lifecycle hooks, potentially based on a prop (as done in my case). As soon as the user begins interacting, the value will stay in sync with the UI state.

The arrow functionality can then be achieved using:

<span class="fa" :class="openState ? 'fa-chevron-down' : 'fa-chevron-up'"></span>

or

<font-awesome-icon :icon="openState ? 'chevron-down' : 'chevron-up'" />

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Implementing CSS counter-increment with jQuery

Is there a way to use jQuery to set the CSS counter-increment attribute on ".demo:before" even though jQuery cannot access pseudo elements directly? I recall seeing a suggestion on Stack Overflow about using a data attribute and then referencing that value ...

Error message indicating a duplicated navigation issue occurred following the receipt of an authorization code from Stripe

Upon receiving a response from Stripe after the client submits a form for a Standard account, I am encountering an issue where the authorization code is included: http://localhost:8080/authorize?state=s_987654321&code=ac_123456789. However, shortly af ...

Bootstrap dropdown feature automatically rearranges all items in my navigation bar

I recently set up a navbar for my website, but I'm struggling to grasp the concept of positioning items with Bootstrap. One issue I encountered is that when I click on the dropdown button (profile image), it causes all the items in my navbar to shift, ...

Display flex causing Mui LinearProgress Bar to disappear

Looking for a way to create a unique bullet graph using material UI? How about two MuiLinearProgress bars placed side by side with a vertical Divider in between them. Struggling to get them displayed next to each other? <div className={classes.bulletGra ...

Designing a horizontal slide banner with enhanced functionality

I am working on displaying a vertical banner that slides out horizontally from the right side of the screen when the user clicks on the open button/div, and also has the ability to close it. The basic design concept is illustrated in the sample image below ...

Modify current HTML code for 1027x768 displays

Looking for assistance with a webpage displayed at http://s2.ralfgroup.com. It appears correctly on screens with a resolution of 1280x1024, but extends beyond the screen on screens with a resolution of 1027x768. The issue seems to be related to the naviga ...

tips for arranging the body of a card deck

I have a card-deck setup that looks like this https://i.sstatic.net/vuzlX.png I am trying to arrange these boxes in such a way that the total width of the box equals the sum of the Amazon Cost width and the BOXI+ width: https://i.sstatic.net/3uNbe.png He ...

Steps to reverting CSS attributes back to their default values for a specified element (or blocking inheritance)

How can you reset a specific CSS attribute of an HTML element, which is automatically inheriting styles from its parent, to the default value? For example: CSS: .navigation input { padding: 0; margin: 0 30em; } HTML <div class="navigation"& ...

Ways to display a sorting icon depending on a calculated attribute

My goal is to display the appropriate sorting icon based on a computed value. For instance, if the column1 is clicked, one of two classes, classRefcodeDown or classRefcodeUp, should be true. Both computed properties invoke a method called sortClassRefcode, ...

Excessive content within div

Need help with fixing the height of a div using asp.net. Currently, I am hiding overflow content and looking for a solution. Here's my code snippet: <div id="Content" style="height: 90px !important; overflow: hidden; text-decoration: none; text-ov ...

I am attempting to create a captivating image for a "jumbotron"

My goal is to achieve a full-width image that stretches across the entire website. Furthermore, I want the image to remain centered and shrink from the sides as the window size decreases. Here's what I've attempted: HTML <div class="site-ban ...

Incorporate a bootstrap tooltip into the search functionality of a datatable

I've been attempting to implement a Bootstrap tooltip on the search box of a data table, but I haven't had any luck finding guidance on how to do so. Here's what I've attempted, unfortunately without success: $('.dataTables_filter ...

Steps to automatically redirect to the login page when a user is not authenticated in a Vue 3 frontend with Laravel as the backend

RoxanneSkywalker OP Posted 32 minutes ago Achievement Unlocked: Ten Thousand Strong Badge How can I implement a redirect to the login page when a user is not authenticated in Vue 3 with Laravel as the backend? Hey there, I am seeking guidance on how to re ...

Vue.js is throwing an error stating that a component template must have only one main element

I am currently troubleshooting an issue with file upload functionality, but I am unsure of the specific error. In an attempt to track changes, I have been using console logs. Upon running $ npm run watch, an error message is displayed: "Webpack is watchi ...

Make google maps InfoWindow wider than 700px

To display the InfoWindow content at a size of 840px x 660px, I need to adjust the MaxWidth property when creating the google.maps.InfoWindow object. (For example: new google.maps.InfoWindow({ content: some_text, maxWidth: 840});) However, despite settin ...

Transferring information between Rails views and Vue.js

Having some trouble passing an instance variable from my Rails view to a Vue.js component. The error message displaying is: Property or method "epic_list" is not defined on the instance but referenced during render. Let's take a look at the code: V ...

Obtaining the CSS class assigned to a specific WebElement

Is it possible to retrieve the CSS class that has been assigned to the selected WebElement? While the getCssValue method is available, it only returns the value of a specific attribute and not the actual class applied to the WebElement. ...

A step-by-step guide to building an API page with Python

Hello everyone! I am just starting out with Vue.js and Python, and I have a question for you. My task is to create a basic webpage using Vue.js on the front end and Python on the backend, with Heidi SQL as my database. My team has requested that I create ...

Tips for adjusting the color of a linear gradient in a shimmer effect

I have a puzzling question that I just can't seem to solve. My goal is to display a shimmer effect on cards as a temporary placeholder until the actual content loads. I found some CSS code in this answer, but when I tried it with a dark background, t ...

Unusual occurrences when using absolute positioning, style.top, style.left, and the HTML "a" tag

Struggling to complete a task on Javascript.info involving an "a" tag. The objective is simple - place (and remove) a tooltip above the element upon hover. No issues with positioning over the roof or house, but as soon as I try to place the box a ...