How to get formControlName Programmatically in Angular 5 or above
Asked Answered
U

8

16

Need to know, when you have a multiple controls in a form and you want to know to which control user changed so that you can take some actions.

<input formControlName="item_name" #itemName (input)="inputChanged(itemName)">

Why I need to get formControlName?

as you can see in the image, some fields are edited but not confirmed that's why user sees options to verify or cancel the operation on that specific field. That's why I require to get formControlName of input-changed field so that I can display the options only to that field.

enter image description here

I have searched for its solution but couldn't found on stack-overflow that's why I decided to post this question with answer

Unstoppable answered 1/6, 2018 at 0:29 Comment(3)
Why can't you just pass the name as a string to inputChanged("item_name")?Bridgettbridgette
When you have a multiple controls and you want to get the control name that input has been changed.Unstoppable
Why would you need (input) at all with controls? Their purpose is to avoid things like that.Greysun
U
11

from this input field to get formControlName

<input formControlName="item_name" #itemName (input)="inputChanged(itemName)">

You only need to get the attribute formControlName

inputChanged(element: HTMLElement) {
  log(element.getAttribute('formControlName')) // item_name 
}
Unstoppable answered 1/6, 2018 at 0:30 Comment(2)
Using a template reference variable is the simplest solution to match the simple src event html technic. angular.io/guide/template-syntax#ref-varsSnivel
Note: Be aware that you will not have a formControlName attribute, when you set the formControlName as template variable, e.g. [formControlName]="xyz". Did cost me some time and headache to figure that out.Ebonize
A
6

Most straighforward way I've found:

HTML:

<input formControlName="item_name" (input)="inputChanged($event)">

TS:

inputChanged(e) {
  log(e.target.getAttribute('formControlName')) // item_name 
}

No need to add an id in every input. Just pass $event as parameter.

Absolute answered 4/1, 2019 at 10:4 Comment(1)
Not sure if its a question of Angular Version. I'm using Angular 9.2. I cannot find an attribute formControlName, but there is an attribute ng-reflect-name, which seems to be set to the fromControlName.Ebonize
D
3

You can use that approach:

<input formControlName="item_name" #itemName (change)="inputChanged($event)">

When the input's value changes, the change event occurs, and Angular provides a corresponding DOM event object in the $event variable which this code passes as a parameter to the component's inputChanged() method.

inputChanged (event: any) { // without type info
this.myValue = event.target.value;
  }
}

Reference link: https://angular.io/guide/user-input

Another alternative more elegant:

template

<form [formGroup]="usersForm">
  <input type="text" formControlName="name" placeholder="name"/>
</form>

component class

export class AppComponent implements OnInit, OnDestroy {
  usersForm: FormGroup;
  message: string;

  private subscriptions$ = new Subscription();

  constructor( private formBuilder: FormBuilder) {}

  ngOnInit(): void {
    this.usersForm = this.formBuilder.group({
      name: '',
      age: '',
      gender: '',
    });

    this.subscriptions$.add(this.name.valueChanges.subscribe(value => {
      // Do someting
    }));
  }

  ngOnDestroy(): void {
    this.subscriptions$.unsubscribe();
  }

  get name(): AbstractControl {
    return this.usersForm.get('name');
  }
}

See the complete example in the Stackbliz:
https://stackblitz.com/edit/form-builder-example

Delphinus answered 1/6, 2018 at 0:52 Comment(3)
I want to get the formControlName. Is there any way to get in function "inputChanged" ?Traprock
if you see, I am using the "valueChanges" Observable from the "AbstractControl" class. This Observable returns the Value;Delphinus
With this approach you know exactly which control has changed.Delphinus
D
1

If You are using Reactive Forms then instead of declaring formControlName in component template, you can create form in Component TS as follows:

 this.myForm= this.formBuilder.group({
      'item_name' : [null, Validators.compose([Validators.required])]
    });

Also, Instead of handling input changes through event, Reactive forms provide you privilege to handle input value changes by registering "value_changes" upon form field as follows:

this.myForm.get('item_name').valueChanges.subscribe(val => {
    this.formattedMessage = `My name is ${val}.`;
  });

In this way you always use the formControlName as defined in Reactive form Group in Component TS Definition.

It will be used in component template as follows:

<input formControlName="item_name" />
Defrost answered 1/6, 2018 at 5:53 Comment(2)
your method looks good to me. Can you share a detailed document or video link please.Unstoppable
Yes you can find detailed documentation in following link: angular.io/guide/reactive-formsDefrost
P
1

You can get formControlName attribute using ElementRef

HTML Code

 <input formControlName="item_name" #itemName>

component Class file

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

export class AppComponent implements OnInit { 

    // itemName name is reference variable #itemName

    @ViewChild('itemName') itemName: ElementRef;

    ngOnInit() {
        this.itemName.nativeElement.getAttribute('formControlName');
    }
}

Get Change Value of formControllName

<input type="text" formControlName="item_name" #itemName (input)="inputChanged($event.target.value)">

   export class AppComponent {
    inputChanged(searchValue: string) {
    console.log(searchValue);
    }
}
Pentylenetetrazol answered 1/6, 2018 at 7:19 Comment(0)
D
0

If you're using Angular Reactive Forms you can use something like this

For you HTML input

<input formControlName="item_name" #itemName (change)="inputChanged()">

For you component

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

formName: FormGroup;
myValue: string;

constructor(private formBuilder: FormBuilder) {}

ngOnInit() {
    this.formName = this.formBuilder.group({
      'item_name' : [null, Validators.compose([Validators.required])]
    });

    window.scroll(0,0);
}

inputChanged(){
    this.myValue = this.formName.get('item_name').value;
}

Reference link: https://angular.io/guide/form-validation

Disembroil answered 1/6, 2018 at 0:40 Comment(0)
K
0

Reactive form instances like FormGroup and FormControl have a valueChanges method that returns an observable that emits the latest values. You can therefore subscribe to valueChanges to update instance variables or perform operations.

Example

myForm: FormGroup;
formattedMessage: string;

constructor(private formBuilder: FormBuilder) {}

ngOnInit() {
  this.myForm = this.formBuilder.group({
    name: '',
    email: '',
    message: ''
  });

  this.onChanges();
}

Notice how we call an onChanges method in the ngOnInit lifecycle hook after having initialized our form. Here’s the content of our onChanges method:

onChanges(): void {
  this.myForm.valueChanges.subscribe(val => {
    this.formattedMessage =
    `Hello,

    My name is ${val.name} and my email is ${val.email}.

    I would like to tell you that ${val.message}.`;
  });
}

You can also listen for changes on specific form controls instead of the whole form group:

onChanges(): void {
  this.myForm.get('name').valueChanges.subscribe(val => {
    this.formattedMessage = `My name is ${val}.`;
  });
}
Kristeenkristel answered 28/4, 2020 at 3:56 Comment(0)
S
0

To get the formControlName from the input dynamically , one option is to use the event from the function in HTML

<input formControlName="item_name" #itemName (input)="inputChanged($event)">

and from component

inputChanged(event) {
   console.log(event.srcElement.attributes.formcontrolname.value); //prints item_name
}
Sulfide answered 21/6, 2022 at 5:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.