最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How can I pass a FormControl to a function from the template? - Stack Overflow

programmeradmin0浏览0评论

Let's say I have this:

<input formControlName="someName" (click)="onClick()">

I want my onClick function to be generic and set the value of the corresponding FormControl (the one I clicked).

How can I pass the concerned FormControl as a parameter of onClick?

I thought I could retrieve it from the control property of FormControlDirective or FormControlName but none of them have an exportAs attribute.

Let's say I have this:

<input formControlName="someName" (click)="onClick()">

I want my onClick function to be generic and set the value of the corresponding FormControl (the one I clicked).

How can I pass the concerned FormControl as a parameter of onClick?

I thought I could retrieve it from the control property of FormControlDirective or FormControlName but none of them have an exportAs attribute.

Share Improve this question asked Mar 18, 2020 at 18:51 Guerric PGuerric P 31.8k6 gold badges58 silver badges104 bronze badges
Add a comment  | 

7 Answers 7

Reset to default 5 +100

I think this is what you want to achieve.

import { Directive, HostListener, Optional, Output, EventEmitter } from '@angular/core';
import { NgControl, FormControl } from '@angular/forms';

@Directive({
  selector: '[appOnClickControl]' // if you want to target specific form control then use custom selector else you use can use input:
                                   // selector: 'input' to target all input elements
})
export class TestDirective {
  @Output() emitFormControl = new EventEmitter<FormControl>();

  constructor(@Optional() private formControl: NgControl) {
  }


  /**
   * If your only goal is to set value to the form control  then use this
   */
  @HostListener('click')
  onClick() {
    if (this.formControl) {
      this.formControl.control.setValue('test');
    }
  }

  /**
   * If you wanna pass the form control through the function you might use this
   */
  @HostListener('click')
  getFormControl(): void {
      this.emitFormControl.emit(this.formControl.control as FormControl);
  }
}
 <input
  appOnClickControl // use this to initialize directive
  (emitFormControl)="yourMethod($event)" // $event is the clicked form control
  formControlName="test"
></input>

In your html:

<input formControlName="someName" (click)="onClick($event)">

And then define your onClick function as:

onClick(event): void {
 alert(event.target.value)
}

Edit To get FormControl:

<input formControlName="someName" (click)="onClick(Form.get('someName'))">

and

onClick(formControl): void {
    formControl.setValue(someValue);
  }

kinda repetitive but pretty sure you can only do this:

<input formControlName="someName" (click)="onClick('someName')">

then use someName on your form group to find the control

onClick(name: string) {
  const fc = this.form.get(name);
  // do whatever
}

Not exactly sure what you're after, but try if the following works for you. It uses setValue() method to set values for the form. You can also use patchvalue if you want to set only partial values of the form.

Template

<form [formGroup]='groupedform' >
  <label>Name:  <br>
    <input type="text" formControlName='Name' required (mousedown)="onMouseDown(groupedform)"/>
  </label>
  <br>
  <br>
  <label>Email:  <br>
    <input type="email" formControlName='Email' required (mousedown)="setEmail(groupedform)"/>
  </label>
  <p>
  <button type="submit" [disabled]="!groupedform.valid" (click)="updateName()">Update Name</button>
  </p>
</form>

Component

export class AppComponent  {
   name = 'Angular';
   firstname = new FormControl('');
   groupedform = this.fb.group({
    Name : ['', Validators.required],
    Email: [],
  });

  constructor(private fb:FormBuilder) { }

  updateName() {
    console.log(this.groupedform.value);
  }

  onMouseDown(formControl: any) {
    this.groupedform.setValue({
      'Name': 'sample',
      'Email': '[email protected]'
    });
  }

  setEmail(formControl: any) {
    this.groupedform.patchValue({
      'Email': '[email protected]'
    });
  }
}

Working example: Stackblitz

You can use template variable for this

<input formControlName="someName" #temp (click)="onClick(temp)">

onClick(val) {
console.log(val);}

I am not sure what type of value you want to set, but you can use an attribute directive for this type of common operation (if it is simple).

You can create an attribute directive and set on all the form controls, the attribute directive logic will automatically handle it for you. You can definetely configure the values passed to directives.

import { Directive, HostListener, ElementRef, Input } from "@angular/core";

@Directive({
  selector: '[clickMe]'
})
export class ClickDirective {
  @Input('clickMe') clickValue:string;
  constructor(private elementRef: ElementRef){}

  @HostListener('click') onClick() {
    this.elementRef.nativeElement.value = this.clickValue;
  }
}

Now just use these directives with the the form controls and pass your values, you can use data binding as well.

<form [formControl]="myForm">
  Firstname:<input type="text" fromControlName="firstname" [clickMe]="'first value'" />
<br>
Lastname:<input type="text" fromControlName="lastname" [clickMe]="'last value'" />
</form>

Please find the working stackblitz here:https://stackblitz.com/edit/angular-j1kwch

You could use the event passed and get the attribute name out of it:

<input type="text" class="form-control" formControlName="yourName" (blur)="yourMethod($event)" />

Then in your method get the name of the formControlName from the target:

yourMethod(event: any) {
  const controlName = e.target.getAttribute('formcontrolname');
  this.formGroup.get(controlName); // this is your FormControl
  ....
}
发布评论

评论列表(0)

  1. 暂无评论