0

I have a directive which I want to use to add dynamically attributes to input fields. Which works, it adds the correct attribute to the input field. But the directive for that attribute doesn't work. So I think I need to compile it, in the new Angular there is no compile.

So I used Renderer2, but it still doesn't work.

The directive to add dynamically attributes:

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

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

export class addAttributesDirective implements OnInit {
    @Input() attributes: any;
    constructor(private renderer: Renderer2, private el: ElementRef) {}

    ngOnInit() {
        this.addAttributes();
    }
    
    addAttributes() {
        const mapping: any = {
            FieldUppercase: 'uppercase'
        };

        this.attributes.forEach((attr: any) => {
            const attribute = mapping[attr];
            if (attribute) {
                this.renderer.setAttribute(this.el.nativeElement, attribute, 'true');
            }
        });
        
        this.el.nativeElement.removeAttribute('addAttributes');
    }
}

So when I use:

<input type="text"
      [name]="id"
      [id]="id"
      class="form-control"
      [ngModel]="value"
      [attributes]="attributes"
      addAttributes />

It adds uppercase="true" to the input field, which is correct.

But the directive for uppercase doesn't work.

Directive uppercase:

import { Directive, ElementRef, Input, OnInit } from '@angular/core';

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

export class UppercaseDirective implements OnInit {
    @Input() attributes: any;
    
    constructor(private el: ElementRef) {
    }

    ngOnInit() {
        console.log('uppercase'); 
    }
}

Normally I need to see uppercase in the console log, but that's not working. What am I doing wrong?

I can't use pipes in certain situations so want to do it like this.

Josef
  • 2,869
  • 2
  • 22
  • 23
Can
  • 553
  • 1
  • 9
  • 29
  • Can you check if this helps? https://stackoverflow.com/questions/41298168/how-to-dynamically-add-a-directive – buchipper Jul 10 '20 at 11:30
  • Not really. I have a general directive `addAttributesDirective` in which I want to add new attributes to an input element. Attribute is added, but does nothing as stated in that directive `UppercaseDirective`. If I add the uppercase attribute separately to the input element, it works .But I want to control it from the `addAttributesDirective` – Can Jul 10 '20 at 11:37

2 Answers2

3

There doesn't seem to a way to do this dynamically at runtime using the addAttribute. I think what you could do is to add all directives to your element with a boolean input and then conditionally enable or disable them. (Stackblitz).

For example -

import { Directive, ElementRef, Input, OnInit } from '@angular/core';
    
@Directive({
  selector: '[uppercase]'
})

export class UppercaseDirective implements OnInit {
    @Input() uppercaseattributes: any;
    @Input() uppercase: boolean;
    
    constructor(private el: ElementRef) {
    }

    ngOnInit() {
        if (this.uppercase)
        {
            /// ===> DO STUFF
            console.log('uppercase'); 
        }
    }
}

import { Directive, ElementRef, Input, OnInit } from '@angular/core';

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

export class LowercaseDirective implements OnInit {
    @Input() lowercaseattributes: any;
    @Input() lowercase: boolean;
    
    constructor(private el: ElementRef) {
    }

    ngOnInit() {
        if (this.lowercase)
        {
            /// ===> DO STUFF
            console.log('lowercase'); 
        }
    }
}

import { Component, VERSION } from '@angular/core';
    
@Component({
  selector: 'my-app',
  template: `<hello name="{{ name }}"></hello>
              <p (click)="onClick()" 
                  [uppercase]="enableUpperCase" 
                  [lowercase]="enableLowerCase">
                  Start editing to see some magic happen :)
              </p>`,
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular ' + VERSION.major;
  enableUpperCase: boolean = false;
  enableLowerCase: boolean = true;

  onClick() { 
      this.enableUpperCase = !this.enableUpperCase; 
      this.enableLowerCase = !this.enableLowerCase; 
  }
}
Josef
  • 2,869
  • 2
  • 22
  • 23
buchipper
  • 606
  • 4
  • 16
0

At runtime you can use

<a [attr.href]="value ? value : null"> click me </a>

Looks hacky but it works. Found that here: https://www.joshuacolvin.net/angular-conditional-attributes/

Chris Barr
  • 29,851
  • 23
  • 95
  • 135