1

I want to insert dynamically attributes to an input html tag, but I don't know to to do this:

I've got this code from component side:

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-transclusion',
  templateUrl: './transclusion.component.html',
  styleUrls: ['./transclusion.component.css']
})
export class TransclusionComponent implements OnInit {

  elements: any;

  constructor() { }

  ngOnInit() {
    this.elements = {};
    this.elements.name = 'TEST1';
    this.elements.type = 'text';
    this.elements.value = '12';
    this.elements.placeholder = 'PRUEBA';
    this.elements.maxlength = '10';

    // This is only for test elements keys
    for (const el in this.elements) {
      if (this.elements.hasOwnProperty(el)) {
        console.log(`${el}: ${this.elements[el]}`);
      }
    }
  }
}

And this is my template side:

<input  type="text"
        [attr.name]="elements.name"
        [attr.value]="elements.value"
        [attr.placeholder]="elements.placeholder"
        [attr.maxlength]="elements.maxlength"/>

I want any 'forin' like method to iterate over each elements attribute and insert dynamically on the input tag, so it results like this:

<input type="text"
       [attr.*for="el in elements"]="el"/>

How can I implement this?

Best Regards Antonio

1

3 Answers 3

2

If you want to dynamically change the attributes of a single <input> tag, I would recommend you use @ViewChild. For example,

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

@Component({
  selector: 'app-transclusion',
  template: `
    <input #foobar/>
    `,
  styleUrls: ['./transclusion.component.css']
})
export class TransclusionComponent implements AfterViewInit {

  @ViewChild('foobar') foobar: ElementRef;

  constructor() { }

  ngAfterViewInit() {
    this.foobar.nativeElement.value = 'foobar';
    // change other values of element
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

You're right I can access to that element using ElementRef but i'm working on a generic forms generator that supports sereval formcontrol types (input, dropdown, calendars, spinner, toggle button, etc) and I'll have to use so much viewchildren. Thanks for the information.
2

I've just solved it using this

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

@Component({
  selector: 'app-transclusion',
  templateUrl: './transclusion.component.html',
  styleUrls: ['./transclusion.component.css']
})
export class TransclusionComponent implements OnInit {

  elements: any;

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

  ngOnInit() {
    this.elements = {};
    this.elements.name = 'TEST1';
    this.elements.type = 'text';
    this.elements.value = '12';
    this.elements.placeholder = 'PRUEBA';
    this.elements.maxlength = '10';

    const div = this.renderer.createElement('input');

    for (const el in this.elements) {
      if (this.elements.hasOwnProperty(el)) {
        this.renderer.setAttribute(div, el, this.elements[el]);
      }
    }
    this.renderer.appendChild(this.el.nativeElement, div);
  }

}

Thanks for all @nikolaus and @gab

Comments

1

You are following the wrong approach if you want to use attributes to "config" your input field you should use directives instad of a component...
and if you need to modify the native element on which you are appling your directive use the renderer service shipped with angular

1 Comment

I've never used the renderer before, I'll study it and try to implement it with this, to avoid use directly ElementRef as recomended here stackoverflow.com/a/39785823/5283767 Thanks for all

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.