[ 2 posts ]

peteh

  • Joined: Mon Aug 17, 2009 12:32 pm
  • Posts: 12
  • Offline
  • Profile

Stacked modal dialogs and positioning

Post Posted: Tue Aug 02, 2011 10:01 pm
+0-
Here as an example of stacked YUI dialogs in my application:
Image
Admittedly I've cheated a little by manually arranging the dialogs.

I've been playing with constraintoviewport, fixedcenter and context configuration settings for the dialogs but none produced a satisfactory result. Here is what I would consider a satisfactory result:

  • The dialog should behave a bit like a position:fixed element (absolute position in relation to the browser window)
  • The user must be able to move the dialog and so must custom code
  • The user should be able to move the dialog such that portions are clipped because they are outside the browsers window
  • The dialog can NEVER be moved such that the entire content is outside the browsers window, i.e. something is always visible when the dialog is visible

I'd love to hear from anybody who has had some successes with this.

Pete

peteh

  • Joined: Mon Aug 17, 2009 12:32 pm
  • Posts: 12
  • Offline
  • Profile

Re: Stacked modal dialogs and positioning

Post Posted: Mon Aug 08, 2011 4:05 am
+0-
I found a way to manage this a lot better.

I frequently use the context configuration attribute with my dialogs but found that if the context element itself is inside another dialog, it works OK the first time but if you close and re-open the dialog but in between move the dialog containing context object, alignment is lost.

Also, for stacking dialogs I found the fixedcenter and constraintoviewport configuration attributes where not particularly helpful.

I added the method moveToViewport to the YAHOO.widget.Dialog.prototype (see below). I now call this method each time immediately before calling the show method. The result is quite acceptable:

  • If the context element is specified and it's reference corner corner is inside the view port, the dialog will be moved such that its reference corner alings with the contexts reference corner
  • If at least some parts of the dialog are currently visible, no move takes place
  • The dialog will be moved such that its top left corner is 10 pixels from the left and the top of the view port

Users can drag a dialog anywhere they like and close it, but when the dialog is re-opened by calling moveToViewport before calling show, the metod will do the first of the above steps that applies.

Code:
/**
* Moves a YAHOO.widget.Dialog object into the viewport.
* The method takes one of these steps (in this order):
* 1) If the context element is specified and it's reference corner corner is
*      inside the view port, the dialog will be moved such that its reference
*      corner alings with the contexts reference corner
* 2) If at least some parts of the dialog are currently visible, no move takes
*    place
* 3) The dialog will be moved such that its top left corner is 10 pixels from
*    the left and the top of the view port
* @namespace YAHOO.widget
* @class Dialog
* @method moveToViewport
*/
YAHOO.widget.Dialog.prototype.moveToViewport = function()
{
   var _LFT = 0,
         _TOP = 1,
         _RGT = 2,
         _BTM = 3,
         rectVP = [],
         rectDLG = [],
         context = this.cfg.getProperty('context');

   rectVP[_LFT] = YAHOO.util.Dom.getDocumentScrollLeft();
   rectVP[_TOP] = YAHOO.util.Dom.getDocumentScrollTop();
   rectVP[_RGT] = rectVP[_LFT] + YAHOO.util.Dom.getViewportWidth(),
   rectVP[_BTM] = rectVP[_TOP] + YAHOO.util.Dom.getViewportHeight()

   if (context)
   {
      rectDLG = YAHOO.util.Dom.getXY(context[0]);

      // determine reference point
      switch(context[2])
      {
         case 'tr':
            rectDLG[_LFT] = rectDLG[_LFT] + context[0].clientWidth;
            break;
         case 'bl':
            rectDLG[_TOP] = rectDLG[_TOP] + context[0].clientHeight;
            break;
         case 'br':
            rectDLG[_TOP] = rectDLG[_TOP] + context[0].clientHeight;
            rectDLG[_LFT] = rectDLG[_LFT] + context[0].clientWidth;
            break;
      }

      if (rectDLG[_LFT] >= rectVP[_LFT] && rectDLG[_LFT] <= rectVP[_RGT] &&
            rectDLG[_TOP] >= rectVP[_TOP] && rectDLG[_TOP] <= rectVP[_BTM])
      {
         switch(context[1])
         {
            case 'tr':
               rectDLG[_LFT] -= this.element.clientWidth;
               break;
            case 'bl':
               rectDLG[_TOP] -= this.element.clientHeight;
               break;
            case 'br':
               rectDLG[_LFT] -= this.element.clientWidth;
               rectDLG[_TOP] -= this.element.clientHeight;
               break;
         }

         this.moveTo(rectDLG[_LFT], rectDLG[_TOP]);
         return;
      }
   }

   rectDLG = YAHOO.util.Dom.getXY(this.element),
   rectDLG[_RGT] = rectDLG[_LFT] + this.element.clientWidth;
   rectDLG[_BTM] = rectDLG[_TOP] + this.element.clientHeight;

   // No overlap?
   if (rectDLG[_LFT] > rectVP[_RGT] || rectDLG[_RGT] < rectVP[_LFT] ||
         rectDLG[_TOP] > rectVP[_BTM] || rectDLG[_BTM] < rectVP[_TOP])
   {
      this.moveTo(rectVP[_LFT] + 10, rectVP[_TOP] + 10);
   }
};
  [ 2 posts ]
Display posts from previous:  Sort by  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum