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 Chat (such as one of these permanent autoconfirmed members).

Dialogs: Difference between revisions

From WHATWG Wiki
Jump to navigation Jump to search
 
(37 intermediate revisions by the same user not shown)
Line 24: Line 24:
* http://newsvine.com/ - make sure to be logged out if you have an account, and click the Log In | Register link
* 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
* 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
==== Popups ====
These are "dialogs" in the sense that they are modal boxes that accept input, but they are typically anchored to some other UI, not centered in the viewport.
* Google Calendar's "create" widget
<img src=http://junkyard.damowmow.com/483>
* Google+'s speedbumps
<img src=http://junkyard.damowmow.com/484>
<img src=http://junkyard.damowmow.com/487>


=== Other Dialogs ===
=== Other Dialogs ===
Line 29: Line 40:
* http://www.kongregate.com/ - register for account, log in, click Get Kreds, click Fund Your Account button
* 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.
* GMail - Click "more" on the left, then Create New Label.
<img src=http://junkyard.damowmow.com/491>
* Google+ circle editor
<img src=http://junkyard.damowmow.com/486>
* Google+ hovercard UI
<img src=http://junkyard.damowmow.com/490>
* iCloud's login error message box — note animation during display
<img src=http://junkyard.damowmow.com/488>
<img src=http://junkyard.damowmow.com/489>


=== Tooltips ===
=== Tooltips ===
Some of these appear on mouseover, some on click, and some on load. Some of them dismiss when the mouse moves away, some have to be explicitly dismissed. The distinguishing factor though is that these are not model — you can interact with other stuff on the page while they are up (in the simplest case, selecting the text from which they appeared).


* Digg has one when you click on something when logged out.
* Digg has one when you click on something when logged out.
<img src=http://junkyard.damowmow.com/479>
<img src=http://junkyard.damowmow.com/479>


* The tooltips in the table of [http://bioinfo-prod.mpl.ird.fr/xantho/x.org/gui/seqterm.php] are interesting because they are currently &lt;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.
* The tooltips in the table of [http://bioinfo-prod.mpl.ird.fr/xantho/x.org/gui/seqterm.php] are interesting because they are currently &lt;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. They appear on mouse over.
<img src=http://junkyard.damowmow.com/481>
<img src=http://junkyard.damowmow.com/481>


* GMail's contacts list has rich tooltips.
* GMail's contacts list has rich tooltips that appear on mouse over.
 
* Google Docs and GMail have some that appear on load
<img src=http://junkyard.damowmow.com/482>
<img src=http://junkyard.damowmow.com/492>
 
* Google+ has one for when you add someone -- the rest of the page is still interactive (though using any other widget makes this one go away).
<img src=http://junkyard.damowmow.com/485>


=== Lightboxes ===
=== Lightboxes ===
Line 45: Line 76:
* http://trailers.apple.com/trailers/independent/therift/ - click "View Trailers" and then "Teaser" - video lightbox, many other examples on trailers.apple.com
* http://trailers.apple.com/trailers/independent/therift/ - click "View Trailers" and then "Teaser" - video lightbox, many other examples on trailers.apple.com
* http://warmetal.wikia.com/wiki/Aegis - click on the picture of the card
* http://warmetal.wikia.com/wiki/Aegis - click on the picture of the card
=== 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 ==
== Code Examples ==
Line 220: Line 230:
== Brainstorms ==
== Brainstorms ==


=== Requirements ===
=== 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.)
(These are random ideas inspired by the above and similar APIs in other languages. They need careful evaluation and are not a proposal.)


* &lt;dialog; element. defaults to display:none; height:shrinkwrap; width: shrinkwrap; position: center;.
* &lt;dialog> &lt;dialogtitle> ... &lt;/dialogtitle> ... &lt;/dialog>
* &lt;dialog caption=""> to give title (instead of &lt;dialogtitle>)
* &lt;dialog canclose=""> to toggle close box
* dialog title area can be dragged (cursor:move).
* dialog.show() / .hide();
* show at cursor position, track cursor position, show at offset from cursor position...
* have to handle showing an element that's descendant of display:none content; does that just not count?
* have to handle showing an element that's descendant of display:none content; does that just not count?
* dilaog.showModal() / .close(returnValue) / .returnValue
* callbacks as arguments to show() and especially showModal(), as in, dialog.showModal(function (returnValue) { ... })
* callbacks as arguments to show() and especially showModal(), as in, dialog.showModal(function (returnValue) { ... })
* &lt;input type=dialog-button value=returnValue> / &lt;button type=dialog-button value=returnValue> - default action is to close dialog and set .returnValue to the button's value
* dialog::cover { } to style a position:fixed rect that covers the viewport under a modal dialog
* some way to have the cover animate-fade in before the dialog appears
* some way to animate the dialog opening
* dialog[open] like details[open]
* what does hidden="" do on such an element?
* &lt;info> as a child of an element for a rich tooltip
* &lt;info for=""> to give tooltip for an element that can't have children, like <img>, <option>
* A feature to have info boxes point at a particular other element (think the bubbles on Google maps, the new feature notifications in GMail, the tooltip on Digg)


=== Ideas ===
=== Proposal ===


(These are more random ideas inspired by the above and similar APIs in other languages. They need careful evaluation and are not a proposal.)
*<dialog>
** can be used as flow, or as child of &lt;th> or &lt;dt>. Can't be used in &lt;hx> due to parsing problems (it couldn't contain its own heading).
** semantically it's like hidden="", the contents aren't considered part of the parent.
** sectioning root.
*<dialog open> attribute is set when dialog is showing.
** dialog:not([open]) { display: none; } /* allows authors to do transitions if they want */
* lightboxes are handled by the <dialog> being width:100%;height:100%; or some such
* rely on CSS for all styling except positioning (for now)


*<dialog>
* dialog.showModal([anchor])
*-
** dialog is focused when displayed
*dialog.showModal();
** everything else in the document is made unfocusable
** causes the dialog to be absolutely positioned with explicit top and left/right (based on rtl) so that it is centered.
** escape key  fires 'cancel' event; default behaviour is to call close() with empty string as value
** can be dragged which affects the left andtop/right
** dialog.oncancel event handler
*dialog::cover
** push onto fullscreen stack
** only active if the dialog was shown with showModal(); has magic positioning that covers the whole viewport under the dialog.
** obtain a dialog::backdrop
*dialog.show([anchor])
*** only active if the dialog was shown with showModal(); has magic positioning that covers the whole viewport under the dialog regardless of scrolling.
** displays the dialog, anchored so that its anchor point is at the center of the given element's first box.
*** animatable separate form the dialog element itself, so you can fade it in then the dialog.
** anchor point comes from 'anchor' property? anchor: (top||bottom||left||right) [<percentage> [from (left||right||bottom||top)]]; uses given point on margin box edge
*** dialog.onclickoutside event handler fires if user clicks on the cover
** z-index: magic to keep on top of anything displayed before it
 
* dialog.show([anchor]);
** shows the dialog
 
* dialogs can be opened without anchors
** 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.
** [let JS do this:] dialog can be drag moved which affects the left and top/right
* dialogs opened with anchors
** 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.close([returnValue]) sets dialog.returnValue if value is given, and closes the dialog
* dialog.returnValue is a string
* dialog.onclose event handler
 
* <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


=== Other brainstorms ===
=== Other brainstorms ===

Latest revision as of 22:28, 4 April 2012

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

<img src=http://junkyard.damowmow.com/477>

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

<img src=http://junkyard.damowmow.com/480>

<img src=http://junkyard.damowmow.com/478>

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

Popups

These are "dialogs" in the sense that they are modal boxes that accept input, but they are typically anchored to some other UI, not centered in the viewport.

  • Google Calendar's "create" widget

<img src=http://junkyard.damowmow.com/483>

  • Google+'s speedbumps

<img src=http://junkyard.damowmow.com/484> <img src=http://junkyard.damowmow.com/487>

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.

<img src=http://junkyard.damowmow.com/491>

  • Google+ circle editor

<img src=http://junkyard.damowmow.com/486>

  • Google+ hovercard UI

<img src=http://junkyard.damowmow.com/490>

  • iCloud's login error message box — note animation during display

<img src=http://junkyard.damowmow.com/488> <img src=http://junkyard.damowmow.com/489>

Tooltips

Some of these appear on mouseover, some on click, and some on load. Some of them dismiss when the mouse moves away, some have to be explicitly dismissed. The distinguishing factor though is that these are not model — you can interact with other stuff on the page while they are up (in the simplest case, selecting the text from which they appeared).

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

<img src=http://junkyard.damowmow.com/479>

  • 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. They appear on mouse over.

<img src=http://junkyard.damowmow.com/481>

  • GMail's contacts list has rich tooltips that appear on mouse over.
  • Google Docs and GMail have some that appear on load

<img src=http://junkyard.damowmow.com/482> <img src=http://junkyard.damowmow.com/492>

  • Google+ has one for when you add someone -- the rest of the page is still interactive (though using any other widget makes this one go away).

<img src=http://junkyard.damowmow.com/485>

Lightboxes

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 considered part of the parent.
    • sectioning root.
  • <dialog open> attribute is set when dialog is showing.
    • dialog:not([open]) { display: none; } /* allows authors to do transitions if they want */
  • lightboxes are handled by the <dialog> being width:100%;height:100%; or some such
  • rely on CSS for all styling except positioning (for now)
  • dialog.showModal([anchor])
    • 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
    • push onto fullscreen stack
    • obtain a dialog::backdrop
      • 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
    • z-index: magic to keep on top of anything displayed before it
  • dialog.show([anchor]);
    • shows the dialog
  • dialogs can be opened without anchors
    • 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.
    • [let JS do this:] dialog can be drag moved which affects the left and top/right
  • dialogs opened with anchors
    • 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.close([returnValue]) sets dialog.returnValue if value is given, and closes the dialog
  • dialog.returnValue is a string
  • dialog.onclose event handler
  • <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

Other brainstorms

(Proposals for similar or related functionality found elsewhere.)