I have the following form field which works fine. By that, I mean that when I type, paste, etc into the field, the fooObj.expDate
gets updated just fine in real time and validation occurs. I have the pre-tag to make this obvious to myself.
<pre>{{fooObj.someDate | json}}</pre>
<div class="form-group inline-form__input">
<label for="someDate">Some Date</label>
<input tabindex="2"
type="tel"
class="form-control"
maxlength="7"
placeholder="MM/YY"
formControlName="someDate"
name="someDate"
[(ngModel)]="fooObj.someDate"
someDate>
</div>
However, I have that someDate
directive on this field. This directive intercepts paste events. It cancels the paste event, does some fancy formatting of the input and then does this:
setTimeout(() => {
this.target.value = 'lol fancy date';
}, 3000);
target.value
is my someDate
field. The value gets updated fine inside the input box (I see it change on the screen inside the input). However, fooObj.someDate
is NOT updated and validation does not occur. E.g. setting target value in a timeout does NOT trigger the same validation/object update as typing a key / pasting / any other javascript event.
Angular docs don't have much useful to say on this:
Angular updates the bindings (and therefore the screen) only if the app does something in response to asynchronous events, such as keystrokes. This example code binds the keyup event to the number 0, the shortest template statement possible. While the statement does nothing useful, it satisfies Angular's requirement so that Angular will update the screen.
So, how do I trigger an update of the field from a directive on that field?
Edit: I tried triggering an event on the element as recommended in the comments by using the code found here on my element: How can I trigger an onchange event manually?
Runs fine, but doesn't force the field to update:
if ("createEvent" in document) {
var evt = document.createEvent("HTMLEvents");
evt.initEvent("change", false, true);
this.target.dispatchEvent(evt);
}
else
this.target.fireEvent("onchange");
Also, here is where I am getting the idea of synthetic events not triggering "normal" actions as a keyDown or whatever would (I am really hoping I am misreading or they are wrong for this use case, but it didn't work with trying to re-issue a paste event): https://www.w3.org/TR/clipboard-apis/#clipboard-event-interfaces
NOTE: Synthetic events do not have default actions. In other words, while the script above will fire a paste event, the data will not actually be pasted into the document.