FormArray does not properly handle invalid input focus

Although everything functions correctly with a regular FormGroup, the issue arises when dealing with a FormArray as it fails to focus on the invalid input.

Here is how my form is initialized:

initForm() {
    this.parentForm= this.fb.group({
      childFormArray: this.fb.array([this.createchildForm()])
    });
  }

Following the initialization, the FormArray is set up like so:

createChildForm(data?: any): FormGroup {
    var childForm = this.fb.group({
      name: [data?.name? data?.name: '']
    });
    childForm .valueChanges.subscribe(value => {
      var fieldWithValue = Object.keys(value).filter(key => value[key] == '');
      fieldWithValue.forEach(conName => {
         childForm .get(conName)?.addValidators([Validators.required]);
      });
    });
    return childForm ;
  }

My method for setting errors after clicking submit (a requirement);

   assignError(){
    this.parentForm.controls.childFormArray.value.forEach((v: any, index: number) => {
          var array = this.parentForm.controls.childFormArrayas FormArray;
          var item = array.at(index);
          var emptyItems = Object.keys(v).filter(key => v[key] == '');
          emptyItems.forEach(ele => {
            if (ele != "section") {
              item.get(ele)?.updateValueAndValidity({ emitEvent: false });
            }
          });
        });
       }

Additionally, I have created a validator that checks for invalid input and focuses on it.

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

@Directive({
    selector: '[focusInvalidInput]'
})
export class FormDirective {
    constructor(private el: ElementRef) { }
    @HostListener('submit')
    onFormSubmit() {
        const invalidControl = this.el.nativeElement.querySelector('.ng-invalid');
        if (invalidControl) {
            invalidControl.focus();
        }
    }
}

Including its selector in the respective form:

focusInvalidInput (ngSubmit)="saveDetails()"

Inside the submit method, I call the error adding method:

 saveDetails(){
  assignError();
}

Despite all these efforts, focusing on the invalid inputs within the FormArray remains unsuccessful. When I log the invalidControl, it displays all the invalid inputs, which should not be the case possibly due to multiple invalid inputs causing confusion on which one to focus. Trying to utilize the .first() method resulted in an error stating that first is not recognized as a method.

Answer №1

The reason for the issue was that focus does not work on div elements, and my inputs wrapped inside a div were part of formArray controls.

<div id="resp-table-body" *ngFor="let item of getParentFormControls(); let i = index"
                            [formGroupName]="i">
                                <div class="table-body-cell">
                                    <input type="text" class="form-control no_shadow_input" id="name"
                                        placeholder="Enter Here" formControlName="name" autocomplete="off">
                                    <span *ngIf="item.get('name')?.hasError('required')"
                                        class="text-danger">
                                        Name is required
                                    </span>
                                </div>
    </div>

To fix this, I simply added input.ng-invalid to my directive.

const invalidControl = this.el.nativeElement.querySelector('input.ng-invalid');

After making this change, everything is now functioning correctly.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using React to update state with a function that returns a value

I am facing an issue where the value returned by the function checkSuggestionList is not being passed to this.state.validSearchParentInput. It seems like the value is being set using setState before the function checkSuggestionList finishes executing. ...

Create a Dockerfile specifically designed for an Angular application

I've been scouring numerous online articles in an attempt to create a docker container specifically for testing Angular. Unfortunately, I keep encountering the same error in all of the examples: => ERROR [6/6] RUN npm run build --omit=dev ...

How to eliminate the yellow box in Three.JS when working with EdgesGeometry, LineSegments, and BoxHelper

Three.js Version: 82 I recently came across an interesting example on the official Three.js website: In this example, I noticed the presence of yellow boxes surrounding the 3D models. Previously, in version 79, I used THREE.EdgesHelper to outline the 3D ...

Creating dynamic animations for your elements with AJAX

How can I apply animation to an element as soon as it appears? I want others with the same properties to remain unaffected. Here is my approach: $.each(data, function(i, obj) { if(obj['Ping'] == "FALSE"){ ...

Display a text field upon clicking on a specific link

I am trying to create a text field that appears when a link is clicked, but I haven't been able to get it right yet. Here is what I have attempted: <span id="location_field_index"> <a href="javascript:void(0)" onclick="innerHTML=\"< ...

Unleashing the Power of Typescript and SolidJS: Expanding the Properties of JSX Elements

Is there a way to enhance the props of an existing JSX element in SolidJS and craft a custom interface similar to the ButtonProps interface shown in this React example below? import Solid from 'solid-js'; interface ButtonProps extends Solid.Butt ...

The property 'apply' is trying to be accessed but is undefined and cannot be read

Not being an expert in frontend development, I've hit a roadblock on what seems like a simple issue. I'm attempting to load one set of nodes from a JSON file successfully, but when trying to add new nodes from another JSON file, I encounter this ...

Discovering the process of deriving a deeper shade hex color

When using this particular solution to calculate the darker range of a color, I encountered an issue where the output does not seem to be the correct Hex value as it is missing one part. > #84079 I'm wondering what mistake I might be making in my ...

Erase every element contained within the div

What steps should I take to clear out the elements within my mainDiv? <div id='mainDiv'> <fieldset> <div> <input type='text'> <select></select> </div> ...

Moving the sidebar from the app component to a separate component in Angular results in a situation where the sidebar does not maintain full height when the page is scrolled down

Within my Angular application, I have implemented a sidebar as a separate component. Previously, the content of the sidebar was housed within the main app component's HTML page, and it functioned properly by taking up the full height of the page when ...

Setting the initial value in a directive property can be done by assigning the desired

Explore this interactive example: Check out my custom attribute directive named myTrimmer designed to trim lengthy text: It functions perfectly with static content. <div myTrimmer="10">some longgggg texttttttttttttttt</div> However, it encou ...

The issue arises due to conflicting indent configurations between eslint and @typescript-eslint/indent

Currently, I am using eslint and prettier in a TS express application. I am trying to set the tab width to 4, but it appears that there is a conflict between the base eslint configuration and the typescript eslint. When looking at the same line, this is w ...

An AJAX function nested within another AJAX function

Is there a way for me to return the second ajax call as the result of the ajax function? I could use some assistance with this. function ajax(url: string, method:string, data:any = null) { var _this = this; return this.csrfWithoutDone().done(funct ...

`How to easily download multiple images with just one click``

I am looking for a way to enable users to download multiple images by simply checking the boxes next to each image and clicking a single button. Currently, I have individual download links below each image. I have added checkboxes next to each image for s ...

Ways to confirm the existence of local storage in Vue.js data

Recently, I created a to-do list using Vue js and localstorage(LS). Everything was working fine until I tried to run it on a different browser where LS is not allowed. An error popped up saying Cannot read property 'items' of null". The issu ...

Troubleshooting Problem with Angular Material 2's Mat-Paginator [Length] Bug

Utilizing the mat-paginator component for a table, I am facing an issue where I am unable to dynamically set the length of the paginator based on the total number of results retrieved from an API call. Despite trying various methods like setting it in the ...

"Securing Your Web Application with Customized HTTP Headers

I'm currently working on setting up a POST request to a REST API (Cloudsight) with basic authorization. Here is the code I have so far: var xhr = new XMLHttpRequest(); xhr.open("POST", "http://api.cloudsightapi.com/image_requests", true); xhr.setRequ ...

Feeling lost when it comes to forms and hitting that submit button?

Below is a sample form structure: <html> <head> <title>My Page</title> </head> <body> <form name="myform" action="http://www.abcdefg.com/my.cgi" method="POST"> <div align="center"> <br><br; <br& ...

Incorporate adjustable div heights for dynamically toggling classes on various DOM elements

One of the challenges in developing a chat widget is creating an editable div for users to input text. In order to maintain the design integrity, the box needs to be fixed to the bottom. An essential requirement is to have javascript detect resizing as us ...

Accessing the session object within an Express middleware function is crucial for

This is my unique Express middleware setup: var app = express() .use(express.cookieParser()) .use(express.session({secret: 'HiddenSecret'})) .use(express.bodyParser()) .use(function displaySession(req, res, next) { consol ...