Utilizing separately generated elements from ngFor

I am currently working with an angular2 component that generates a list of chapters using an *ngFor= tag. However, I am facing an issue where I am unable to individually target these chapters in my ng2 component to highlight the selected chapter. I expected the code snippet below to produce something like this:

<p class="chapter 1" #1>1. My First Chapter</p>

But unfortunately, the #1 is not being generated as expected, resulting in my selector not functioning properly and preventing me from setting the first chapter in the list as selected by default.

import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core';

@Component({
  selector: 'tutorial',
  template: `
<div class="content row">
    <div class="chapters col s3">
        <h3>Chapters:</h3>
        <p *ngFor="let chapter of chapters" class="chapter" #{{chapter.number}}>{{chapter.number}}. {{chapter.title}}</p>
    </div>
</div>
`
})
export class bookComponent implements AfterViewInit {
    public chapters = _chapters;
    @ViewChild('2') el:ElementRef;

    ngAfterViewInit() {
      this.el.nativeElement.className += " clicked";
    }
 }

What steps should I take to be able to individually select the dynamically generated <p> tags?

Answer №1

If you are looking for a more angular approach to your use case, consider the following:

<p *ngFor="let chapter of chapters; let i=index" (click)="clickedItem = i" [class.clicked]="i == clickedItem" class="chapter" #{{chapter.number}}>{{chapter.number}}. {{chapter.title}}</p>
export class bookComponent implements AfterViewInit {
  public chapters = _chapters;
  clickedItem: number;
}

It is recommended to update the model and bind the view to ensure Angular accurately reflects the changes in the model without manually modifying the DOM.

Answer №2

To control the addition or removal of the clicked class, I recommend using NgFor loop:

<p *ngFor="let section of sections" class="section"
  [class.clicked]="section.id === activeSectionId">
  {{section.id}}. {{section.title}}
</p>

All you have to do is adjust the value of activeSectionId in your component logic.

export class novelComponent {
    public sections = _sections;
    private activeSectionId = 1;
}

Answer №3

Utilizing the directive with HostListener enables you to choose an element as depicted below.

See it in action : http://plnkr.co/edit/mtmCKg7kPgZoerqT0UIO?p=preview

import {Directive, Attribute,ElementRef,Renderer,Input,HostListener} from '@angular/core';

@Directive({
  selector: '[myAttr]'
})

export class myDir {
    constructor(private el:ElementRef,private rd: Renderer){
      console.log('fired');
      console.log(el.nativeElement); 
    }

    @HostListener('click', ['$event.target'])
    onClick(btn) {
      if(this.el.nativeElement.className=="selected"){
          this.el.nativeElement.className ="";  
      }else{
          this.el.nativeElement.className ="selected";
      }
   }
}

//our root app component
import {Component} from '@angular/core';

@Component({
  selector: 'my-app',
  directives:[myDir],
  template: 
  `
  <style>
    .selected{
      color:red;
      background:yellow;
    }
  </style>
    <div class="content row">
    <div class="chapters col s3">
        <h3>Chapters:</h3>
        <p myAttr *ngFor="let chapter of chapters" class="chapter" #{{chapter.number}}>{{chapter.number}}. {{chapter.title}}</p>
    </div>
</div>
  `
})
export class App {
  chapters=[{number:1,title:"chapter1"},{number:2,title:"chapter2"},{number:3,title:"chapter3"}]


}

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

Every time an action is carried out in the app, React generates countless TypeError messages

Whenever I'm using the application (particularly when started with npm start), my console gets flooded with thousands of TypeError messages like this: https://i.sstatic.net/3YZpV.png This issue doesn't occur when I build the app... It's fr ...

Tips for including a set width on Y-Axis labels

How can I set a fixed width for y-axis labels? Is there a way to do this? like shown here yAxis: { labels: { style: { width: '30px', fontSize: '10px', textOverflow: 'none' } } }, ...

Discover the method of sending individual row data to a component using *ngFor in Angular 4

I need assistance with Angular as I am not very experienced in it. Here is the HTML code that I have: <tbody> <tr *ngFor="let data of employeeFilterLists"> <td>{{data.Code}}</td> <td (clic ...

Angular 2's one-of-a-kind singleton solution

I'm feeling a bit lost when it comes to singleton services in Angular 2. I need a translation service that will be accessible throughout the entire application, and I want to ensure that only one instance of the service exists. My issue arises when tr ...

Converting a JavaScript function to work in TypeScript: a step-by-step guide

When writing it like this, using the this keyword is not possible. LoadDrawing(drawing_name) { this.glg.LoadWidgetFromURL(drawing_name, null, this.LoadCB,drawing_name); } LoadCB(drawing, drawing_name) { if (drawing == null) { return; ...

Issue encountered when running a minification build on Angular 5

After successfully updating my Single Page Application (SPA) from Angular 4 to Angular 5 along with all dependencies, everything seemed to be working well. Both the development and production builds were functioning without any errors or warnings. However ...

Tips for integrating the react-financial-charts library into your React and JavaScript project

While exploring the react-financial-charts library, I discovered that it is written in TypeScript (TS). Despite my lack of expertise in TypeScript, I am interested in using this library in my React+JS project due to its active contributions. However, I hav ...

Click to Rotate Angular Chevron

Is it possible to animate the rotation of a chevron icon from left-facing to right-facing using Angular? CSS: .rotate-chevron { transition: .1s linear; } HTML: <button [class.button-open]="!slideOpen" [class.button-close]="slideOpe ...

Storing JSON data retrieved from an API into a class property using the fetch function: a step-by-step guide

I am faced with the challenge of communicating with a localhost API that I have created in my React application class. This API is responsible for returning a list of JSON data, and my goal is to store this data in a property. Having limited knowledge abo ...

Error encountered when attempting to implement Material Angular 2 autocomplete functionality

I encountered an issue with Angular 2 while integrating autocomplete in material design. This is my first attempt at implementing it along with practicing backend ASP.net Core. Despite trying to install some ng2 libraries, I still couldn't get it to w ...

Acquiring information from a Service and saving it in a Child component - Angular version 11

Utilizing my service, I fetch API data for the child component. Initially, it retrieves the Id and other user data, displaying it in the console. ngOnInit(): void { this.commonService.userSetChange.subscribe( apiData => { this.getUserS ...

Express Server Providers for Angular 17's Server-Side Rendering

I attempted to share my request and response object with the Angular application by defining Providers in the "server.ts" file. However, when injecting them into app.component, they always appear undefined regardless of whether I am in the server or clie ...

Creating a TypeScript function that utilizes generics to automatically infer the return type

How can I create a function with a generic argument that can return any type, and have the return type inferred from its usage? I attempted the following code: type Thing<T> = <U>(value: T) => U const shouldMakeStrings: Thing<string> ...

Pull information from API and populate a dropdown menu in an Angular material select input

I am facing an issue with displaying data from an API in a mat select input field. I have tried to iterate over the data using a for loop but it is not working as expected. Can someone help me figure out how to properly populate the mat select input with d ...

Encountering a "Cannot POST" error in Angular upon redirection to a callback URL with a SAML response

Currently, I'm implementing SAML authentication in my angular application that will be hosted on AWS. The angular code is stored in a separate project from the webapi where Itfoxtec saml library is being utilized. The flow of communication between my ...

Never display mat-select panel when closed

In my current scenario, I am using the following template structure: <mat-select #select> <mat-option *ngFor="let option of optionsData"> {{ select.panelOpen ? option.viewValue : option.value }} </mat-option&g ...

Printing the default value set in the constructor using HTML

I'm encountering an issue while trying to set a default value from the constructor parameters and display it in HTML. The error message I'm receiving is: No suitable injection token for parameter 'name' of class 'AppComponent' ...

Mutations are not set up in the schema

Having an issue with setting up mutations in my project using npm, apollo server, and typeorm. Every time I attempt to create a mutation, I receive the error message "Schema is not configured for mutations". Searching for solutions has been fruitless as mo ...

What is the mechanism behind the widening of object literal types in Typescript inference?

I've been reading up on how typescript broadens inferred types but I'm still not entirely clear about what's happening here: type Def = { 'T': { status: 5, data: {r: 'm'}}, } function route<S extends keyof Def> ...

What could be the reason for encountering TypeScript within the Vue.js source code?

While exploring the vue.js source code, I stumbled upon some unfamiliar syntax that turned out to be TypeScript after further investigation. What baffled me was finding this TypeScript syntax within a ".js" file, when my understanding is that TypeScript ...