Search code examples
javascriptwindow.opendocument.writenew-window

Is there a way to fix nested document.write in window.open?


I have a button that will open a new blank window using window.open, but will write a multiplication table on it.

Here's my code.

document.getElementById("p").innerHTML = "<button id = 'mult' type = 'button'>Multiplication Tables</button>";
document.getElementById("mult").onclick = function() {
  newWindow()
};
document.getElementById("close").onclick = function() {
  close()
};

function newWindow() {
  var multiplyWindow = window.open("", "multiplicationTables", "width = 300, height = 200");
  multiplyWindow.document.write(multiply());
}

function multiply() {
  document.write("<center><table border='1px'>");
  for (var a = 5; a < 11; a++) {
    document.write("<tr style='height:40px'>");
    for (var b = 5; b < 11; b++) {
      document.write("<td style='width:40px'><center><font size='4'>" + a * b + "</center></font></td>");
    }
    document.write("</tr>");
  }
}
<p id="p"></p>

I know the problem is because when I run the multiply() function, we are nesting a document.write. I thought of using document.getElementById, but the problem with that is (I think) there is no ID of a new window opened using window.open.

Instead, what happens is the multiplication table is printed on the original window, and in the new pop-up window, an "undefined" message shows up. This makes sense, again because of the nested document.writes.


Two questions:

  1. How do I fix this nested document.write and still get it to work?
  2. Is there a way to assign an ID to a new window using window.open?

Additionally, I look at this SO post: document.write nested in document.write, but the only answer was simply not to use document.write.

Thank you in advance.


Solution

  • Apart from DO NOT USE DOCUMENT.WRITE

    you cannot "nest"

    change

    function multiply() {
      document.write("<center><table border='1px'>");
      for (var a = 5; a < 11; a++) {
        document.write("<tr style='height:40px'>");
        for (var b = 5; b < 11; b++) {
          document.write("<td style='width:40px'><center><font size='4'>" + a * b + "</center></font></td>");
        }
        document.write("</tr></table>");
      }
    }
    

    to not document.write but return html

    function multiply() {
      const html = []
      html.push("<center><table border='1px'>");
      for (var a = 5; a < 11; a++) {
        html.push("<tr style='height:40px'>");
        for (var b = 5; b < 11; b++) {
          html.push("<td style='width:40px'><center><font size='4'>" + a * b + "</center></font></td>");
        }
        html.push("</tr>");
      }
      return html.join("")
    }
    
    
    function newWindow() {
      const multiplyWindow = window.open("", "multiplicationTables", "width=300,height=200");
      if (multiplyWindow) {
        multiplyWindow.document.write(multiply());
        multiplyWindow.document.close(); // important
      }  
      else alert("sorry, popups are blocked");
    }
    
    const p = document.getElementById("p");
    p.innerHTML = "<button class='mult' type='button'>Multiplication Tables</button>";
    p.addEventListener("click",function(e) {
      const tgt = e.target;
      if (tgt.classList.contains("mult")) newWindow()
    })
    <p id="p"></p>