Is there a way for me to move to the next row while navigating to the right using the keyCode function?

I am working with a table that has three columns. The first column contains text, while the second and third columns have input fields. I can navigate within a row using keyCode to move to the right, but once I reach the last column, I am unable to jump to the next row. What changes do I need to make in my code to enable this functionality?

To see the code in action, visit my StackBlitz: https://stackblitz.com/edit/angular-wmfjhh-vhkikf?file=app%2Ftable-basic-example.ts

Here is a snippet of the code:

// Snippet from HTML
<tbody formArrayName="rows" *ngIf="rows && rows !== null && !isLoading">
      <tr class="optimize-row" *ngFor="let rowControl of rows.controls; let rowIndex = index">
        <td [formGroupName]="rowIndex" *ngFor="let column of displayedColumns; let columnIndex = index;">
          <div *ngIf="attributesWithFormControls.includes(column.attribute); else otherColumns">
            <span>
              <label>
                <input style="background-color: silver" [id]="'row-' + rowIndex + '-col-' + columnIndex" type="text" arrow-div [formControl]="rowControl.get(column.attribute)" (focus)="onFocus($event)">
              </label>
            </span>
          </div>
          <ng-template #otherColumns>
            <div tabindex="0" [id]="'row-' + rowIndex + '-col-' + columnIndex" arrow-div>
              Here is a Number
            </div>
          </ng-template>
        </td>
      </tr>
    </tbody>
// TS
/**
   * Use arrowKey
   * @param object any
   */
  move(object) {
    console.log('move', object);

    const id = object.element.nativeElement.id;

    console.log(id);

    const arr = id.split('-');
    let row: number = Number(arr[1]);
    let col: number = Number(arr[3]);
    switch (object.action) {
      case 'UP':
        --row;
        break;
      case 'DOWN':
        ++row;
        break;
      case 'LEFT':
        --col;
        break;
      case 'RIGTH':
        ++col;
        break;
    }
    this.setFocus(row, col);
  }

 onFocus(event: FocusEvent): void {
    console.log('onFocus', event.target);

    const target = event.target as HTMLElement;

    if (target.tagName === 'INPUT') {
      this.currentInputInFocus = target;
    }
  }

  private setFocus(row: number, col: number) {
    console.log(`setFocus [row:${row}] [col:${col}]`);
    const newElementToFocusOn = document.getElementById(
      `row-${row}-col-${col}`
    );
    if (newElementToFocusOn) {
      console.log('focusing');
      this.currentInputInFocus = newElementToFocusOn;
      this.currentInputInFocus.focus();
    }
  }

Answer №1

In order to properly handle the switch case based on the count of input, you should consider adding more conditions:

For instance, if the column exceeds 2 (keep in mind that this number can be dynamic based on the input per row), it indicates the need to move to the next line. As a result, you must increment the row value as well:

if(col > 2)
         {
           row++;
           col = 0;
         }

The same concept applies to the previous line as well:

  switch (object.action) {
  case 'UP':
    --row;
    break;
  case 'DOWN':
    ++row;
    break;
  case 'LEFT':
    --col;
    if(col < 0)
    {
      row--;
      col = 2;
    }
    break;
  case 'RIGTH':
    ++col;
    if(col > 2)
     {
       row++;
       col = 0;
     }
    break;
}

You can see a working example on this link

Answer №2

When implementing your move function, be sure to handle the scenario where the user clicks on the right button. In this case, you need to check if the column is at the last position in the table. If it is, increment the row by one and reset the column to zero. Otherwise, simply increment the column.

A similar logic can be applied when the user clicks on the left button and reaches the first column of the table.

Your switch case statement should resemble the following:

switch (object.action) {
  case 'UP':
    --row;
    break;
  case 'DOWN':
    ++row;
    break;
  case 'LEFT':
    if (col === 0) {
      --row;
      col = 2;
    } else {
      --col;
    }
    break;
  case 'RIGHT':
    if (col === 2) {
      ++row;
      col = 0;
    } else {
      ++col;
    }
    break;
}

For a visual example, refer to this sample: stackblitz

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

What is the best way to align a dialog box on a screen?

I'm having an issue with the positioning of my dialog box - it always appears in the upper left corner when I want it to be centered in the middle. Can anyone provide guidance on how to achieve this? Below is my script code: $(function() { $("#c ...

Vue(x) causing state mutation in array

I'm currently in the process of building a Vue application to help me learn more about web development. I've hit a roadblock when it comes to updating an array in my state with data from an API. Here's a snippet of the API response: { "st ...

Angular 4 Templates in Visual Studio 2017

Seeking recommendations for an Angular 4 template that is compatible with Visual Studio 2017. Any suggestions on the optimal template to utilize and recommended steps to follow? This project will involve creating a single-page application using Angular 4 ...

Is there a way to successfully include an apostrophe in a URL?

I am currently utilizing Node.js: var s = 'Who\'s that girl?'; var url = 'http://graph.facebook.com/?text=' + encodeURIComponent(s); request(url, POST, ...) This method is not functioning as expected! Facebook seems to be c ...

Exploring ModuleFederation with Ionic and Angular showcasing the "unique" NG_VALUE_ACCESSOR concept

I am currently working in an NX workspace with the latest versions of NX, Angular, and Ionic. Within my workspace, I have one host app and one remote. My current challenge involves creating a page with two form controls. Whenever I attempt to create a bin ...

Is there a way to seamlessly update a field without refreshing the page or overloading the server?

I'm intrigued by the concept of updating a field dynamically without refreshing the page or overwhelming the server with queries. Stackoverflow demonstrates this feature when someone answers our question, and it instantly shows at the top of the page. ...

An error occurred while trying to import a module due to an unexpected token

Take a look at this codepen link I encountered an error (line 10 in index.vue) with the following import: import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer.js"; Any idea what could be causing this issue? All other ...

creating sleek animations with Pixi.js for circular shapes

Is it possible to create smooth animations on circles or sprites similar to D3.js hits in Leaflet? https://drive.google.com/file/d/10d5L_zR-MyQf1H9CLDg1wKcvnPQd5mvW/view?usp=sharing While D3 works well with circles, the browser freezes. I am new to Pixi. ...

Using Angular 4's Renderer2 to handle dynamic element IDs

Could you please advise on how to retrieve a dynamic id from the component (ts) file using the format below? Note: My goal is to scroll the content to the specific dynamic item when a user clicks a button (in this case, it's an item in a Bar chart). ...

The power of negative multiplication in TypeScript and React

I am working with a state variable called sortDirection const [sortDirection, setSortDirection] = useState<1 | -1>(1); My goal is to allow a button to toggle the state variable like this setSortDirection(sortDirection * -1); However, I encounter a ...

What is the best way to apply an animation class to a modal upon clicking a button?

When I click the "x" button on the modal, I want the animation to occur. However, what currently happens is that the modal closes without the animation. Then, upon reopening the modal, the animation occurs without any clicking involved. Below is my curren ...

I'm encountering issues with undefined parameters in my component while using generateStaticParams in Next.js 13. What is the correct way to pass them

Hey there, I'm currently utilizing the App router from nextjs 13 along with typescript. My aim is to create dynamic pages and generate their paths using generateStaticParams(). While the generateStaticParams() function appears to be functioning corre ...

Exploring Dependency Injection in Angular2: A Comparison of TypeScript Syntax and @Inject Approach

I'm currently working with Angular2 build 2.0.0-alpha.34 and I can't figure out why I'm getting different results from these two code snippets. The only variation is between using @Inject(TitleService) titleService and titleService: TitleSe ...

How can you capture the VIRTUAL keyCode from a form input?

// Binding the keydown event to all input fields of type text within a form. $("form input[type=text]").keydown(function (e) { // Reference to keyCodes... var key = e.which || e.keyCode; // Only allowing numbers, backspace, and tab if((key >= 48 && ke ...

Guide on validating and capturing business hours data from two separate fields into one input using Angular and Reactive Forms

https://i.sstatic.net/K5OA8.png My goal is to set up a reactive form using Angular, with the form group structure already defined in my .ts file as shown below: constructor( private fb:FormBuilder){} ngOnInit(): void { this.createBusinessListingF ...

How jQuery can be leveraged to eliminate HTML elements within a dropdown menu

<script> $(document).ready(function() { $('.notification .tools .remove').on('click', function () { alert('hola'); $(this).parentsUntil('.notification').remove(); }) ...

Can the string literal type be implemented in an object interface?

My custom type is called Color, type Color = 'yellow' | 'red' | 'orange' In addition, I created an object with the interface named ColorSetting. interface ColorSetting { id: string yellow?: boolean red?: boolean orang ...

Switching user agents to access mobile websites

I'm currently using JavaScript to redirect the main website to the mobile website, but I'm struggling to switch back to desktop view on a mobile device. Is there any way to provide a link labeled "Full Website" that redirects to the main website ...

Managing state in a live chat application

Currently seeking advice on managing state in a real-time messaging/chat app created with VueJS 2. The application is made up of multiple components as shown in the diagram below: https://i.sstatic.net/VGTo8.png Up to this point, I have successfully imp ...

Protractor Surprise Alert: Oops! jQuery is missing

Troubleshooting jQuery Error After conducting thorough research, I have come across various code samples to handle expected alert boxes. However, I am facing difficulty in finding a solution for handling random alerts that may or may not appear. The webs ...