Opened 8 years ago

Closed 8 years ago

Last modified 8 years ago

#14788 closed feature (wontfix)

Wrong placement of popup when anchor node moved to different document

Reported by: sprabhal Owned by:
Priority: undecided Milestone: tbd
Component: Dijit Version: 1.7.1
Keywords: Cc:
Blocked By: Blocking:

Description (last modified by bill)

I am trying to create a menu widget, open new windows and place them in the newly created window's DOM after creation. This works for other elements but not for widgets that use dijit popup. Eg. Menu, DropDown?.

Once the menu widget is placed in the new window, when a menu item is clicked, the popup still opens in the old window. I notice the same behavior with DropDown?.

It's easily reproducible with the following code. Sample code:

<!doctype html>
<html>

<head>
    <script src="js/dojo1.7.1/dojo/dojo.js"></script>
    <script>
        dojo.require("dijit.MenuBar");
        dojo.require("dijit.PopupMenuBarItem");
        dojo.require("dijit.Menu");
        dojo.require("dijit.MenuItem");

        var pMenuBar;
        dojo.ready(function() {
            pMenuBar = new dijit.MenuBar({});

            var pSubMenu = new dijit.DropDownMenu({});
            pSubMenu.addChild(new dijit.MenuItem({
                label:"File item #1"
            }));
            pSubMenu.addChild(new dijit.MenuItem({
                label:"File item #2"
            }));
            pMenuBar.addChild(new dijit.PopupMenuBarItem({
                label:"File",
                popup:pSubMenu
            }));

            var pSubMenu2 = new dijit.DropDownMenu({});
            pSubMenu2.addChild(new dijit.MenuItem({
                label:"Edit item #1"
            }));
            pSubMenu2.addChild(new dijit.MenuItem({
                label:"Edit item #2"
            }));
            pMenuBar.addChild(new dijit.PopupMenuBarItem({
                label:"Edit",
                popup:pSubMenu2
            }));

            pMenuBar.placeAt("wrapper");
            pMenuBar.startup();

            dojo.connect(dojo.byId("newWindow"), "onclick", function () {
                //Any blank page
                var w = window.open("http://localhost/blank.html");

                w.onload = function () {
                    dojo.place(pMenuBar.domNode, w.document.body, "last");
            }
            });



        });
    </script>
</head>
<body class="claro">
    <div id="wrapper"></div>
    <button id="newWindow">New Window</button>

</body>

</html>

Change History (3)

comment:1 Changed 8 years ago by bill

Description: modified (diff)
Resolution: wontfix
Status: newclosed
Summary: Wrong placement of popup when Menu node moved to different documentWrong placement of popup when anchor node moved to different document
Type: defectfeature

That's true, we don't support moving widgets between documents at all, so I'm not surprised this breaks.

The obvious thing to try is to move all the popup widgets to the new document at the same time that you move the anchor DropDownButton/MenuBar/etc. widget.

Another possibility is to use before advice on dijit/popup's open() method, to (if necessary) move the popup to the same document as the anchor. Something like:

require(["dojo/aspect", "dojo/dom-construct", "dijit/popup"],
         function(aspect, construct, popup){
  aspect.before(popup, "open", function(args){
      construct.place(args.popup.around.domNode,
           args.around.domNode.ownerDocument.body);
  });
});

comment:2 Changed 8 years ago by sprabhal

Thanks for the reply. This issue seems bigger than just popups. The widget are even more messed up if I move a dijit.form.TextBox? the same way. All the focus attributes are lost once moved to the new document object. onFocus and onBlur never get triggered.

Are there any workarounds?

I do understand that Dojo was not designed to support this. It would be awesome if you could supporting this in a future release.

comment:3 Changed 8 years ago by bill

Now that you mention it, dijit does setup a bunch of event listeners on <body>, both the focus stuff you mentioned, which is setup in dijit/focus.js, and also in _CssStateMixin.js (starting in 1.8). Plus it sets classes on <body> and <html> like .dijit_a11y and .dj_ie (or whatever your browser is). So all of that would indeed break.

Sorry, I don't know any workarounds besides the obvious thing of loading dojo and dijit into that other window.

Dojo core does have some seldom used methods withDoc() and withGlobal(), but they won't solve the problems mentioned in this ticket.

Note: See TracTickets for help on using tickets.