3

I am returning a value from a dialog box (MatDialogRef) to an input tag. Even though I am changing the value of the input tag, the change event is not getting triggered.

I have tried using the dispatchEvent. All of the documentation and examples I have found show the creation of the event and then triggering. I do not wish to create the event.

Others show the callback within the code. I cannot call the method within the html view change from the component without getting errors on missing parameters.

I have looked at doing this with vanilla JS and TypeScript.

// dialog box opens up clock-like interface to allow the end user to select a start and stop time

// I am using ViewChild to grab the DOM elements
// ViewChild to access startTime and stopTime DOM elements
  @ViewChild( 'startTime' ) elStartTime: ElementRef;
  @ViewChild( 'stopTime' ) elStopTime: ElementRef;

// This method runs when the ok button is clicked that closes the dialog
public calcHours (): void {
    // Variables to capture timeClock entries from DOM. Total variable to house calculation
    let currentStartTime = this.elStartTime.nativeElement.value;
    let currentStopTime = this.elStopTime.nativeElement.value;
    // Cast the returned time from string to number
    currentStartTime = +( currentStartTime.slice( 0, -( currentStartTime.indexOf( ':' ) + 1 ) ) );
    currentStopTime = +( currentStopTime.slice( 0, -( currentStopTime.indexOf( ':' ) + 1 ) ) );
    // Math to calculate the number of hours based upon the returned string time
    const totalHours = currentStopTime - currentStartTime;
    if ( currentStartTime !== '' && currentStopTime !== '' ) {
      this.dialogRef.close( totalHours );
    }
  }

// On the main component, I am using ViewChild to grab the input
// ViewChild to access hours worked DOM elements
  @ViewChild( 'hoursWorked' ) elHoursWorked: ElementRef;

// When the dialog closes, this method runs and changes the hoursWorked input
dialogRef.afterClosed().subscribe( result => {
      // Value returned from dialog box
      const dialogHoursCalc = `${ result }`;
      // Set value of input field from dialog box
      this.renderer.setProperty( this.elHoursWorked.nativeElement, 'value', dialogHoursCalc );
    } );

// My html template input tag is as follows...
<input class="form-control" type="number" step="0.01" data-number-to-fixed="2" placeholder="0.00"
                            (change)="onRecordUpdated(timeCard, timecarddet)" [(ngModel)]="timecarddet.hours" min="0"
                            max="365" #hoursWorked>

Expectation - The end user opens up the dialog box with the clock-like interface. They select a start and stop time. They click the ok button. The dialog closes and the hoursWorked input field is updated. The updating of the input field triggers the change event and the onRecordUpdated method runs.

Actual - The end user opens up the dialog box with the clock-like interface. They select a start and stop time. They click the ok button. The dialog closes and the hoursWorked input field is updated. The change event is never triggered and the onRecordUpdated method never runs.

How do I get the change event to trigger and have the onRecordUpdated method run?

Clay Hess
  • 228
  • 6
  • 24
  • Possible duplicate of [How do I programmatically force an onchange event on an input?](https://stackoverflow.com/questions/136617/how-do-i-programmatically-force-an-onchange-event-on-an-input) – nircraft Apr 05 '19 at 19:41
  • I do not believe this is a duplicate as I am trying to do this in Angular/Typescript not JS – Clay Hess Apr 05 '19 at 22:21
  • @ClayHess I deleted my answer, I noticed that it was incorrect since `subscribe` should trigger change detection without any explicit action. If it doesn't happen, it probably means you're out of a zone. It usually happens when you use libraries that aren't thought for Angular inside an Angular project – Christian Vincenzo Traina Apr 06 '19 at 21:34
  • Cristian...thanks for the update. Can you explain what you mean by "use libraries that aren't thought for Angular" please? – Clay Hess Apr 06 '19 at 23:27
  • I tried a different route. I have jQuery in my app. So I thought I would use .val() and .change() to trigger the calculation. So I put in $(selector).val(myValue).trigger('change'); The change event does not get triggered. I am not sure why. Is it because I am also using ngModel and that is superseding the jQuery change method? – Clay Hess Apr 08 '19 at 20:05
  • I also wonder if it is because I am somehow making the change outside of the Angular zone like you mentioned. If so, can you point me to any resources that may guide me? – Clay Hess Apr 08 '19 at 21:39
  • I believe I have discovered the problem. I was using a template-based form and the value was being mutated outside the Angular change detection process. I am switching to Reactive Forms. – Clay Hess Apr 11 '19 at 21:43

1 Answers1

-2

That's late, but for the next person that will has this problem :

  1. Get ChangeDetectorRef from angular core
  2. Call detectChanges function;

import { ChangeDetectorRef } from '@angular/core';

export class FooComponent {
  constructor(
    private changeDetector: ChangeDetectorRef
  ) {}

  fooEvent(){
    this.changeDetector.detectChanges();
  }
}


Ashijo
  • 90
  • 8