0

I'm running into weird behaviour on IE11 when filtering tabular data using Angular.

<ng-container *ngFor="let item of items; trackBy: trackByFn">
    <tr>...</tr>
    <tr *ngIf="showDetails(item)">...</tr>
</ng-container>

What happens is that some rows are not properly rendered when the items change (i.e. when searching or filtering data) in IE11:

enter image description here

As you can see in the image above, the <tr> element is there, and so is its content. The green rows render just fine, but the red one clearly isn't. As soon as I hover the empty row, its content will appear again.

The issue is probably caused by the ng-container wrapping each two rows, IE can't handle this properly. Any ideas to fix this?

JasonK
  • 5,214
  • 9
  • 33
  • 61
  • 1
    ---------- This should help try the below link [Try this](https://stackoverflow.com/questions/5805956/internet-explorer-9-not-rendering-table-cells-properly) – Naveen Nov 29 '19 at 10:26
  • Does your code has any extra spaces in td? If yes then try to remove it may help to fix this issue for IE browser. – Deepak-MSFT Nov 29 '19 at 13:21

1 Answers1

0

Removing the spaces in <td> elements didn't resolve the issue, unfortunately. However, I did managed to get it working by creating a custom *ngIf directive for Internet Explorer only, which forces the browser to re-render the table:

For those who run into the same issue, here is the code:

import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';

/**
 * Add the template content to the DOM when the condition is true for IE browsers only.
 */
@Directive({
  selector: '[appIfIE]'
})
export class IfIeDirective {

  private hasView = false;
  private isIE = navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') > -1;

  constructor(
    private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef
  ) {}

  @Input() set appIfIE(condition: boolean) {
    if (!this.isIE && !this.hasView) {
      this.createView();
    } else if (this.isIE && condition && !this.hasView) {
      this.createView();
    } else if (this.isIE && !condition && this.hasView) {
      this.clearView();
    }
  }

  createView() {
    this.viewContainer.createEmbeddedView(this.templateRef);
    this.hasView = true;
  }

  clearView() {
    this.viewContainer.clear();
    this.hasView = false;
  }

}

... and apply the directive where you see fit:

<tbody *appIfIE="!loading">

Cheers!

JasonK
  • 5,214
  • 9
  • 33
  • 61