Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IE 11 is ignoring appendChild() for dynamically generated html pages

I am trying to create a pseudo report that shows me errors from importing data. to do this I have two functions:

                let createHtmlErrorReport = (err) => {

                    let currentDate = new Date().toLocaleString();
                    let contents = '<!DOCTYPE html> ' +
                        '<html>' +
                        '<head>' +
                        '<title>Import Inventory Import</title>' +
                        '<meta charset="utf-8" />' +
                        '<meta http-equiv="Content-Language" content="en">' +
                        '<style type="text/css">' +
                        ' html { margin:0;  }' +
                        ' body { background-color:#d6d6d6; font: 10pt sans-serif;}' +
                         'ul li{ padding: 3px; font:12pt;}'+
                        ' #header {padding:10px; background-color:#007fcc; color:#ffffff; } ' +
                        '</style>' +
                        '</head>' +
                        '<body>' +
                        '<div id="header">'+
                        '<strong>Import Inventory Import</strong>' +
                        '</div>' +
                        '<p><strong>Imported ' + currentDate + ' by ' + err.username + ' | ' + err.unprocessedItemsCount + ' items not imported | ' + err.processedItemsCount + ' items imported | '+ err.errorMessages.length + ' errors.</strong></p>'+
                        '<p>The following errors occured during import: </p>'+
                        '<div id="errorList" style="padding:5px;"></div>'+
                        '</body>' +
                        '</html>';
                    return contents;

                }

In the above I create a new document, add some basic styling and then create div container where I want a list of errors to be inserted.

<div id="errorList" style="padding:5px;"></div> 

The next function calls this method and builds the error list

            let generateImportErrorReport = (errors) => {
                        let doc = createHtmlErrorReport(errors);
                        let errorReportWindow = window.open('', '_blank');
                        errorReportWindow.document.write(doc);
                        let list = document.createElement('ul');
                        //builds a list of errors 
                        for (let i = 0; i < errors.errorMessages.length; i++) {
                            let item = document.createElement('li');
                            let message = errorReportWindow.document.createTextNode(errors.errorMessages[i]);           
                            item.appendChild(message);
                            list.appendChild(item);;
                        }  
}

The list is nothing more than an array of strings:

errors.errorMessages = [
{'Message 1'},
{'Message 2'}
]

This code works fine in Chrome and Firefox however in IE the new document is generated but the list is never appended to the selected Element. I can see the element generated but it will not add to the newly created document.

Internally the IE dev tools captures a generic message of Error: No such interface supported

I've seen other SO postings of similar problems but no solution that fits my scenario as I'm generating the html, and document at the same time vs working with an existing document.

Edit**: This code while standard js is written in typescript as part of an angular application. The TS is generated as ECMA3 and using either arrow functions or standard notation generates the same result.

I'd appreciate any suggestions or pointers on what I am missing.

like image 475
rlcrews Avatar asked Jun 30 '17 18:06

rlcrews


1 Answers

To make it work in IE 11, you can follow Mirko Cianfarani's suggestion: create the dynamic elements with the document object to which these elements will be appended. In your case, that is the document of the new report window, errorReportWindow.document. The report document should also be closed at the end.

var generateImportErrorReport = function(errors) {
  let doc = createHtmlErrorReport(errors);
  let errorReportWindow = window.open('', '_blank');
  let errorDoc = errorReportWindow.document; // Get the error report document object
  errorDoc.write(doc);
  let list = errorDoc.createElement('ul'); // Create with errorDoc
  // Builds a list of errors
  for (let i = 0; i < errors.errorMessages.length; i++) {
    let item = errorDoc.createElement('li'); // Create with errorDoc
    let message = errorDoc.createTextNode(errors.errorMessages[i]); // Create with errorDoc
    item.appendChild(message);
    list.appendChild(item);;
  }
  var errorList = errorDoc.getElementById('errorList');
  errorList.appendChild(list);
  errorDoc.close(); // Close the document
}

You can test the code in these two plunkers:

  • This plunker uses your original code
  • This plunker uses the code shown above
like image 154
ConnorsFan Avatar answered Nov 06 '22 11:11

ConnorsFan