0

I found out that there is a IE bug, where setting the placeholder is calling the input event as described here. This happens on page load, so there was no user interaction.

My code:

app.component.html

<mat-form-field>
  <input matInput placeholder="test" (input)="onValueChange('test')">
</mat-form-field>

app.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})

export class AppComponent implements OnInit {

  ngOnInit() {
  }

  onValueChange(value: string) {
    console.log("should not be in here");
  }
}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatDialogModule } from '@angular/material/dialog';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatCardModule } from '@angular/material/card';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    MatCardModule, MatFormFieldModule, MatInputModule, MatDialogModule, BrowserAnimationsModule, MatExpansionModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

browserlist (note that IE 9-11 is enabled)

# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries

# You can see what browsers were selected by your queries by running:
#   npx browserslist

> 0.5%
last 2 versions
Firefox ESR
not dead
IE 9-11 # For IE 9-11 support, remove 'not'.

tsconfig.json (note the es5)

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "module": "esnext",
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es5",
    "lib": [
      "es2018",
      "dom"
    ]
  },
  "angularCompilerOptions": {
    "fullTemplateTypeCheck": true,
    "strictInjectionParameters": true
  }
}

Here is the stackblitz project, but you can't debug with IE11. In my real project I have a ngFor, which creates multiple input elements.

Is there a solution for this?

Demonstrating the issue

IE calls input change event on page load

ng version

Angular CLI: 8.3.22
Node: 10.14.2
OS: win32 x64
Angular: 8.2.14
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.803.22
@angular-devkit/build-angular     0.803.22
@angular-devkit/build-optimizer   0.803.22
@angular-devkit/build-webpack     0.803.22
@angular-devkit/core              8.3.22
@angular-devkit/schematics        8.3.22
@angular/cdk                      7.3.6
@angular/cli                      8.3.22
@angular/material                 7.3.6
@ngtools/webpack                  8.3.22
@schematics/angular               8.3.22
@schematics/update                0.803.22
rxjs                              6.5.4
typescript                        3.5.3
webpack                           4.39.2

step-by-step instructions

  • ng new test (no Angular routing, SCSS)
  • replace app.component.html and app.component.ts (add mat-form-field and onValueChange())
  • add MatFormFieldModule, MatInputModule and BrowserAnimationsModule to app.module.ts
  • ng add @angular/material (Indigo-pink, no HammerJS, browser animations yes)
  • edit browserlist (remove NOT at the line IE 9-11)
  • set target to es5 in tsconfig.json
testing
  • 19,681
  • 50
  • 236
  • 417

2 Answers2

1

I tried to test your sample code with the IE 11 browser. I found that the input event is not getting called on page load. It occurs normally when the input gets changed.

Testing result:

enter image description here

I suggest you again test the issue and check the result with a new empty project.

Let me know if I missed any steps in testing. I will again try to test the issue to check the result.

Edit :-------------------------------------------------------------------------------------------------------------------------

After spending some time on again matching the two projects I found the difference.

I noticed that placeholder="test" in your HTML code in app.component.html causing this issue. You had already mentioned it in your original post. Other than that I did not get any other difference. It does look like any bug.

<mat-form-field>
  <input matInput placeholder="test" (input)="onValueChange($event)">
</mat-form-field>

See here:

enter image description here

It was working on my side because I had added the Value attribute to the input. I had added it just for testing purposes and because of that value gets displayed instead of placeholder text. I forget to remove it.

This is my code:

<mat-form-field>
  <input matInput placeholder="test" (input)="onValueChange($event)" value="sample text">
</mat-form-field>

I am not sure why placeholder caused this issue. As IE will only get security updates in the future, I am not sure whether there will be any fix for it. You can try using workarounds for it to avoid the issue in the IE browser.

Deepak-MSFT
  • 10,379
  • 1
  • 12
  • 19
  • I edited my question to show you the issue. Which code did you use? My initial code or the one, which should fix it? I'm using IE with the version 11.55.17763.0. The fix from me seems to be currently working, but I'll have to adapt my real project and see if it works with multiple elements. – testing Mar 13 '20 at 14:53
  • I again check that test project stored on my machine and verify that I tested your first code and I also run it again and verify that onValueChange is not getting executed on pageload and it is working fine on IE 11 (11.719.18362.0) browser. I want to confirm with you which Angular version you are using? – Deepak-MSFT Mar 16 '20 at 08:11
  • Angular 8 (see edited question). I could zip my project and upload it if you would like to. The difference in IE version could be a hint (as well as the Angular version). – testing Mar 17 '20 at 15:38
  • You can see my project properties here. https://imgur.com/a/xr3S3bu It's almost similar to little variations. You can try to share the sample project. We will try to test it to check the issue. Please remember to remove any confidential information from the sample project. We do not require any personal or confidential information. Thanks for your understanding. – Deepak-MSFT Mar 18 '20 at 09:19
  • [Here](https://1drv.ms/u/s!Ai9ncfqPpKQMawK54aDN6evQ6Cw?e=IGXdQS) you go. I've deleted `node_modules` folder, but you can bring it back with `npm install`. – testing Mar 19 '20 at 10:11
  • I tried to run your project and I can see the issue. I tried to compare your project with mine and it looks similar. So not sure what caused this issue. I suggest you try to create a new project and check whether it also has a similar issue or not. – Deepak-MSFT Mar 20 '20 at 03:18
  • Now I set up a complete new project on a new machine with the same result. Now I'm using *Angular CLI: 9.0.7* and *IE 11.719.18362.0*. I made some changes, which I'll edit in my question (forgot to mention these). So is this the problem with the `placeholder`, that IE recognizes it as input change? – testing Mar 22 '20 at 14:21
  • Looks like you are adding something after creating a new project causing this issue. I also created a new project. Then I installed the Angular material. Then try to put mat input and ran the project and again it worked fine on my side. Can you just follow these steps and see whether it works or not? It can help to narrow down the issue. – Deepak-MSFT Mar 23 '20 at 06:01
  • You also need to adapt *app.mobule.ts* in your instructions. I tried your instructions and I get a white page in IE. I have to make some more changes (as described in my edited question - see step-by-step instructions). Then I'm at the same problem again. – testing Mar 23 '20 at 18:28
  • Yes, you need to do those changes for the IE browser. I did not mention it to reduce complexity. My project has the similar steps like yours. – Deepak-MSFT Mar 24 '20 at 07:28
  • Did you use other settings at the project creation (browser animations, routing, ...)? Do you have the same issue if you follow my instructions? – testing Mar 24 '20 at 11:50
  • Please check the Edit part in my answer. – Deepak-MSFT Mar 25 '20 at 07:18
  • My workaround in the question seems to work (forgot another place to add it). If you have a better workaround, feel free to add it. – testing Mar 25 '20 at 11:48
1

My solution is based on this:

app.component.html

<mat-form-field>
  <input matInput placeholder="test" (input)="onValueChange($event)" (focus)="onFocus($event)" (blur)="onFocus(null)">
</mat-form-field>

app.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})

export class AppComponent implements OnInit {
  selectedElement: any;

  ngOnInit() {
  }

  onValueChange(event) {
    if (event && this.selectedElement && event.target == this.selectedElement) {
        // do whatever you like
        console.log(event.target.value)
    }
  }

  onFocus(event) {
    if(event){
       this.selectedElement = event.target;
    } else {
       this.selectedElement = null; 
    }
    //console.log(this.selectedElement);
  }
}

With this the code is only be called if the user changes a value (enter/deleting some characters). You have to do this for every input/textarea field, which has a placeholder and uses the (input).

testing
  • 19,681
  • 50
  • 236
  • 417