Tips for incorporating drop-down arrow states into a Bootstrap 4 accordion with Angular or CSS

Is there a simple way to implement an arrow (>) to show the

aria-expanded="true" or aria-expanded="false"
states in the Bootstrap 4 accordion using either Angular2 or plain CSS?

I have gone through several tutorials and attempted numerous methods, but it seems like I am missing something.

I've experimented with just CSS, but the arrow doesn't appear (although this approach might be correct):

.card .card-header:after{
    float: right;
    border: 2px solid #f07f09;
    border-width: 0 3px 3px 0;
    padding: 6px;
    margin-right: 10px;
}

I also tried using ngClass, but my problem is that it applies the arrow state to all elements with the code below (is there a way to incorporate the index for this to work?):

<i [ngClass]="{'right':!expanded, 'down':expanded}"></i>

and the function setting the state:

(click)="changeDropdownArrowState()"

Function in my component:

  changeDropdownArrowState () {
    this.expanded = !this.expanded;
  }

My HTML:

<div class="card">
    <div class="card-header" id="headingOne">
        <h2 class="mb-0">
            <button class="btn btn-link btn-block text-left" type="button" data-toggle="collapse"
                data-target="#collapseOne" aria-expanded="false" aria-controls="collapseOne" (click)="changeDropdownArrowState()">
                <h1>Personal Details
                    <i [ngClass]="{'right':!expanded, 'down':expanded}"></i>
                </h1>
            </button>
        </h2>

    </div>

    <div id="collapseOne" class="collapse" aria-labelledby="headingOne" data-parent="#retailCliamAccordian">
        <div class="card-body">
            some text
        </div>
    </div>
</div>
<div class="card">
    <div class="card-header" id="headingTwo">
        <h2 class="mb-0">
            <button class="btn btn-link btn-block text-left collapsed" type="button" data-toggle="collapse"
                data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo" (click)="changeDropdownArrowState()">
                <h1>Product Details
                    <i [ngClass]="{'right':!expanded, 'down':expanded}"></i>
                </h1>
            </button>
        </h2>
    </div>
    <div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#retailCliamAccordian">
        <div class="card-body">
            other text
        </div>
    </div>
</div>

My CSS:

i {
    float: right;
    border: 2px solid #f07f09;
    border-width: 0 3px 3px 0;
    padding: 6px;
    margin-right: 10px;
}

.right {
    transform: rotate(-45deg);
}

.down {
    transform: rotate(45deg);
}

https://i.sstatic.net/CrDF8.png

Another possible solution could involve utilizing the aria-expanded="true/false" attribute.

Answer №1

If you'd like a simple solution, you can define an array of true/false values in your .ts file as follows:

expandableAreasState = [true, false, false, ...] // the first item will be expanded by default in this example

You can then modify the method like so:

  changeDropdownArrowState(index: number) {
    this.expandableAreasState[index] = !this.expandableAreasState[index];
  }

When calling inside the template, use it like this:

<button class="btn btn-link btn-block text-left collapsed" type="button" data-toggle="collapse"
            data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo" (click)="changeDropdownArrowState(0)"> // use 1 instead of 0 for the next one and so on...
     <h1>Product Details
          <i [ngClass]="{'right':!expandableAreasState[0], 'down':expandableAreasState[0]}"></i>
     </h1>
</button>

Alternatively, you might find ng-bootstrap to be a better fit for your needs as it simplifies bootstrap implementation without jQuery dependencies.

If your cards are similar and not too complex, consider creating an interface:

CardConfig {
  title: string;
  text: string;
  ...
}

Define an array of these card settings in a util or config file:

export const cardConfiguration: CardConfig[] = [{title: ''Personal details, text: 'some text', ...}]

Import this configuration in your component.ts file:

cardConfig = cardConfiguration

Then, utilize *ngFor to loop over them in the template.

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

Requests from a Heroku Angular frontend to a Heroku Spring Boot backend result in a 403 error code being returned

I successfully deployed a basic CRUD Springboot backend on Heroku. When I deploy the frontend to my local environment, the REST calls work without any issues. Using curl from either my local machine or the Heroku frontend bash also results in successful ...

Activate a function in components upon the refresh of a service value (Angular 6)

Currently, I am in the process of developing an app with a specific structure in mind: https://i.sstatic.net/6d5Uq.png The functionality includes clicking on an item in MenuComponent, which then triggers the transmission of an object to the dashboard-com ...

conditional operator that compares values in router events

As I examine an object, links = { link1: 'page1', link2: 'page2', link3: 'page3', link4: 'page4', link5: 'page5', link6: 'page6' } I possess a function for retrieving t ...

What is the correct method for caching fonts within an Angular application?

In the process of developing a web application similar to photoshop-minis using Angular, one key aspect I am focusing on is reducing load times. Particularly when it comes to fonts, as not all necessary fonts are available through Google Fonts. Instead of ...

I tried to import Bootstrap into my project, but it seems to be malfunctioning

Is there a way to display cards in a slider format? I want the carousel to show the next card on each click. I tried importing Bootstrap into my project but it doesn't seem to be functioning as expected. Here's the link to the tutorial I am usi ...

Guide to inserting a glyphicon within a bootstrap badge

I've been working on a unique way to display hierarchical data using bootstrap badges and AngularJS. My goal is to create a user-friendly experience where people can easily navigate through categories. There are 3 main types of categories: parent: T ...

Load all HTML content from external files using a Bootstrap modal

Using Bootstrap 4.1.3 I have a specific requirement that is different from the solution provided here: Bootstrap Modal Dynamic Content The scenario involves fetching the complete modal HTML content from an external file and then presenting it as a modal. ...

Using JavaScript to create CSS animations triggered on hover

Looking for a CSS Animation that will play forward once when the mouse enters a specific div, and then play in reverse when the mouse leaves. Check out my JsFiddle here. The div with the class ".item" should trigger the mouse enter event. The animation co ...

having trouble generating a vertical advertisement banner on wordpress

Hey there, I'm attempting to place a vertical banner ad created with HTML/CSS inside a textarea in the WordPress widget section. I added a textarea to the side column, inserted the HTML with corresponding CSS styles into the stylesheet. However, the s ...

Launch a modal from a separate webpage

I've been trying to implement a modal using Bootstrap 4, and after referring to the documentation, it seems to be working smoothly. <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/> <scri ...

Is there a way to modify the Firebase DB without relying on push keys?

After reading a tutorial, I learned about using push keys to generate unique push ids. However, I prefer using my own unique key for set or update instead of relying on push keys. Am I missing something here? Your input would be greatly appreciated. Than ...

Adjusting the height of a CSS div to be 0 while also modifying the

I have encountered a unique dilemma <div class="parent"> <p>stuff stuff stuff</p> </div> Using CSS, I set the width and height of parent = 0; because I intend to modify it when a button is clicked. However, for this purpose, I ...

Guide to building interactive dropdown menus in Angular 8

In my user interface, each row contains three dropdowns for level 1, level 2, and level 3, as well as an "Add Level" button. When the "Add Level" button is clicked, a new set of three dropdowns for level 1, level 2, and level 3 should be added dynamically ...

Using an array to enforce form validation rules in Angular, including prohibited form values

I am currently developing a basic Angular form with specific validation requirements: The input must not be left empty The input cannot match any of the values stored in the array forbiddenValues. While I understand how to implement the required validat ...

Navigation bar links refusing to decrease in size

I am encountering an issue with the navigation bar on my website. When I reduce the size of the browser tab, the text remains the same size while the logo shrinks and eventually disappears. How can I ensure that everything scales down proportionally? Pleas ...

Retrieve the text content of the paragraph element when its parent is clicked. The paragraph element belongs to a group that contains many

In a function I'm working on, I need to retrieve the specific text within a p element when its parent (.photoBackground) is clicked. The purpose of this operation is to grab the caption for a gallery, where there are multiple p elements with the same ...

"Utilize Ionic to subscribe the back button and close an internal div with ease

I have a div called "Search Filters" that appears when the condition this.show_filters == true is met. I am now attempting to use the Android back button to change this variable to false. async toggleFiltersWindow(){ console.log('#1 toggleFilters( ...

Angular toolbar permanently positioned at the top of the screen

My custom toolbar, along with other components, is present in the app I'm working on. In the app.component, the structure looks something like this: <app-toolbar> </app-toolbar> <main> <a [routerLink]="['/login/en&a ...

Adding an additional border when combining two divs with rounded borders

I attempted to create a design similar to the Instagram "ask me a question" box, but I am encountering an issue where there is some extra border around the title when the two divs merge. What am I doing incorrectly? .info { overflow: hidden; ...

How to incorporate a <select> field in Django templates with personalized Bootstrap designs

Currently facing a challenge in connecting my front-end html, css, and javascript with the django backend. The html templates are functioning perfectly as designed, displaying data flawlessly when calling a django field within the current view like so: &l ...