-2

I am dynamically generating formcontrols in the .html file.

<div *ngFor="let question of questions" style="  width: 40%;">
      <app-question [question]="question" [formGroup]="ratingForm"></app-question>
</div>

However, I need to dynamically be able to add css classes to two of the formcontrols that are auto-generated in the html file. I think I need to use @ViewChild to find the formcontrol after it's been auto-generated and then modify it to add the CSS Class I want conditionally. I only want to add the css classes if one of the two formcontrol's value have been changed.

So I have two form controls. Roof Name and Roof Year. If Roof Name OR Roof Year value changes, add a Css Class .highlight to both of them. How do I add this in the typescript? I have an OnControlChange method that triggers every time a field has been changed.

questions: any[];

ngOnInit() {
    let formControl = new RatingFormElements();
    this.formNames = Object.getOwnPropertyNames(formControl);
    let tempQuestions: any[] = 
    this.questionService.getQuestionsByKeys(this.formNames);
    this.questions = tempQuestions; //this becomes a formGroup
}

private onControlChange(value: any, name: string) {
    if (name == "roofyear" || name == "roofname") {
      //I need to do something here
      //something like this:
      this.questions.controls["roofname"].cssClass = "highlight"
      //or something like this:
      //Select DOM Element by ID: roofyear
      //add CssClass highlight to it
    }
  }
}

This is the html that gets auto-generated.

<input _ngcontent-egw-c322="" matinput="" oninput="this.value = this.value.toUpperCase()" uppercasepipe="" class="mat-input-element mat-form-field-autofill-control ng-tns-c78-77 cdk-text-field-autofill-monitored ng-dirty ng-touched ng-valid" ng-reflect-placeholder="Roof Year" ng-reflect-name="roofyear" autocomplete="on" ng-reflect-mask-expression="0000" ng-reflect-thousand-separator="" ng-reflect-suffix="" ng-reflect-prefix="" ng-reflect-id="roofyear" type="text" ng-reflect-type="text" id="roofyear" placeholder="Roof Year" aria-invalid="false" aria-required="false">

it has id="roofyear" so all my code needs to do is be able to find this DOM element by ID and then add a css class to it.

Soulzityr
  • 406
  • 1
  • 8
  • 26
  • Where are those "controls" you mention? What are `questions`? How that relates to `ratingForm`? More code.... – Antoniossss Jan 06 '21 at 18:28
  • Whats "generated in typescript file"? I didn't know that any ts files are generated when you use angular. – Antoniossss Jan 06 '21 at 18:30
  • Actual code of `app-question` would be helpfull i guess. – Antoniossss Jan 06 '21 at 18:31
  • edited with more details. I am trying to only include the code that is directly related to it. The markup is auto-generated so I just need to be able to find the DOM Element and add a css class to it like in the commented dummy code. – Soulzityr Jan 06 '21 at 18:40

2 Answers2

0

Depends on your actual markup which is not included, you will be able to do this using [class.x]=condition like

<input [class.highlight]="name=='roofyear' || name=='roofname'"/>
Antoniossss
  • 31,590
  • 6
  • 57
  • 99
0

You can get access to your FormControl and it's function by creating it like this:

@Component({
  selector: 'app-my',
  templateUrl: './my.component.html',
  styleUrls: ['./my.component.css']
})
export class MyComponent implements OnInit {
  public fg: FormGroup;
  public input: FromControl = new FormControl('', Validators.required);

  public constructor() { }

  public ngOnInit(): void {    
    this.fg = new FormGroup({
      input: this.input          
    });
  }
}

To be able to change the class depending on your value I assume, you can do this in your html:

<div [ngClass]="{'my-class': input.value === 'example'}"></div>

For more example on how to use the ngClass directive see this link: StackOverflow - Angular: conditional class with *ngClass

EDIT

@Component({
    selector: 'app',
    template: `
        <div #myDiv>Some text</div>
    `,
})
export class AppComponent implements AfterViewInit {
    @ViewChild('myDiv') myDiv: ElementRef;

    ngAfterViewInit() {
        console.log(this.myDiv.nativeElement.innerHTML);
    }
}
Leccho
  • 467
  • 5
  • 23
  • Hello, as I stated the html is dynamically generated so I cannot add the class like that to my html. I have to do it programatically in TypeScript in the OnControlChange method I pasted. The typescript example you gave doesn't show me how to add the cssclass to the formcontrol – Soulzityr Jan 06 '21 at 18:48
  • You're still the one generating the html dynamically, you should be able to add it to you element. It should be how you do it. If you still can't there's always this link: https://stackoverflow.com/questions/48755198/how-to-assign-a-css-class-to-a-form-control-programatically – Leccho Jan 06 '21 at 18:52
  • What happens if I cannot add the onBlur event to the html input like it shows in the answer to that question? – Soulzityr Jan 06 '21 at 18:58
  • Use the ID of the element and if there's no ID you add one. But again if your adding the ID, you should just add the ngClass directive. If you really can't add anything to the html then you must find a way to identify the element. – Leccho Jan 06 '21 at 19:07
  • "then you must find a way to identify the element." That is my original question. – Soulzityr Jan 06 '21 at 19:16
  • I get it but you don't listen. It's imposible that you cannot add the ngClass in your html. Or I don't see how it's impossible. – Leccho Jan 06 '21 at 19:32
  • You can find an element with id or with class. If you can't add them you can give up now. – Leccho Jan 06 '21 at 19:33
  • I do not have control over the auto-generator for the html. I don't see why that's impossible. It's a library I cannot edit. It is not that I'm not listening. You are missing my question. If you look at my html I pasted, there already is an ID included. I need to know how to use ViewChild to get that element and add a css class to it. – Soulzityr Jan 06 '21 at 20:10
  • I added the way to get an element with the ID. Look at my post edit. – Leccho Jan 08 '21 at 18:54