skip to Main Content

I’m trying to set up a form in an Angular template, as per the example given in
"HTML Input form* Attributes" – w3schools:

<form action="/action_page.php" id="form1">
...
</form>

...
<input type="text" id="lname" name="lname" form="form1">

The important bits are the form="form1" on the last line and the id="form1" on the first line, which link the <input> element to the <form> element, without having to have the <input> nested within the <form>.

When I try to update my Angular HTML template with a hardcoded value, everything works fine:

<input form="my-form-id">

But I need to update it dynamically:

<input [form]="dynamicVariable">

Unfortunately, using the [form] attribute with square brackets causes the following error:

Can't bind to 'form' since it isn't a known property of 'input'.ngtsc(-998002)

Is there a way to use the form attribute dynamically in an Angular template?

2

Answers


  1. Chosen as BEST ANSWER

    Instead of

    <input [form]="dynamicVariable">
    

    Use

    <input [attr.form]="dynamicVariable">
    

    Although I don't think this works for practical Angular usage. For example, if I try:

      <td>
        <form [id]="tagMappingForm.value.tagName" [formGroup]="tagMappingForm">      
          <input formControlName="childrenTags">
        </form>
      </td>
      <td>
        <input [attr.form]="tagMappingForm.value.tagName" formControlName="label">
      </td>
    

    The first input works fine, but the second input causes an error:

    NG01050: formControlName must be used with a parent formGroup directive.  You'll want to add a formGroup
    

  2. Here , AfterViewInit lifecycle hook is used to set the form property of the input element to the form element using plain JavaScript.
    Create your form group as usual in your component class:

    import { Component, AfterViewInit, ElementRef } from '@angular/core';
    
    @Component({
      selector: 'app-my-component',
      templateUrl: './my-component.component.html',
    })
    export class MyComponent implements AfterViewInit {
      constructor(private el: ElementRef) {}
    
      ngAfterViewInit() {
        const formElement = this.el.nativeElement.querySelector('#my-form');
        const inputElement = this.el.nativeElement.querySelector('#lname');
    
        inputElement.form = formElement;
      }
    }
    

    Your template will have the form and input element separately:

    <form id="my-form">
      <!-- ... other form controls ... -->
    </form>
    
    <input type="text" id="lname">
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search