A user account is required in order to edit this wiki, but we've had to disable public user registrations due to spam.

To request an account, ask an autoconfirmed user on IRC (such as one of these permanent autoconfirmed members).

Difference between revisions of "Dialogs"

From WHATWG Wiki
Jump to: navigation, search
(Proposal)
(Tooltips)
Line 39: Line 39:
  
 
* GMail's contacts list has rich tooltips.
 
* GMail's contacts list has rich tooltips.
 +
 +
* Google Docs
 +
<img src=http://junkyard.damowmow.com/482>
  
 
=== Lightboxes ===
 
=== Lightboxes ===

Revision as of 18:09, 5 August 2011

Problem statement

There's no markup or API for dialog boxes, tool palettes, hovering tooltips, the contents of popup widgets, and the like.

Real world examples today

Dialogs

Registration Dialogs

  • http://digg.com/ - make sure to be logged out if you have an account, and click the Join Digg! button

Login Dialogs

  • http://slashdot.org/ - make sure to be logged out if you have an account, and click the Log In link
  • http://digg.com/ - make sure to be logged out if you have an account, and click the Login button
  • http://newsvine.com/ - make sure to be logged out if you have an account, and click the Log In | Register link
  • http://www.bahn.de/ - Login link is rightmost in main navigation bar - try tapping: funny handling of focus order, skipping positions, at times keyboard trap

Other Dialogs

  • http://www.kongregate.com/ - register for account, log in, click Get Kreds, click Fund Your Account button
  • GMail - Click "more" on the left, then Create New Label.

Tooltips

  • Digg has one when you click on something when logged out.

  • The tooltips in the table of [1] are interesting because they are currently <div>s and force the parent to be a TD rather than a TH since TH is inline only, even though the visible content is really just phrasing content.

  • GMail's contacts list has rich tooltips.
  • Google Docs

Lightboxes

Other

A list of URLs from Steve Faulkner to look at — if anyone has the time to go through these and pick out those that are real use cases (as opposed to demos or examples, since those tend to not reflect real needs but more reflect what's easy to demo!) then please add them where appropriate above.

http://flowplayer.org/tools/overlay/index.html http://alloy.liferay.com/deploy/demos/dialog/ http://www.bbc.co.uk/glow/docs/1.5/furtherinfo/widgets/overlay/ http://rightjs.org/ui/dialog/demo http://jqueryui.com/demos/dialog/ http://download.dojotoolkit.org/release-0.4.2/dojo-0.4.2p1-widget/tests/widget/test_Dialog.html http://www.sencha.com/examples/pages/window/hello.html http://www.sencha.com/examples/pages/window/dialog.html http://www.sencha.com/examples/pages/window/accordion.html http://dev.sencha.com/deploy/ext-4.0.2a/examples/window/window.html http://leandrovieira.com/projects/jquery/lightbox/ http://www.huddletogether.com/projects/lightbox/ http://developer.yahoo.com/yui/examples/container/panel.html http://reghellin.com/milkbox/ http://bertramakers.com/moolabs/imagezoom.php http://www.aryweb.nl/projects/MooDialog/

Code Examples

Reddit

HTML:

<a href="#" onclick="return showcover(false);">register</a>
...
<div class="login-popup cover-overlay" style="display: none; "
    <div class="cover" onclick="return hidecover(this)"></div>
    <div class="popup">
        ...
    </div>
</div>

Javascript:

function showcover(a, b) {
    $(".login-popup:first").show().find('form input[name="reason"]').val(b || "");
    return !1
}
function hidecover(a) {
    $(a).parents(".cover-overlay").hide();
    return !1
}

(showcover() has been truncated to remove code not relevant to showing the dialog: if variable a is set as 'true', another element (not found in this page) is also shown)

CSS:

.popup {
  position: fixed;
  left: 10%;
  background-color: white;
  top: 40px;
  width: 80%;
  z-index: 1001;
}
.cover {
  position: fixed;
  top: 0px;
  left: 0px;
  height: 100%;
  width: 100%;
  background-color: gray;
  opacity: .7;
  z-index: 1000;
}

Slashdot

HTML:

<div id="modal_cover" class="push" onclick="hide_modal_box(); return false;" style="display: none;"></div>
<div id="modal_box" class="push" style="display: none;">
   ...
   <div id="modal_box_content">...</div>
</div>

<a href="//slashdot.org/my/newuser" onclick="javascript:getModalPrefs('newUserModal', 'Create Account', 1); $('#modal_box').addClass('join'); return false;" class="btn link">Join</a>

Javascript: (getModalPrefs has been truncated to remove code not relevant to showing the dialog)

function getModalPrefs(section, title, tabbed, params) {
    Slash.busy(BUSY_FETCHING_MODAL, true);
    $bg = get_modal_parts('#modal_cover').css('opacity', 0.75).show();
    $any('modal_box_content').load('/ajax.pl', $.extend({op: this_op,section: section,reskey: reskey_static,tabbed: tabbed,return_to: return_to}, params || null), function(response, status, transport) {
        if (status === 'success') {
            $any('preference_title').html(title);
            var $modal = show_modal_box().data('tabbed', tabbed);
            tabbed && $modal.addClass("tabbed");
        } else {
            $bg.hide();
        }
        Slash.busy(BUSY_FETCHING_MODAL, false);
    });
}

function show_modal_box() {
    return custom_modal_box('show').keyup(function(e) {
        e.which == $.ui.keyCode.ESCAPE && hide_modal_box();
    });
}

function hide_modal_box() {
    var retainclass = " ";
    if ($('#modal_box').hasClass('push')) {
        retainclasses = 'push';
    }
    custom_modal_box('hide').hide().attr('style', 'display: none;').removeClass().addClass(retainclasses).removeData('tabbed').unbind();
    if (document.forms.modal_prefs && document.forms.modal_prefs.refresh_onclose && document.forms.modal_prefs.refresh_onclose.value) {
        document.location = document.URL;
    }
    return false;
}

CSS:

#modal_box.join {
  margin: 0px 33% 0;
  width: 390px;
  height: 440px;
}
#embbeded_login_modal.push, #modal_box.push {
  margin-top: 9em !important;
}
#modal_box {
  position: fixed;
  z-index: 1000001;
}
#modal_cover {
  margin-top: -12px;
  margin-left: -13px;
  background: rgba(0, 0, 0, .6);
  height: 100%;
  position: fixed;
  width: 100%;
  z-index: 1000000;
}

DB Dahn

HTML:

<li id="mn-login" class="rollover">
    <a href="https://fahrkarten.bahn.de/privatkunde/start/start.post?lang=de&scope=login" id="login" class="jhover" rel="nofollow"><span>Login</span></a>
    <h3><span>Login</span></h3>
    <ul>...</ul>
</li>

If #mn-login is given class of rollover (done using javascript on focus and mouseover, removed on blur, the h3 and ul tags are displayed in CSS:

#main-nav ul ul, #main-nav ul h3 {
  border: 1px solid #9FA3AB;
  display: none;
  left: -9999em;
  position: absolute;
}
#main-nav li#mn-login.rollover h3 {
  left: -6px;
}
#main-nav li#mn-login.rollover ul {
  left: auto;
  right: 6px;
}


Brainstorms

Early Ideas

(These are random ideas inspired by the above and similar APIs in other languages. They need careful evaluation and are not a proposal.)

  • have to handle showing an element that's descendant of display:none content; does that just not count?
  • callbacks as arguments to show() and especially showModal(), as in, dialog.showModal(function (returnValue) { ... })

Proposal

  • <dialog>
    • can be used as flow, or as child of <th> or <dt>. Can't be used in <hx> due to parsing problems (it couldn't contain its own heading).
    • semantically it's like hidden="", the contents aren't there.
    • sectioning root.
  • dialog.showModal();
    • causes the dialog to be absolutely positioned with explicit top and left/right (based on rtl) so that its margin box is centered in current viewport, but margin top edge is not above top of viewport.
    • dialog can be drag moved which affects the left and top/right
    • dialog is focused when displayed
    • everything else in the document is made unfocusable
    • escape key fires 'cancel' event; default behaviour is to call close() with empty string as value
    • dialog.oncancel event handler
    • dialog::cover
      • only active if the dialog was shown with showModal(); has magic positioning that covers the whole viewport under the dialog regardless of scrolling.
      • animatable separate form the dialog element itself, so you can fade it in then the dialog.
      • dialog.onclickoutside event handler fires if user clicks on the cover
    • <form method=dialog>
      • only valid inside <dialog>
      • makes submission hide the dialog and call the close callback
      • on submission, dialog.returnValue is set to the value of the submit button that was used
  • lightboxes are handled by the <dialog> being width:100%;height:100%; or some such
  • dialog.close([returnValue]) sets dialog.returnValue if value is given, and closes the dialog
  • dialog.returnValue is a string
  • dialog.onclose event handler
  • dialog.show([anchor])
    • anchor can be an element or a MouseEvent. If it's an element, the anchor point is the center of the given element's first box. Otherwise it's the mouse position given by the event.
    • displays the dialog, anchored so that its anchor point is at the point given by the show() method argument.
    • follows anchor point
    • anchor point comes from 'anchor' property? anchor: (top|bottom|left|right) [center | <length> [from (top|bottom|left|right)]]; uses given point on margin box edge
    • can't be drag moved.
  • <dialog open> attribute is set when dialog is showing.
    • dialog:not([open]) { display: none; } /* allows authors to do transitions if they want */

Other brainstorms

(Proposals for similar or related functionality found elsewhere.)