Identify and correct the invalid item within an array form

https://i.sstatic.net/33oNr.png

How can I target and focus on an invalid item in a form array?

I have attempted the following using nativeElement focus, but I am not able to pinpoint the exact invalid control.

 if (this.basicForm.invalid) {
        const invalid = [];
        const controls = this.basicForm.controls;
         for (const key of Object.keys(this.basicForm.controls)) {
           if (this.basicForm.controls[key].invalid) {
     
            const invalidControl = 
               this.el.nativeElement.querySelector('[formcontrolName="' + key + '"]');
               invalidControl.focus();
                break;
}
}
}

Answer №1

Unfortunately, using .querySelector('[formcontrolName="' + key + '"]') is not recommended.

Instead, it is suggested to utilize a directive to focus on the invalid field.

@Directive({
  selector: '[focusOnError]'
})
export class FocusOnErrorDirective {

  @ContentChildren(NgControl, { descendants: true }) fields: QueryList<NgControl>

  @HostListener('submit')
  check() {
    const fields = this.fields.toArray();
    // By logging field, we can determine how to access the nativeElement
    for (let field of fields) {
      if (field.invalid) {
        const nativeElement = field.valueAccessor && (field.valueAccessor as any)._elementRef ? 
                (field.valueAccessor as any)._elementRef.nativeElement : null;
        if (nativeElement) {
          nativeElement.focus();
        }
        break;
      }
    }
  }
}

To implement the directive in your <form>, simply add it like so:

<form [formGroup]="form" focusOnError (submit)="submit(form)">
 ...
</form>

An example can be found on this stackblitz link

Note: If dealing with complex elements like custom formControls or ng-autocomplete from angular-ng-autocomplete, accessing the nativeElement might require additional steps.

For instance, with angular-ng-autocomplete, you can access the nativeElement using

(field.valueAccessor as any).searchInput.nativeElement

By examining the field object in the console, you can improve the directive accordingly.

  check() {
    const fields = this.fields.toArray();
    for (let field of fields) {
      if (field.invalid) {
        const nativeElement =field.valueAccessor?
            (field.valueAccessor as any)._elementRef? 
                   (field.valueAccessor as any)._elementRef.nativeElement
            : (field.valueAccessor as any).searchInput? 
                   (field.valueAccessor as any).searchInput.nativeElement
            : null:
            null;

        if (nativeElement) {
          nativeElement.focus();
        }
        break;
      }
    }
  }

Make sure to check for field.valueAccessor and proceed accordingly to reach the desired nativeElement.

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

Having trouble with Trading View? I need to add a custom time frame to my chart, but for some reason they're not showing up. Not only that

Having trouble with Trading View as I try to add a custom time frame, but it's not displaying on the chart. Also looking to hide the time interval dropdown widget. https://i.sstatic.net/pMk6c.png Looking to customize the chart by hiding certain time ...

NodeJS data is unavailable for Angular2 to access

I am currently using NodeJS as the backend to serve JSON data from MySQL through localhost:3002/visit. My goal is to have Angular2 retrieve this JSON data from my NodeJS server. The issue arises when I try to switch the URL in my Angular2 app's HTTP G ...

Change the value of the material slide toggle according to the user's response to the JavaScript 'confirm' dialogue

I am currently working on implementing an Angular Material Slide Toggle feature. I want to display a confirmation message if the user tries to switch the toggle from true to false, ensuring they really intend to do this. If the user chooses to cancel, I&ap ...

Modify Angular HTML attributes - update names

Currently, I am working with an HTML string that looks like this: <span class="diff-html-changed" id="1" changes="MyText">test</span> I want to display this text as HTML. To include it in my code, I perform the following steps: displayedCont ...

How can I avoid a component from triggering its subscription twice in Angular 5 when the component is nested twice inside another component?

How can I prevent a component in Angular 5 from triggering its subscription twice when the component is placed twice inside another component? For example, I have a NavMenuComponent with two instances of a cart in its template. <!-- cart 1 in n ...

Looking to utilize custom toolbars with apexcharts for enhanced functionality

Recently, I integrated apexcharts into my new app and the chart is functioning properly. However, I encountered an issue when trying to add a custom toolbar similar to a sidebar with charts. After implementing the UI for it, I now need to make the icons fu ...

npm-install fails to automatically install sub-dependencies

I'm currently working on an Angular 4 project that has specific dependencies. The project is functioning properly as it is. Now, my goal is to utilize this project in another project. I've added the original project to the package.json file (und ...

How can I retrieve the `checked` state of an input in Vue 3 using Typescript?

In my current project, I am using the latest version of Vue (Vue 3) and TypeScript 4.4. I am facing an issue where I need to retrieve the value of a checkbox without resorting to (event.target as any).checked. Are there any alternative methods in Vue tha ...

A guide to submitting forms within Stepper components in Angular 4 Material

Struggling to figure out how to submit form data within the Angular Material stepper? I've been referencing the example on the angular material website here, but haven't found a solution through my own research. <mat-horizontal-stepper [linea ...

Implementing dynamic ngFor loops for nested objects with varying child lengths in Angular

I am looking to implement a file tree feature in my Angular application. The file tree structure can have multiple levels with numerous children attached. Below is an example of the JSON object I am working with: "root": { "element": { "displ ...

AgmMarkerSpiderModule experiences compatibility issues when upgrading from angular 11 to version 12

Issue: node_modules/agm-oms/marker-spider.module.d.ts:7:22 - error NG6002: Module AppModule is importing AgmMarkerSpiderModule, but it cannot be recognized as an NgModule class This typically implies that the library (agm-oms/marker-spider.module) contain ...

What is the process for transferring data from child components to parent components in Angular 2?

I have been thinking about the scenario where a descendant of a descendant of a parent needs to pass information back up to the parent. Would the descendant passing the information need to go through the chain back up? Descendant2 Component -> Descenda ...

Use JavaScript's Array.filter method to efficiently filter out duplicates without causing any UI slowdown

In a unique case I'm dealing with, certain validation logic needs to occur in the UI for specific business reasons[...]. The array could potentially contain anywhere from several tens to hundreds of thousands of items (1-400K). This frontend operation ...

The spinner failed to appear within 2000 milliseconds

After submitting the form, I want to display a spinner for 2000 milliseconds. However, my implementation using the setTimeout function is not working as expected. import { Component, OnInit } from '@angu ...

Retrieving a distinct value from an Observable

I am currently attempting to extract the monthlyFee value from this specific response body. ...

Struggling to center align a button with Bootstrap 5 and Flexbox

I'm having trouble centering the Define New link, and I can't figure out what I'm doing wrong. I'm new to this, so please be patient with me. Below is the code snippet: <div class="col-xl-3 d-flex flex-column justify-content-be ...

Error thrown when using React Router DOM: FC{} | ReactNode is not compatible with type ReactNode

Recently, I started using TypeScript and delving into a project that involves the react-router-dom. However, as I attempt to create elements in my App.tsx file, an error keeps popping up. Let's take a look at the code snippet: <Route path="la ...

What is the best approach to transpiling TypeScript aliased paths to JavaScript?

I am currently facing an issue with my TypeScript project where I need to transpile it into executable JavaScript while using path aliases for my NPM package development. One specific scenario involves importing a method from the lib directory without spe ...

What is the functionality of typeof globalThis in TypeScript?

Currently, I am delving into the TypeScript definitions repository @types, specifically examining entries like this one for @types/node: declare var global: typeof globalThis; I am wondering about the mechanics behind this. Since globalThis is contingent ...

Error: Unable to locate the type definition file for the '@babel' package

I am currently working on a new project and here is the content of my package.json file. { "name": "dapp-boilerplate", "version": "1.0.0", "main": "index.js", "license": "MI ...