17

I have a list and the plugin (dragula) I used, adds certain CSS class on certain action. I am using Angular 5. I want to find out the presence of certain class (myClass) and remove that and replace with (yourClass). In jQuery we can do that like this

$( "p" ).removeClass( "myClass" ).addClass( "yourClass" );

How can I achieve this in Angular5. Here the main issue is that myClass is added automatically to the selected li by the plugin. So using a function I cant set the class.

When I tried with renderer2, it is removing the CSS class and adding another class. But it is adding only to the first li. My code is:

let myTag ; 
myTag = this.el.nativeElement.querySelector("li");
this.renderer.addClass(myTag, 'gu-mirrorss')
this.renderer.removeClass(myTag, 'dragbox');
<div  class="right-height" id ='dest' [dragula]='"second-bag"' [dragulaModel]="questions"> 
       {{ questions.length == 0 ? ' Drag and drop questions here ' : ' '}}
       <li #vc  data-toggle="tooltip" data-placement="bottom" title= {{question.questionSentence}} class="well dragbox"  *ngFor="let question of questions; let i = index" [attr.data-id]="question.questionId" [attr.data-index]="i" (click)="addThisQuestionToArray(question,i, $event)" [class.active]="isQuestionSelected(question)"  #myId > {{question.questionId}} {{question.questionSentence}}</li>
</div>
Roy
  • 7,811
  • 4
  • 24
  • 47
Senchu Thomas
  • 518
  • 3
  • 9
  • 24
  • 3
    In "Angular way" you use [ngClass]="{'class1':condition1,'class2':condition2}" – Eliseo Feb 22 '18 at 10:46
  • Do you want to add/remove from typescript? – Sandip - Frontend Developer Feb 22 '18 at 10:53
  • @SandipPatel yes. I think [ngClass]="'class1':condition1,'class2':condition2}" is not possible because the list will chnage dynamically and the class is added by the plugin I want it to remove on perticular condition – Senchu Thomas Feb 22 '18 at 10:55
  • [ngClass] will not work in this situation, since the plugin adds the class. You need to use ElementRef to find it and remove it manually. – rmcsharry Feb 22 '18 at 11:12
  • Don't imperatively set the class. Set it in the template and activate/deactivate it conditionally (in the template) based on a public boolean variable of your ts file (or some boolean expression). e.g. `
    `
    – lilalinux Jun 28 '22 at 11:00

6 Answers6

35

Import ElementRef from angular core and define in constructor then try below code:

Below line of code will give you first occurrence of <p> tag from Component. querySelector gives you first item and querySelectorAll gives you all items from DOM.

import { Component, ElementRef } from "@angular/core";

constructor(private el: ElementRef) {
}

let myTag = this.el.nativeElement.querySelector("p"); // you can select html element by getelementsByClassName also, please use as per your requirement.

Add Class:

if(!myTag.classList.contains('myClass'))
{
    myTag.classList.add('myClass'); 
}

Remove Class:

myTag.classList.remove('myClass'); 
16

You can use id in your html

<button #namebutton class="btn btn-primary">login</button>

add viewchild in your.ts

@ViewChild('namebutton', { read: ElementRef, static:false }) namebutton: ElementRef;

create a function that will trigger the event

 actionButton() {
    this.namebutton.nativeElement.classList.add('class-to-add')
    setTimeout(() => {
      this.namebutton.nativeElement.classList.remove('class-to-remove')
    }, 1000);
  }
              

and call the function.

If your native element is undefined check this answer Angular: nativeElement is undefined on ViewChild

Mauricio Gracia Gutierrez
  • 10,288
  • 6
  • 68
  • 99
Daniel Lopez
  • 398
  • 3
  • 12
4

Here are multiple ways to pass classes

<some-element [ngClass]="'first second'">...</some-element>

<some-element [ngClass]="['first', 'second']">...</some-element>

<some-element [ngClass]="{'first': true, 'second': true, 'third': false}">...</some-element>

<some-element [ngClass]="stringExp|arrayExp|objExp">...</some-element>

<some-element [ngClass]="{'class1 class2 class3' : true}">...</some-element>

From Official Docs

WasiF
  • 26,101
  • 16
  • 120
  • 128
3

If you want to change all li.myClass, you can do like this:

Note the #questions in the container div.

Component.ts

@ViewChild('questions') questions: any;

questions.nativeElement.querySelectorAll('.myClass').forEach(
  question => {
    question.classList.remove('myClass');
    question.classList.add('newClass');
  }
)

Component.html

<div #questions class="right-height" id ='dest' [dragula]='"second-bag"' [dragulaModel]="questions"> 
       {{ questions.length == 0 ? ' Drag and drop questions here ' : ' '}}
       <li
         #vc 
         data-toggle="tooltip"
         data-placement="bottom"
         title= {{question.questionSentence}}
         class="well dragbox"
         *ngFor="let question of questions; let i = index"
         [attr.data-id]="question.questionId"
         [attr.data-index]="i"
         (click)="addThisQuestionToArray(question,i, $event)"
         [class.active]="isQuestionSelected(question)"
         #myId>
           {{question.questionId}} {{question.questionSentence}}
      </li>
</div>
LordAlpaca
  • 166
  • 5
  • I am getting TypeError: Cannot read property 'nativeElement' of undefined. Because using `this.questions.nativeElement.querySelectorAll` because I use this inside a function – Senchu Thomas Feb 22 '18 at 17:04
  • Sorry, I didn't understand correctly, is it working now? – LordAlpaca Feb 23 '18 at 12:56
1

The Best and easiest way is : -

If student is null then dissabled else not. Use this in button attribute. If you are using bootstrap theme

[ngClass]="{disabled: (students === null) ? true : false}"
Inamur Rahman
  • 2,913
  • 1
  • 27
  • 29
1

If 'yourFlag' is true, 'classB' is enabled.

This worked in angular10.

class="classA {{yourFlag ? 'classB' : ''}}"
Toshiaki Aizawa
  • 101
  • 2
  • 5