To collapse a div in an HTML Angular environment, the button must be clicked twice

A series of divs in my code are currently grouped together with expand and collapse functionality. It works well, except for the fact that I have to click a button twice in order to open another div. Initially, the first click only collapses the first div.

<div *ngFor="let item of data; let i = index">
      <button
        (click)="setIndex(i)"
      >
        <span
          [translate]=“item.title”
        ></span>

      </button>
      <div
        [class.collapse]='currentIndex !== i'
      >
        <div [innerHTML]=“item.description | translate"
        ></div>
      </div>
      <hr>

    </div>

In addition, the typescript function in question is as follows:

setIndex(i) {
    this.currentIndex = this.currentIndex === -1 ? i : -1;
  }

I attempted changing the click event to mousedown or keydown, but unfortunately, it did not yield the desired outcome.

Answer №1

To enhance the functionality of your setIndex function, modify it as shown below:

setIndex(i) {
   this.currentIndex = this.currentIndex === i ? -1 : i;
}

It is crucial to update the currentIndex value with the newly clicked index i in order to ensure that the corresponding div is displayed properly.

If the current div is already visible and you click on it again (meaning currentIndex === i), simply set it back to -1 to collapse it.

Answer №2

Revise your setIndex() as shown below.

Explanation

We initially set currentIndex = -1.

When a user clicks on any button, we need to check if currentIndex is -1 and then assign the value of i to currentIndex.

Now there are 2 more scenarios to consider. If a user keeps clicking on the same button repeatedly, we have to verify i === currentIndex

The last scenario is that when the first div is open with currentIndex = 0, and subsequently, if a user clicks on the third button leading to index = 2, we must first assign

currentIndex = -1 and then currentIndex = i

html

<div *ngFor="let item of data1; let i = index">
      <button (click)="setIndex(i)">
        <span>{{item.title}}</span>
      </button>
      <div [hidden]='currentIndex !== i'>
        <div>{{item.description}}</div>
    </div>
    <hr>
</div>

ts

setIndex(i) {
    if (this.currentIndex === -1) {
        this.currentIndex = i;
    } else if (this.currentIndex === i) {
        this.currentIndex = i;
    } else {
        this.currentIndex = -1;
        this.currentIndex = i;
    }
}

Note:

I have used [hidden] here just for demonstration purposes. You can customize it as needed.

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

Getting a variable from outside of the observable in Angular - a step-by-step guide

I have an Observable containing an array that I need to extract so I can combine it with another array. this.builderService.getCommercialData() .subscribe( data=>{ this.commercialDetails = data; this.commercialDetailsArr ...

Expanding a class functionality by incorporating a method through .prototype

My goal is to define a class called "User" and then add a method to the class using the "prototype" keyword. I want the method "who_auto" to be accessible to all future instances of "User". When testing this code in JSFiddle, I encountered the error messa ...

Exploring Laravel 4: Controlling AJAX data manipulation via the controller

I am a beginner in using Laravel and ajax. Currently, I am working on retrieving data from a form through ajax and calling a controller method using ajax as well. The controller method searches the database and returns a json response to be handled by ajax ...

Using Vue.js, perform calculations on various fields within an array of objects generated by the v-for directive

I am currently learning Vue.js and I have implemented a v-for loop to iterate through an array of objects. However, I now need to calculate a specific field (precoPorKg) within this loop. In order to perform this calculation, the input item.quantidade mus ...

Refreshing rows in ngx-datatable

Just started using ngx-datatable (version 11) with Angular-5 and encountered an issue. When loading rows during ngInit, everything works fine. However, when lazy-loading due to a user search request, the table shows the correct total number of rows but onl ...

Extract data from dynamically loaded tables using PhantomJS and Selenium Webdriver

I've been informed by everyone that I should be able to retrieve the table content using PhantomJS when working with JavaScript. However, despite my attempts, I have not been successful. My expectation was to obtain the table from the website Page 1 ...

Executing animation after the completion of a transition

Is there a way to synchronize the bounce animation with the scaling of an object, so that it appears smooth and fluid? I've tried using the animation delay property along with the transition delay property, but they don't seem to align correctly. ...

Is it possible to utilize CSS rules for a non-existent div within CSS?

Can this be achieved using CSS? If .div1 is not present, enforce the following rule: .div2{ property: value; } For example, <div class="div1"> ... </div> <div class="div2"> <!-- it exists, so no action needed --> </div& ...

Using Ajax.Updater to run JavaScript code

I've tried numerous online tutorials and examples, but haven't had much success... I'm looking to execute JavaScript from an HTML Response in Ajax. Here's my code snippet: <script src="prototype.js" type="text/javascript"></ ...

What is the best way to guide the user to a different page with PHP once the preventDefault() function in jQuery has been utilized on a

My approach to form validation involves using jQuery, AJAX, and PHP on my website. I utilize PHP for the actual input validation process as I believe it is more secure and prevents users from manipulating scripts through browser source code inspection. Add ...

Tips for transforming a React sign in component into an already existing Material UI sign in component

I am looking to revamp my current sign-in page by transitioning it into a material UI style login page. Displayed below is the code for my existing sign-in component named "Navbar.js". This file handles state management and includes an axios call to an SQ ...

Utilizing node-json2html, generate individual HTML tables for each record

I need assistance in consolidating my JSON data into a single HTML table, instead of generating separate tables for each record through my current transformation process. var data=[{"name":"aa","mid":"12345","user":"a123","password":"a@123"},{"name":"bb" ...

Tips for combining Bootstrap 5's .is-invalid class with Angular's ng-invalid attribute

Bootstrap 5 provides a convenient way to indicate invalid input fields using the .is-invalid class. While working with a reactive form, I noticed that the "ng-invalid" style is applied when an input field is considered "invalid". I am curious if there is ...

Update the headers of the axios.create instance that is exported by Axios

I have a single api.js file that exports an instance of axios.create() by default: import axios from 'axios' import Cookies from 'js-cookie' const api = axios.create({ baseURL: process.env.VUE_APP_API_URL, timeout: 10000, headers ...

`The Conundrum of Basic HTML Parsing`

Hello, I am currently working on extracting professor names and comments from the ratemyprofessor website by converting each div into plaintext. The following is the structure of the div classes that I am dealing with: <div id="ratingTable"> <div ...

Encountering a problem with Firebase while offline. The error message "FirebaseError: Firebase App named '[DEFAULT]' already exists with different options or config." is appearing

I've been having some trouble integrating Firebase into my app using the useFireBaseAuth hook. Everything works smoothly when there's an active internet connection, but I'm facing issues when offline. An error message shows up: Server Error ...

Is it possible to use the `fill` method to assign a value of type 'number' to a variable of type 'never'?

interface Itype { type: number; name?: string; } function makeEqualArrays(arr1: Itype[], arr2: Itype[]): void { arr2 = arr2.concat([].fill({ type: 2 }, len1 - len2)); } What is the reason for not being able to fill an array with an ob ...

Implement a validation function in the "jQuery validation library."

Hello, I am currently using the jQuery validation plugin to validate my form. I am trying to add an additional rule to the validation, but I am struggling to get it to work. The input value should be less than or equal to the previous element's value. ...

Issue with fullPage.js - Unable to scroll to footer on the last section of the page

I'm currently working with the fullPage.js plugin () and encountering some issues. While sliding through each section, everything functions as expected. However, when I reach the last section and try to scroll down to the footer below it, I encounter ...

Utilize the fitBounds feature from GoogleMaps in Vuejs for seamless integration

I've been working on getting the map boundaries to work properly, using a method in conjunction with my existing initMap and askGeolocation methods. Despite my best efforts, I can't seem to get the bounds functionality working so that the map zo ...