0

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 class="form-group">
    <label for="prova">Prova input array</label>
    <input type="text" class="form-control form-control-sm" id="prova" placeholder="prova" [(ngModel)]="bigvalue" name="prova" maxlength="100">
</div>
<div class="d-flex flex-row" style="overflow-x: auto">
    <div *ngFor="let val of bigvalue | arrayfromstring; let i = index;" class="ml-4 my-3">
        <label for="value{{i}}">val{{i}}:</label>
        <input type="text" class="form-control form-control-sm" 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('');
      }
}

2 Answers 2

3

You just need a trackBy function

<div *ngFor="let val of bigvalue | arrayfromstring; let i = index; trackBy: trackByFn" class="ml-4 my-3">
  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

Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.