Reactive forms in Angular now support changing focus when the Enter key is pressed

I have successfully created a table and a button that generates dynamic rows with inputs inside the table. One issue I'm facing is that when I press enter in the first input, a new row is created (which works), but I can't seem to focus on the new input field. Below is my current implementation:

<input type="text" class="form-control" placeholder="Product Code" formControlName="product_code" tabindex="{{i+1}}" (keyup.enter)="autoProduct($event)">

Here is the relevant code from my .ts file:

autoProduct(event) {
    this.addProduct();
    if (event.keyCode === 13) {
      event.preventDefault();
      const inputs =
        Array.prototype.slice.call(document.querySelectorAll('input'));
      console.log(inputs);
      const index =
        (inputs.indexOf(document.activeElement) + 1) % inputs.length;
      console.log(index);
      const input = inputs[index];
      console.log(input);
      input.focus();
      input.select();
    }
  }

I've looked at solutions on Stack Overflow, but I haven't been able to get it to work. Any assistance would be greatly appreciated.

Answer №1

You can implement the ViewChildren functionality.

private inputToFocus: any;
@ViewChildren('inputToFocus') set inputF(inputF: any) {
  this.inputToFocus = inputF
  this.inputToFocus.first.nativeElement.focus();
}

To use this, add #inputToFocus in your input tag. For example: <input ... #inputToFocus>

Edit

If you want to add a new input field dynamically, here is the code snippet:

.ts:

import { Component, ViewChildren } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular 6';
  counts = [1];
  private inputToFocus: any;
  @ViewChildren('inputToFocus') set inputF(inputF: any) {
    this.inputToFocus = inputF
    this.inputToFocus.last.nativeElement.focus();
  }

  autoProduct(event) {
    if (event.keyCode === 13) {
      event.preventDefault();
      const inputs =
        Array.prototype.slice.call(document.querySelectorAll('input'));
      const index =
        (inputs.indexOf(document.activeElement) + 1) % inputs.length;
      this.addProduct(index);
      const input = inputs[index];
      input.focus();
      input.select();
    }
  }
  addProduct(i) {
     this.counts.push(i)
  }
}

.html:

<div *ngFor="let count of counts; let i=index">
  <input type="text" class="form-control" placeholder="Product Code" tabindex="{{i+1}}" (keyup.enter)="autoProduct($event)" #inputToFocus>
</div>

Please note that I have updated the usage of .last.

Answer №2

Here is a code snippet that allows you to have control over focus in a form. This code focuses on the next field every time you press enter or the arrow down key, and it can be customized according to your needs. It also works seamlessly with Bootstrap.

The code records input fields in a table, giving you the flexibility to enable focus on any specific field. If you dynamically add an input field, the table will automatically update.

In my experience, I haven't found a better solution using Angular.

To implement this functionality, you can use the following HTML code in your editor component:

<div>
    <form>
      <div class="container-fluid" *ngFor="let item of data; let i = index">
        <div class="form-group">
          <div class="row">
            <div class="col-md-3">{{item.designation}}</div>
            <div class="col-md-2">{{item.type}}</div>
            
            <div *ngIf="item.type == 'float'" class="col-md-2">{{item.value | number: '1.1-3'}}</div>
            <div *ngIf="item.type == 'int'" class="col-md-2">{{item.value | number}}</div>

            <div class="col-md-2">
              <input #input type="number" class="form-control" (keydown)="onKeydown($event, i)">
            </div>

            <div class="col-md-3">{{item.commentaire}}</div>
          </div>
        </div>
      </div>
    </form>
  </div>

In the editor component TypeScript file (editor.component.ts), incorporate the following logic:

import { Component, OnInit } from '@angular/core';
import { ViewChildren, QueryList } from '@angular/core';

@Component({
  selector: 'app-editor',
  templateUrl: './editor.component.html',
  styleUrls: ['./editor.component.css']
})
export class EditorComponent implements AfterViewInit {

  @ViewChildren("input") inputs: QueryList<any>

  constructor() {
  }

  private onKeydown(event, val) {
    console.log(event.key);
    
    if (event.key === "Enter" || event.key === "ArrowDown") {
      // Focus on the next input field
      if (val + 1 < this.inputs.toArray().length) {
        this.inputs.toArray()[val + 1].nativeElement.focus();
      } else {
        this.inputs.toArray()[0].nativeElement.focus();
      }
    }
  }

  private processChildren(): void {
    console.log('Processing children. Count:', this.inputs.toArray().length)
  }

  ngAfterViewInit() {
    console.log("AfterViewInit");
    console.log(this.inputs);
    this.inputs.forEach(input => console.log(input));

    this.inputs.changes.subscribe(_ => 
      this.processChildren()
    );
  }

}

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

Prevent selection of future dates and display them in a muted grey color in the p-calendar component

I am attempting to prevent users from selecting future dates and visually distinguish them by setting a grey color background. However, I am having trouble disabling the future dates while the grey color background is functioning correctly. Any ideas on ho ...

Testing a custom Angular directive that encapsulates the functionality of SlickGrid

Currently, I am working on testing an angular directive that acts as a wrapper for slickgrid. 'use strict'; describe('Unit: Grid Directive', function() { var $scope; var element; beforeEach(module('grid')); beforeEac ...

esBuild failing to generate typescript declaration files while running in watch mode

Recently dove into using edBuild and I have to say, it's been a breeze to get up and running - simple, fast, and easy. When I execute my esBuild build command WITHOUT WATCH, I can see that the type files (.d.ts) are successfully generated. However, ...

jquery function context

I'm having trouble grasping function scope in this scenario. When a button is clicked, it triggers a dialog box with a textarea inside displaying a URL that can be copied for camera setup. <button id="axis-details" onclick="apikey('<?php e ...

Online application for saving a vast quantity of information on the user's device

Is there a way for a web application to store an extensive amount of data client-side, allowing for millions of records to be accessed offline by users exclusively on Chrome? I initially considered indexedDb, but I discovered it becomes almost unusable wi ...

Form data triggering inaccurate results in ajax response

After following online tutorials and seeking help from Stack Overflow, I am still struggling with a strange issue related to AJAX. I appreciate any assistance in solving this problem. I am trying to create a feature where users can search for match result ...

Is the function signature defined by this Interface syntax?

While exploring some code, I came across the following: export interface SomeInterface<T> { <R>(paths: string[]): Observable<R>; <R>(Fn: (state: T) => R): Observable<R>; } After searching through the TypeScript do ...

Ways to direct to a specific div upon clicking an anchor tag following a page reload?

<a href="#goto">Link 1</a> <div id="goto">DIV</div> Whenever I click on the anchor tag, my webpage reloads and displays a new div with the ID of goto. This div was previously hidden but is now visible at the bottom of the page. I ...

AJAX: Bringing in new content to display beneath the triggering page

Here is the code for my main page: <head> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> <style type="text/css"> div { width:100%; ...

Problem with using React state hook

Trying to implement the state hook for material-ui's onChange feature to manage error texts, I encountered an issue. I have included a screenshot of the error displayed in the console. https://i.sstatic.net/qjed8.png Below is the snippet of my code: ...

When trying to import axios from the 'axios.js' file in the 'lib' directory, a SyntaxError was encountered with the message: Unexpected identifier

My server.ts is causing issues. What am I doing wrong? const express = require('express'); const bodyParser = require('body-parser'); const cors = require('cors'); const morgan = require('morgan'); const axios = requ ...

Tutorial: Implementing InfoWindows for Markers in Google Maps API V3 in a C# Web Page

Here's my newbie question, hope the formatting is correct :) I'm working on an ASP.NET, C# application that retrieves coordinates (Lat, Lon) from SQL and displays them as markers (which is working fine). However, when I try to add infowindow ...

"Data in Fusioncharts appears to be correctly formatted, but it is having difficulties

I am developing a financial analysis tool and I need to visualize stock data using fusion charts. Currently, my dataset includes stock values along with their respective dates: $scope.chartData = [ { "label": "2017-05-11 16:00:00", "value": "930.6" } ...

Having trouble importing a TypeScript module from the global node_modules directory

I have a library folder located in the global node modules directory with a file named index.ts inside the library/src folder //inside index.ts export * from './components/button.component'; Now I am trying to import this into my angular-cli ap ...

Node.js offers a simple and effective way to redirect users to another page after they have

I am experiencing an issue when trying to redirect the client to the confirm page after a successful login process. I keep encountering some errors. view screenshot router.post('/sign_in', urlend, function(req, res) { var email = req.body.user ...

"Exploring the world of Ionic 2: uncovering its public variables

I'm facing an issue with Ionic 2, specifically with Angular. My concern revolves around a variable called "isConnected". I am unable to access it from an internal function within a function as it gives me an error saying "can't define property of ...

"Exploring the Power of ZF2 with Restful APIs and Image

I am currently in the process of developing a website utilizing Zend Framework 2 in combination with AngularJS. The backend consists of a restful webservice running on ZF2, while AngularJS is used on the client side to interact with this webservice. My ne ...

Utilizing Redux-Form to Retrieve Input Values

When a radio button is clicked, I want to display a form using redux-form. I tried following a tutorial that uses checkboxes but couldn't figure out how to implement it with radio buttons. The tutorial link is selectingformvalues. I have 2 radio butt ...

How can I activate a function in one Angular 2 component from another?

I am working with two components named componentA and componentB. They are both siblings and children of componentMother. My goal is to have a button click on componentA trigger a function call on componentB. Would the best approach be using a service wi ...

Is there a way to modify Style Properties in JavaScript by targeting elements with a specific class name using document.getElementsByClassName("Class_Name")?

I am seeking a solution to change the background color of multiple div boxes with the class name "flex-items" using JavaScript. Below is my current code: function changeColor(){ document.getElementsByClassName("flex-items").style.backgroundColor = "bl ...