]> source.dussan.org Git - jquery-ui.git/commitdiff
Menu: Overhauled nested menu via flyoutmenu.js backported from Michael
authorjzaefferer <joern.zaefferer@gmail.com>
Tue, 22 Feb 2011 10:51:08 +0000 (11:51 +0100)
committerjzaefferer <joern.zaefferer@gmail.com>
Tue, 22 Feb 2011 10:51:08 +0000 (11:51 +0100)
Lang's fork. Changed key input handling by setting focus to menu,
getting rid of input option.

tests/visual/menu/contextmenu.html
tests/visual/menu/flyoutmenu.js [new file with mode: 0644]
tests/visual/menu/nested.html
ui/jquery.ui.menu.js

index 513deb2f781fff23f3a683544157a436d84264d8..68fdd5234bac1b7a1f71cff1ae3dfca6f83c320b 100644 (file)
@@ -9,7 +9,9 @@
        <script type="text/javascript" src="../../../ui/jquery.ui.widget.js"></script>
        <script type="text/javascript" src="../../../ui/jquery.ui.position.js"></script>
        <script type="text/javascript" src="../../../ui/jquery.ui.menu.js"></script>
+       <!--
        <script type="text/javascript" src="http://jqueryui.com/themeroller/themeswitchertool/"></script>
+       -->
        <script type="text/javascript">
        $(function() {
                $.fn.themeswitcher && $('<div/>').css({
                $("button").each(function() {
                        $(this).next().menu({
                                select: function(event, ui) {
-                                       $(this).hide();
+                                       $(this).hide().prev().focus();
                                        $("#log").append("<div>Selected " + ui.item.text() + "</div>");
-                               },
-                               input: $(this)
+                               }
                        }).hide();
                }).click(function(event) {
                        // TODO required to prevent the click handler below from handling this event
                                my: "left top",
                                at: "right top",
                                of: event.pageX > 0 ? event : this
-                       });
+                       }).focus();
                        $(document).one("click", function() {
                                menu.hide();
                        })
-               }).keydown(function(event) {
-                       var menu = $("#menu" + this.id).data("menu");
+               }).next().keydown(function(event) {
+                       var menu = $(this).data("menu");
                        if (menu.widget().is(":hidden"))
                                return;
                        event.stopPropagation();
diff --git a/tests/visual/menu/flyoutmenu.js b/tests/visual/menu/flyoutmenu.js
new file mode 100644 (file)
index 0000000..0485440
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * jQuery UI flyout menu
+ *   - written for jQuery UI 1.9 milestone 2 using the widget factory
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * modified from: http://view.jqueryui.com/menu/tests/visual/menu/nested.html
+ *     by: Michael Lang, http://nexul.com/
+ *
+ */
+(function($) {
+
+$.widget("ui.flyoutmenu", {
+       _create: function() {
+               var self = this;
+               this.active = this.element;
+               this.activeItem = this.element.children("li").first();
+               // hide submenus and create indicator icons
+               this.element.find("ul").addClass("ui-menu-flyout").hide().prev("a").prepend('<span class="ui-icon ui-icon-carat-1-e"></span>');
+               
+               this.element.find("ul").andSelf().menu({
+                       select: function(event) {
+                               self._select(event);
+                       },
+                       focus: function(event, ui) {
+                               self.active = ui.item.parent();
+                               self.activeItem = ui.item;
+                               ui.item.parent().find("ul").hide();
+                               var nested = $(">ul", ui.item);
+                               if (nested.length && event.originalEvent && /^mouse/.test(event.originalEvent.type)) {
+                                       self._open(nested);
+                               }
+                       }
+               }).keydown(function(event) {
+                       if (self.element.is(":hidden")) 
+                               return;
+                       event.stopPropagation();
+                       switch (event.keyCode) {
+                       case $.ui.keyCode.LEFT:
+                               self.left(event);
+                               event.preventDefault();
+                               break;
+                       case $.ui.keyCode.RIGHT:
+                               self.right(event);
+                               event.preventDefault();
+                               break;
+                       case $.ui.keyCode.ESCAPE:
+                               self.hide();
+                               break;
+                       default:
+                               clearTimeout(self.filterTimer);
+                               var prev = self.previousFilter || "";
+                               var character = String.fromCharCode(event.keyCode);
+                               var skip = false;
+                               if (character == prev) {
+                                       skip = true;
+                               } else {
+                                       character = prev + character;
+                               }
+                               
+                               var match = self.activeItem.parent("ul").children("li").filter(function() {
+                                       return new RegExp("^" + character, "i").test($("a", this).text());
+                               });
+                               var match = skip && match.index(self.active.next()) != -1 ? match.next() : match;
+                               if (!match.length) {
+                                       character = String.fromCharCode(event.keyCode);
+                                       match = self.widget().children("li").filter(function() {
+                                               return new RegExp("^" + character, "i").test($(this).text());
+                                       });
+                               }
+                               if (match.length) {
+                                       self.activate(event, match);
+                                       if (match.length > 1) {
+                                               self.previousFilter = character;
+                                               self.filterTimer = setTimeout(function() {
+                                                       delete self.previousFilter;
+                                               }, 1000);
+                                       } else {
+                                               delete self.previousFilter;
+                                       }
+                               } else {
+                                       delete self.previousFilter;
+                               }
+                       }
+               });
+       },
+       _open: function(submenu) {
+               // TODO restrict to widget
+               //only one menu can have items open at a time.
+               $(document).find(".ui-menu-flyout").not(submenu.parents()).hide();
+               submenu.show().css({
+                       top: 0,
+                       left: 0
+               }).position({
+                       my: "left top",
+                       at: "right top",
+                       of: this.activeItem
+               });
+               $(document).one("click", function() {
+                       //clicking outside menu flyouts should close all flyouts
+                       //$(document).find(".ui-menu-flyout").hide();
+               })
+       },
+       _select: function(event) {
+               event.stopPropagation();
+               // TODO make _select cancelable?
+               this._trigger( "select", event, { item: this.activeItem } );
+               //this.activate(event, this.element.children("li").first());
+               this.hide();
+       },
+       left: function(event) {
+               var newItem = this.activeItem.parents("li").first();
+               if (newItem.length) {
+                       this.activate(event, newItem);
+               }
+       },
+       right: function(event) {
+               var newItem = this.activeItem.children("ul").children("li").first();
+               if (newItem.length) {
+                       this._open(newItem.parent());
+                       this.activate(event, newItem);
+               }
+       },
+       activate: function(event, item) {
+               if (item) {
+                       item.parent().data("menu").widget().show();
+                       item.parent().data("menu").activate(event, item);
+               }
+               this.activeItem = item;
+               this.active = item.parent("ul")
+               this.active.focus();
+       },
+       show: function() {
+               this.active = this.element;
+               this.element.show();
+               if (this.element.hasClass("ui-menu-flyout")) {
+                       $(document).one("click", function() {
+                               //clicking outside menu flyouts should close all flyouts
+                               //$(document).find(".ui-menu-flyout").hide();
+                       })
+               }
+       },
+       hide: function() {
+               this.activeItem = this.element.children("li").first();
+               this.element.find("ul").andSelf().menu("deactivate").hide();
+       }
+});
+
+}(jQuery));
index 2508c55c4d4fcfaeef88d5c5bbd7e3ee75a67bb7..8240689df3307687d961b43c70011db17f5b0e73 100644 (file)
@@ -9,8 +9,11 @@
        <script type="text/javascript" src="../../../ui/jquery.ui.widget.js"></script>
        <script type="text/javascript" src="../../../ui/jquery.ui.position.js"></script>
        <script type="text/javascript" src="../../../ui/jquery.ui.menu.js"></script>
-       <script type="text/javascript" src="../../../external/jquery.bgiframe-2.1.1.js"></script>
+       <script type="text/javascript" src="../../../external/jquery.bgiframe-2.1.2.js"></script>
+       <script type="text/javascript" src="flyoutmenu.js"></script>
+       <!--
        <script type="text/javascript" src="http://jqueryui.com/themeroller/themeswitchertool/"></script>
+       -->
        <script type="text/javascript">
        $(function() {
                $.fn.themeswitcher && $('<div/>').css({
                        top: 10
                }).appendTo(document.body).themeswitcher();
                
-               $.widget("ui.nestedmenu", {
-                       _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>');    
-                               
-                               this.element.find("ul").andSelf().menu({
-                                       // disable built-in key handling
-                                       input: $(),
-                                       select: this.options.select,
-                                       focus: function(event, ui) {
-                                               self.active = ui.item.parent();
-                                               self.activeItem = ui.item;
-                                               ui.item.parent().find("ul").hide();
-                                               var nested = $(">ul", ui.item);
-                                               if (nested.length && /^mouse/.test(event.originalEvent.type)) {
-                                                       self._open(nested);
-                                               }
-                                       }
-                               })
-                       },
-                       
-                       _open: function(submenu) {
-                               submenu.show().css({
-                                       top: 0,
-                                       left: 0
-                               }).position({
-                                       my: "left top",
-                                       at: "right top",
-                                       of: this.activeItem
-                               });
-                       },
-                       
-                       up: function(event) {
-                               this.active = this.active.menu("deactivate").hide().parent().parent();
-                               this.activeItem = this.active.data("menu").active;
-                       },
-                       
-                       down: function(event) {
-                               var submenu = $(">ul", this.activeItem);
-                               this._open(submenu, this.activeItem);
-                               submenu.menu("activate", event, submenu.children(":first"));
-                       },
-                       
-                       show: function() {
-                               this.active = this.element;
-                               this.element.show();
-                       },
-                       
-                       hide: function() {
-                               this.element.find("ul").andSelf().menu("deactivate").hide();
-                       }
-                       
-               });
+               var menu = $("#menu");
                
-               var nestedmenu = $("#menu").nestedmenu({
-                       select: function(event, ui) {
-                               $("#log").append("<div>Selected " + ui.item.text() + "</div>");
-                       }
-               }).hide();
-               
-               $("button").click(function(event) {
+               var button = $("button").click(function(event) {
                        // TODO required to prevent the click handler below from handling this event
                        event.stopPropagation();
-                       nestedmenu.nestedmenu("show")
+                       menu.flyoutmenu("show")
+                               //.attr("tabIndex", 0)
+                               .focus()
                                .css({
                                        top: 0,
                                        left: 0
                                        of: this
                                });
                        $(document).one("click", function() {
-                               nestedmenu.nestedmenu("hide");
-                       })
-               }).keydown(function(event) {
-                       var menu = nestedmenu.data("nestedmenu").active.data("menu");
-                       if (menu.widget().is(":hidden"))
-                               return;
-                       event.stopPropagation();
-                       switch (event.keyCode) {
-                       case $.ui.keyCode.PAGE_UP:
-                               menu.previousPage(event);
-                               break;
-                       case $.ui.keyCode.PAGE_DOWN:
-                               menu.nextPage(event);
-                               break;
-                       case $.ui.keyCode.UP:
-                               menu.previous(event);
-                               break;
-                       case $.ui.keyCode.LEFT:
-                               nestedmenu.nestedmenu("up", event);
-                               break;
-                       case $.ui.keyCode.RIGHT:
-                               nestedmenu.nestedmenu("down", event);
-                               break;
-                       case $.ui.keyCode.DOWN:
-                               menu.next(event);
-                               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(event, match);
-                                       if (match.length > 1) {
-                                               menu.previousFilter = character;
-                                               menu.filterTimer = setTimeout(function() {
-                                                       delete menu.previousFilter;
-                                               }, 1000);
-                                       } else {
-                                               delete menu.previousFilter;
-                                       }
-                               } else {
-                                       delete menu.previousFilter;
-                               }
-                       }
+                               menu.flyoutmenu("hide");
+                       });
                });
+
+               menu.flyoutmenu({
+                       //input: button,
+                       select: function(event, ui) {
+                               $("#log").append("<div>Selected " + ui.item.children("a").text() + "</div>");
+                               button.focus();
+                       }
+               }).hide();
        });
        </script>
        <style>
index 8cf8886d842fd1498f39d12dcb66d05486ab1725..c6c557134d80483100421b4579426ad1a27ff8c4 100644 (file)
@@ -57,10 +57,7 @@ $.widget("ui.menu", {
                        });
                this.refresh();
                
-               if ( !this.options.input ) {
-                       this.options.input = this.element.attr( "tabIndex", 0 );
-               }
-               this.options.input.bind( "keydown.menu", function( event ) {
+               this.element.attr( "tabIndex", 0 ).bind( "keydown.menu", function( event ) {
                        if ( self.options.disabled ) {
                                return;
                        }