1

Recently, I have been working on a project where the interface should work for desktop and tablets (in particular the iPad).

One issue I am coming across is with a Dojo dialog on the iPad when text entry is taking place.

Basically here is what happens:

  1. Load Dojo interface with buttons on iPad - OK
  2. Press button (touch) to show dialog (90% height and width) - OK
  3. Click on text box (touch) like DateTextBox or TimeTextBox - OK, the virtual keyboard is opened
  4. Click the date or time I want in the UI (touch) - OK, but I can't see all of the options since it is longer than the screen size...
  5. Try to scroll down (swipe up with two fingers or click 'next' in the keyboard) - not OK and the dialog repositions itself to have it's top at the top of the viewport area.

Basically, the issue is that the dialog keeps trying to reposition itself.

Am I able to stop dialog resizing and positioning if I catch the window onResize events?

Does anyone else have this issue with the iPad and Dojo dialogs?

Also, I found this StackOverflow topic on detecting the virtual keyboard, but it wasn't much help in this case...

iPad Web App: Detect Virtual Keyboard Using JavaScript in Safari?

Thanks!

Community
  • 1
  • 1

3 Answers3

2

I just came across the same issue yesterday and found a hack, which is not an elegant solution. If you want to stop the dijit.Dialog from repositioning you can:

1) Set the property ._relativePosition of a dijit.Dialog object (in this case it's "pop") after calling the method pop.show():

pop.show();
pop._relativePosition = new Object(); //create empty object

Next steps would probably be:

  1. Check browser type&OS: dojo or even better BrowserDetect
  2. Check when the virtual keyboard is activated and disable repositioning
  3. Extend dijit.Dialog with custom class (handle all of the exceptions)
2

As suggested another way to do this is to override the _position function by extending the object (or maybe relative position, or other method). Here is my solution which only allows the dialog to be positioned in the middle of the screen once. There are probably better ways to change this by playing with the hide and show events but this suits my needs.

dojo.provide("inno.BigDialog");
dojo.require("dijit.Dialog");
dojo.declare("inno.BigDialog",dijit.Dialog,{
    draggable:false,
    firstPositioned : false,
    _position : function() {
        if (!dojo.hasClass(dojo.body(), "dojoMove") && !this.firstPositioned) {
            this.firstPositioned = true;
            var _8 = this.domNode, _9 = dijit.getViewport(), p = this._relativePosition, bb = p ? null
                    : dojo._getBorderBox(_8), l = Math
                    .floor(_9.l
                            + (p ? p.x : (_9.w - bb.w) / 2)), t = Math
                    .floor(_9.t
                            + (p ? p.y : (_9.h - bb.h) / 2));
            if (t < 0) // Fix going off screen
                t = 0;
            dojo.style(_8, {
                left : l + "px",
                top : t + "px"
            });
        }
    }
});
1

You can override the _position function and call the _position function of the superclass only once. (See http://dojotoolkit.org/reference-guide/dojo/declare.html#calling-superclass-methods)

if (!dojo._hasResource["scorll.asset.Dialog"]) {
    dojo._hasResource["scorll.asset.Dialog"] = true;
    dojo.provide("scorll.asset.Dialog");

    dojo.require("dijit.Dialog");

    dojo.declare("scorll.asset.Dialog", [dijit.Dialog], {
        _isPositioned: false,
        _position: function () {
            if(this._isPositioned == false) {
                // Calls the superclass method
                this.inherited(arguments);
                this._isPositioned = true;
            }
        }
    })
}
sra
  • 23,820
  • 7
  • 55
  • 89