4

I need to create a page that allows users to "undock" a section of the page into a new window that they could move to a second monitor, and then be able to "re-dock" that section to the main page. The section that is undocked needs to maintain its state and event listeners when it's being docked and undocked. Solution can be Javascript or jQuery.

I got this to work beautifully in Chrome and Firefox by just appending DOM objects to the new Window. But IE apparently doesn't let you do this, according to this well-documented post: Calling adoptNode and importNode on a child window fails in IE and Edge. I was getting this error in IE: JS5022

Here is my current attempt, using .html, which appeared to work in IE, but then I realized I'm losing all the event listeners.

<head>
<script src="https://code.jquery.com/jquery-3.1.0.js" integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk=" crossorigin="anonymous"></script>
<script src="lab.js"></script>
</head>
    <body>
      <div id="A">
        <h3>Div A</h3>
        <input type="text" name="fname" placeholder="test">
        <br>
        <button id="popinout">Pop in/out</button>
      </div>

      <div id="B">
        <h3>Div B</h3>
      </div>
    </body>
var docked = true;
var floatWindow;

$("#popinout").click(function() {
  console.log(docked);
  if (docked == true) {
    undock();
  } else {
    dock();
  }
});

var dock = function() {
  docked = true;
  //Left over from approach where I was trying to copy DOM elements.
  $("body").prepend($("#A", floatWindow.document));
  floatWindow.close();
};

var undock = function() {
  docked = false;
  floatWindow = window.open("", "", "menubar=no, toolbar=no, titlebar=no, location=no, resizable=yes");
  var head = $("head").clone().html();
  var tmp = document.createElement("div");
  var divA = $(tmp).append($("#A")).html();
  //css does not load without this open / close (do not know why)
  floatWindow.document.open();
  floatWindow.document.close();
  $("head", floatWindow.document).append(head);
  $("body", floatWindow.document).append(divA);
  floatWindow.onbeforeunload = function() {
    dock();
  };
};

Here's a fiddle: https://jsfiddle.net/esharri2/4tj1zv9m/

Community
  • 1
  • 1
ESH
  • 41
  • 2

1 Answers1

0

I think what you should do is:

  • Make that component / section available via ajax (widget etc)
  • Load it with ajax on "main page"
  • Create separate html page that includes only that section and pass it's state via query params. This is the page you use in popup/new window.

That way you can use the same component/section alone or include it to some other page.

And if your component is really complex (lot of data), you can for example send the component state to server, create some unique hash to that data and then use that hash to load the data from server in popup window.

Hardy
  • 5,590
  • 2
  • 18
  • 27
  • Thanks, Hardy! I had started to think about something like this. This ultimately seems like it'd be a little "cleaner" than what I'm trying to do. – ESH Aug 06 '16 at 13:45
  • Yeah, copying stuff from DOM to another window is more like "bubblegum solution". – Hardy Aug 06 '16 at 13:47