2

I have a list like below:

<a href=xx class="origin">text1</a>
<a href=xx class="origin">text2</a>
<a href=xx class="origin">text3</a>
<a href=xx class="origin">text4</a>
<a href=xx class="origin">text5</a>

What I want is when clicking any of the link, the class name will automatically change to "clicked", when click again, it will change back to "origin".

Something in my mind like this:

<a href=xx class="origin" 
onclick="this.class=this.class=='origin"?'clicked':'origin'>text</a>

How do I implement this with Angular 4?

1
  • 1
    can multiple anchor elements have the clicked class at the same time? Commented Aug 1, 2018 at 16:04

4 Answers 4

2

There's a few ways you can do this, some uglier than others.

You can assign each a tag its own unique boolean, toggle its boolean on click and have its class depend on its boolean value.

<a href=xx class="origin" (click)="a = !a" [ngClass]="{'origin': !a, 'clicked': a}">text1</a>
<a href=xx class="origin" (click)="b = !b" [ngClass]="{'origin': !b, 'clicked': b}">text2</a>
<a href=xx class="origin" (click)="c = !c" [ngClass]="{'origin': !c, 'clicked': c}">text3</a>
<a href=xx class="origin" (click)="d = !d" [ngClass]="{'origin': !d, 'clicked': d}">text4</a>
<a href=xx class="origin" (click)="e = !e" [ngClass]="{'origin': !e, 'clicked': e}">text5</a>

Or, if you don't want to create multiple unique booleans, you can instead get a reference to the clicked a tag with $event.target and check its class the vanilla Javascript way with className.

Inline way:

<a href=xx class="origin" (click)="$event.target.className = ($event.target.className === 'origin') ? 'clicked' : 'origin'">text1</a>

Function way:

<a href=xx class="origin" (click)="toggleClass($event.target)">text1</a>
toggleClass(el) {
  el.className = (el.className === 'origin') ? 'clicked' : 'origin';
}
Sign up to request clarification or add additional context in comments.

Comments

1

I would do it like the following:

HTML:

<a 
  *ngFor="let link of LINKS"
  [attr.href]="link.href"
  [ngClass]="{'origin': !link.isClicked, 'clicked': !link.isClicked}"
  (click)="toggleClass(link)"
>
  {{link.text}}
</a>

TS:

class Link {
  href: string;
  text: string;
  isClicked: boolean;
}

export class ExampleComponent {
  public readonly LINKS: Link[] = [
    {href: 'xxx', text: 'text1', isClicked: false},
    {href: 'xxx', text: 'text2', isClicked: false},
    {href: 'xxx', text: 'text3', isClicked: false},
    {href: 'xxx', text: 'text4', isClicked: false},
    {href: 'xxx', text: 'text5', isClicked: false},
  ];

  public toggleClass(link: Link): void {
    link.isClicked = !link.isClicked;
  }
}

Comments

0

Although all of above answers are correct, but for maintainability I would suggest to create a directive to handle it for you

<a toggler class="origin">text1</a>
<a toggler class="origin">text2</a>
<a toggler >text3</a>
<a toggler >text4</a>
<a toggler class="origin">text5</a>

toggler.directive.ts

import { Directive, HostListener, Renderer2, ElementRef } from '@angular/core';

@Directive({
  selector: '[toggler]'
})
export class TogglerDirective {

  constructor(private renderer: Renderer2,
               private elementRef: ElementRef) { }

  @HostListener('click', ['$event']) onClick($event){
    if (!$event.target.className.includes('clicked')) {
      this.removeClass('origin', $event.target);
      this.addClass('clicked', $event.target);
    } else {
      this.removeClass('clicked', $event.target);
      this.addClass('origin', $event.target);
    }
  }  

  addClass(className: string, element: any) {
       this.renderer.addClass(element, className);
   }

   removeClass(className: string, element: any) {
       this.renderer.removeClass(element, className);
   }
}

see working example in this stackblitz (don't forget to add TogglerDirective to app.module)

even you don't need to set initial class of 'origin' on links

Comments

-1

You can achieve using ngClass binding property.

<a href=xx (click)=handleClick() [ngClass]="{'origin' : !isclicked, 'clicked' : isclicked }">text1</a>

Inside component:

function handleClick(){
    this.clicked = !this.isclicked;
}

1 Comment

this works only when there is one anchor element, which is not the case presented by Op

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.