r3449 committed - menu: drilldown, first draft

r3449 committed - menu: drilldown, first draft


Revision: 3449
Author: joern.zaefferer
Date: Fri Nov 13 08:55:54 2009
Log: menu: drilldown, first draft
http://code.google.com/p/jquery-ui/source/detail?r=3449
Added:
/branches/dev/tests/visual/menu/drilldown.html
=======================================
--- /dev/null
+++ /branches/dev/tests/visual/menu/drilldown.html    Fri Nov 13 08:55:54 2009
@@ -0,0 +1,229 @@
+<!doctype html>
+<html>
+<head>
+    <title>Menu Visual Test: Default</title>
+    <link rel="stylesheet" href="../static.css" type="text/css" />
+    <link rel="stylesheet" href="../../../themes/base/ui.base.css"
type="text/css" />
+    <link rel="stylesheet" href="../../../themes/base/ui.theme.css"
type="text/css" title="ui-theme" />
+    <script type="text/javascript" src="../../../jquery-1.3.2.js"></script>
+    <script type="text/javascript"
src="../../../ui/jquery.ui.core.js"></script>
+    <script type="text/javascript"
src="../../../ui/jquery.ui.menu.js"></script>
+    <script type="text/javascript"
src="../../../ui/jquery.ui.position.js"></script>
+    <script type="text/javascript">
+    $(function() {
+        $.widget("ui.drilldown", {
+            _init: function() {
+                var self = this;
+                this.active = this.element;
+
+                // hide submenus and create indicator icons
+                this.element.find("ul").hide().prev("a").prepend('<span class="ui-icon
ui-icon-carat-1-e"></span>').end().filter(":first").show();
+
+                this.element.find("ul").menu({
+                    selected: function(event, ui) {
+                        self.element.find("h3").text(ui.item.text());
+                        self.options.selected.apply(this, arguments);
+                    },
+                    focus: function(event, ui) {
+                        self.active = ui.item.parent();
+                        // put a previous submenu back into its place and hide it
+                        self.hideDown();
+                        var nested = $(">ul", ui.item);
+                        if (nested.length) {
+                            // append to body in order to display the submenu above the parent
menu, instead of inside of it
+                            nested.appendTo(document.body).menu("deactivate").show().position({
+                                my: "left top",
+                                at: "right top",
+                                of: ui.item
+                            // store the current submenu
+                            }).data("menuparent", ui.item);
+
+                            self.active.data("submenu", nested);
+                        }
+                    }
+                })
+            },
+
+            up: function() {
+                if (!this.active.data("menuparent"))
+                    return;
+                this.hideDown();
+                this.active.menu("deactivate");
+                this.active = this.active.data("menuparent").parent();
+            },
+
+            down: function() {
+                var submenu = this.active.data("submenu");
+                if (!submenu)
+                    return;
+                submenu.data("menu").activate(submenu.children(":first"))
+                this.active = submenu;
+            },
+
+            show: function() {
+                this.element.menu("deactivate").show();
+                this.active = this.element;
+            },
+
+            hide: function() {
+                this.hideDown();
+                var child = this.active.hide(), parent;
+                while(child.data("menuparent")) {
+                    parent = child.data("menuparent");
+                    child.appendTo(parent).removeData("menuparent");
+                    child = parent.parent().removeData("submenu").hide();
+                }
+            },
+
+            hideDown: function() {
+                var submenu = this.active.data("submenu");
+                while(submenu) {
+                    var parent = submenu.data("menuparent");
+                    submenu.appendTo(parent).hide().removeData("menuparent");
+                    parent.parent().removeData("submenu");
+                    submenu = submenu.data("submenu");
+                };
+            }
+        });
+
+        var nestedmenu = $("#drilldown").drilldown({
+            selected: function(event, ui) {
+                $("#log").append("<div>Selected " + ui.item.text() + "</div>");
+            }
+        });
+
+        $().keydown(function(event) {
+            var menu = nestedmenu.data("drilldown").active.data("menu");
+            if (menu.widget().is(":hidden"))
+                return;
+            event.stopPropagation();
+            switch (event.keyCode) {
+            case $.ui.keyCode.PAGE_UP:
+                menu.previousPage();
+                break;
+            case $.ui.keyCode.PAGE_DOWN:
+                menu.nextPage();
+                break;
+            case $.ui.keyCode.UP:
+                menu.previous();
+                break;
+            case $.ui.keyCode.LEFT:
+                nestedmenu.nestedmenu("up");
+                break;
+            case $.ui.keyCode.RIGHT:
+                nestedmenu.nestedmenu("down");
+                break;
+            case $.ui.keyCode.DOWN:
+                menu.next();
+                event.preventDefault();
+                break;
+            case $.ui.keyCode.ENTER:
+            case $.ui.keyCode.TAB:
+                menu.select();
+                nestedmenu.nestedmenu("hide");
+                event.preventDefault();
+                break;
+            case $.ui.keyCode.ESCAPE:
+                nestedmenu.nestedmenu("hide");
+                break;
+            default:
+                clearTimeout(menu.filterTimer);
+                var prev = menu.previousFilter || "";
+                var character = String.fromCharCode(event.keyCode);
+                var skip = false;
+                if (character == prev) {
+                    skip = true;
+                } else {
+                    character = prev + character;
+                }
+
+                var match = menu.widget().children("li").filter(function() {
+                    return new RegExp("^" + character, "i").test($("a", this).text());
+                });
+                var match = skip && match.index(menu.active.next()) != -1 ?
match.next() : match;
+                if (!match.length) {
+                    character = String.fromCharCode(event.keyCode);
+                    match = menu.widget().children("li").filter(function() {
+                        return new RegExp("^" + character, "i").test($(this).text());
+                    });
+                }
+                if (match.length) {
+                    menu.activate(match);
+                    if (match.length > 1) {
+                        menu.previousFilter = character;
+                        menu.filterTimer = setTimeout(function() {
+                            delete menu.previousFilter;
+                        }, 1000);
+                    } else {
+                        delete menu.previousFilter;
+                    }
+                } else {
+                    delete menu.previousFilter;
+                }
+            }
+        });
+    });
+    </script>
+    <style>
+        body { font-size:62.5%; }
+        #drilldown { width: 200px; }
+        .ui-menu .ui-icon { float: right; }
+    </style>
+</head>
+<body>
+
+<div id="drilldown">
+    <h3>Make a selection...</h3>
+    <ul>
+        <li>
+            <a href="#">Amsterdam</a>
+            <ul>
+                <li><a href="#">Aberdeen</a></li>
+                <li><a href="#">Ada</a></li>
+                <li>
+                    <a href="#">Adamsville</a>
+                    <ul>
+                        <li><a href="#">Anaheim</a></li>
+                        <li>
+                            <a href="#">Cologne</a>
+                            <ul>
+                                <li><a href="#">Mberdeen</a></li>
+                                <li><a href="#">Mda</a></li>
+                                <li><a href="#">Mdamsville</a></li>
+                                <li><a href="#">Mddyston</a></li>
+                                <li><a href="#">Mmesville</a></li>
+                            </ul>
+                        </li>
+                        <li><a href="#">Frankfurt</a></li>
+                    </ul>
+                </li>
+                <li><a href="#">Addyston</a></li>
+                <li><a href="#">Amesville</a></li>
+            </ul>
+        </li>
+        <li><a href="#">Anaheim</a></li>
+        <li><a href="#">Cologne</a></li>
+        <li><a href="#">Frankfurt</a></li>
+        <li>
+            <a href="#">Magdeburg</a>
+            <ul>
+                <li><a href="#">Mberdeen</a></li>
+                <li><a href="#">Mda</a></li>
+                <li><a href="#">Mdamsville</a></li>
+                <li><a href="#">Mddyston</a></li>
+                <li><a href="#">Mmesville</a></li>
+            </ul>
+        </li>
+        <li><a href="#">Munich</a></li>
+        <li><a href="#">Utrecht</a></li>
+        <li><a href="#">Zurich</a></li>
+    </ul>
+</div>
+
+<div class="ui-widget" style="margin-top:2em; font-family:Arial">
+    Log:
+    <div id="log" style="height: 400px; width: 300px; overflow: auto;"
class="ui-widget-content"></div>
+</div>
+
+</body>
+</html>