<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();
--- /dev/null
+/*
+ * 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));
<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>
});
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;
}