Home > Net >  Angular array of input change value focus next element and put same value as preceding one
Angular array of input change value focus next element and put same value as preceding one

Time:04-15

I'm trying to manage a big input by splitting it into single little inputs and populate the big one with keyup, but for some reason when I fire the keyup event the cursor goes to next little input and duplicates the value. The big input is changed and updated correctly, but little ones have problems. I tried also returning the bigvalue from editValue function, but with same result

html:

<div >
    <label for="prova">Prova input array</label>
    <input type="text"  id="prova" placeholder="prova" [(ngModel)]="bigvalue" name="prova" maxlength="100">
</div>
<div  style="overflow-x: auto">
    <div *ngFor="let val of bigvalue | arrayfromstring; let i = index;" >
        <label for="value{{i}}">val{{i}}:</label>
        <input type="text"  id="value{{i}}" name="inputarrayvals" value="{{val}}" (keyup)="editValue(i, $event, bigvalue)" maxlength="1">
    </div>
</div>

ts:

bigvalue = "00000000000000000000000000000000000000000000000"
editValue(i, val, item) {
    var vals = item.split('')
    if (val.target.value.length > 0)
        vals[i] = val.target.value
    this.bigvalue = vals.join('')
}

Pipe arrayfromstring used to populate little values:

import{ Pipe, PipeTransform } from '@angular/core';

@Pipe({
    name: 'arrayfromstring'
  })
  export class ArrayFromStringPipe implements PipeTransform {
    transform(string: any) {
          return string.split('');
      }
}

CodePudding user response:

You just need a trackBy function

<div *ngFor="let val of bigvalue | arrayfromstring; let i = index; trackBy: trackByFn" >
  trackByFn(index: number, obj: any) {
    return index;
  }

People say it's for performance but it's also for working with an array of primitive values.


The ngFor directive is set up to work with arrays of objects. When it generates html nodes it attaches the object to each node as a key, that's how it finds them in the DOM. Supposedly the trackBy function above uses indices as keys.

ngFor seems to be completely broken when passing in an array of primitive values and no trackBy function. They seem to be using completely different code when a trackBy function is included.

In fact passing any function to trackBy fixes the odd behaviour, even an empty one.

trackByFn() {}

Or

trackByFn() {
  return 'Angular devs please explain';
}

Both work.


Easiest way to reproduce this issue is like this:

export class OneComponent {
  array = '000000'.split('');
}
<div *ngFor="let val of array; let i = index">
  <input [(ngModel)]="array[i]" />
</div>

and try typing into the inputs.

I reported this as a bug because I think it's pretty janky

https://github.com/angular/angular/issues/45647

CodePudding user response:

This might happen because you hold the Shift key to input your numbers.

They keyup event gets fired both for your number key, and the shift key.

Try using the numpad, or locking the shift key before doing so ?

Otherwise, apply a condition into your function to filter non-numerci keys.

  • Related