1

I'm using @HostListener("document:keyup", ["$event"]) to have a real Time operation. Let's say I have 3 inputs: A B and R(result). I want to sum A+B and show R in its input. But I'd like to modify R and get B modified by R-A.

On screen:

Input A: 5

Input B: 3

Input R: 8

Then, modify R manually to 5 change the value of B.

Input R: 8 -> 5. Input B should turn 0. But it never turns 0 because as soon as I press anything the function just calculates A+B and gives the result on R. How can I achieve this without creating a loop?

 @HostListener("document:keyup", ["$event"])
  public operar(){

    this.gananciaEuros = 0;
    this.gananciaPorcentaje ="";
    this.resultado = "";
    this.calc.controls.total.setValue(0);
    if (!this.calc.controls.costo.value || !this.calc.controls.precioNeto.value) { //si la var está vacía
      this.calc.controls.total.setValue("Rellene ambos campos");
    }else{
      this.resultado = Number(Number(this.calc.controls.precioNeto.value) / Number(this.calc.controls.costo.value));
      this.gananciaEuros = Number((Number(this.calc.controls.precioNeto.value) - Number(this.calc.controls.costo.value)).toFixed(2));
      this.gananciaPorcentaje = String(((this.resultado - 1) * 100).toFixed(2));
      this.calc.controls.total.setValue(Number(this.gananciaEuros)/* +" (" + String(this.gananciaPorcentaje) +"%)" */);
      this.calc.controls.precioNeto.setValue(Number(this.gananciaEuros) + Number(this.calc.controls.costo.value))
    }
  }

html

<div class="divformulario">
    <form [formGroup]="calc">
        <div class="formsubconjuntovertical spacebetween">
         <div [innerHtml]="'Calcular Ganancia sobre precio' | uppercase | bold" "></div>
            <mat-form-field>
                <mat-label>Precio costo</mat-label>
                <input matInput type="number" formControlName="costo" />
            </mat-form-field>
            <mat-form-field  >
                <mat-label>Precio de venta neto</mat-label>
                <input matInput type="number" formControlName="precioNeto" " />
            </mat-form-field>
            <mat-form-field>
                <mat-label>Ganancia</mat-label>
                <input matInput type="number" formControlName="total" style="text-align: right;" "/><span matSuffix>€</span>
            </mat-form-field>
        </div>
    </form>
</div>
Germán
  • 1,007
  • 1
  • 7
  • 20

1 Answers1

1

Instead of using an HostListener, you can use the event keyup and bind the three values (a, b, r) to component variables.

Here is an exemple of the html file:

A
<input type="number" [(ngModel)]="aValue" (keyup)="changeFromA($event)"/>

B
<input type="number" [(ngModel)]="bValue" (keyup)="changeFromB($event)"/>

R
<input type="number" [(ngModel)]="rValue" (keyup)="changeFromR($event)"/>

And in you component:

aValue : number = 5;
bValue : number = 3;
rValue : number = 8;

changeFromA(_ : any) {
  this.rValue = this.aValue + this.bValue;
}

changeFromB(_ : any) {
  this.rValue = this.aValue + this.bValue;
}

changeFromR(_ : any) {
  this.bValue = this.rValue - this.aValue;
}
Powkachu
  • 2,170
  • 2
  • 26
  • 36
  • I'll try this way. Meanwhile, as I'm very new with Angular, what is this underscore that you put in the parenthesis of each function? I understand that ": any" is the type of the variable that typescript needs, but I don't know what a underscore means. – Germán Jan 29 '20 at 08:17
  • It's just the `$event` parameter, I could have written `changeFromA(event : KeyboardEvent)`. I called this parameter `_` because I know I won't use it in my function. That's just a name. :) – Powkachu Jan 29 '20 at 09:02
  • I have tried with a little test - it works probably as expected by "keyup"- however, the inputs contains little arrows up and down to modify the number by clicking them (1 up, 1 down). When I use these little buttons, the result is not changed, probably because they are not "keyup". Any suggestion? (Edit: I'm doing it without passing $event) – Germán Jan 29 '20 at 09:09
  • Add on each input `(change)="changeFromX($event)"` so it will also detect this change. – Powkachu Jan 29 '20 at 09:16
  • That works wonderfully. Thanks a lot, Powkachu. (Nice nick btw). May I ask you one last thing? I have been trying to find a easy way to move the focus to the next input on enter key press. However, every way I have found on the internet are long implementations of code that I quite don't understand. I wonder if you (that seem to know well Angular) know a way to make this focus change easily. I hope you don't mind to help me with this extra question. Thank you. – Germán Jan 29 '20 at 09:32
  • Haha happy to help! [This](https://stackoverflow.com/q/50006888/5049472) can help, it's what I'm used to use. You need to use `@ViewChild` and `myElement.nativeElement.focus()`. – Powkachu Jan 29 '20 at 09:45