Skip to content

Commit 37774bb

Browse files
committed
Menu: new prototype for drilldown menu with keyboard handling
1 parent 27c5deb commit 37774bb

File tree

1 file changed

+235
-0
lines changed

1 file changed

+235
-0
lines changed

tests/visual/menu/drilldown2.html

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<title>Menu Visual Test: Default</title>
5+
<link rel="stylesheet" href="../visual.css" type="text/css" />
6+
<link rel="stylesheet" href="../../../themes/base/jquery.ui.all.css" type="text/css" title="ui-theme" />
7+
<script type="text/javascript" src="../../../jquery-1.4.2.js"></script>
8+
<script type="text/javascript" src="../../../ui/jquery.ui.core.js"></script>
9+
<script type="text/javascript" src="../../../ui/jquery.ui.widget.js"></script>
10+
<script type="text/javascript" src="../../../ui/jquery.ui.position.js"></script>
11+
<script type="text/javascript" src="../../../ui/jquery.ui.button.js"></script>
12+
<script type="text/javascript" src="../../../ui/jquery.ui.autocomplete.js"></script>
13+
<script type="text/javascript">
14+
$(function() {
15+
$.widget("ui.drilldown", {
16+
_init: function() {
17+
var self = this;
18+
this.active = this.element.find(">ul").attr("tabindex", 0);
19+
20+
// hide submenus and create indicator icons
21+
this.element.find("ul").hide().prev("a").prepend('<span class="ui-icon ui-icon-carat-1-e"></span>').end().filter(":first").show();
22+
23+
this.element.find("ul").menu({
24+
focus: function(event, ui) {
25+
self.activeItem = ui.item;
26+
},
27+
selected: function(event, ui) {
28+
if (this != self.active[0]) {
29+
return;
30+
}
31+
var nested = $(">ul", ui.item);
32+
if (nested.length) {
33+
self._open(nested);
34+
} else {
35+
self.element.find("h3").text(ui.item.text());
36+
self.options.selected.apply(this, arguments);
37+
}
38+
}
39+
});
40+
41+
this.back = this.element.children(":last").button({
42+
icons: {
43+
primary: "ui-icon-carat-1-w"
44+
}
45+
}).click(function() {
46+
self.up();
47+
return false;
48+
}).hide();
49+
},
50+
51+
_open: function(submenu) {
52+
this.active = submenu.show().css({
53+
top: 0,
54+
left: 0
55+
}).position({
56+
my: "left top",
57+
at: "left top",
58+
of: this.widget()
59+
});
60+
this.back.show();
61+
},
62+
63+
up: function() {
64+
if (this.active.parent()[0] == this.element[0]) {
65+
return;
66+
}
67+
this.active.hide();
68+
this.active = this.active.parent().parent().show();
69+
if (!this.active.parent().parent().is(":ui-menu")) {
70+
this.back.hide();
71+
}
72+
},
73+
74+
down: function(event) {
75+
var nested = this.activeItem.find(">ul");
76+
if (nested.length) {
77+
this._open(nested);
78+
nested.menu("activate", event, nested.children(":first"))
79+
}
80+
},
81+
82+
show: function() {
83+
},
84+
85+
hide: function() {
86+
},
87+
88+
widget: function() {
89+
return this.element.find(">ul");
90+
}
91+
});
92+
93+
var drilldown = $("#drilldown").drilldown({
94+
selected: function(event, ui) {
95+
$("#log").append("<div>Selected " + ui.item.text() + "</div>");
96+
}
97+
});
98+
99+
drilldown.drilldown("widget").keydown(function(event) {
100+
var menu = drilldown.data("drilldown").active.data("menu");
101+
if (menu.widget().is(":hidden"))
102+
return;
103+
event.stopPropagation();
104+
switch (event.keyCode) {
105+
case $.ui.keyCode.PAGE_UP:
106+
menu.previousPage();
107+
break;
108+
case $.ui.keyCode.PAGE_DOWN:
109+
menu.nextPage();
110+
break;
111+
case $.ui.keyCode.UP:
112+
menu.previous();
113+
break;
114+
case $.ui.keyCode.LEFT:
115+
drilldown.drilldown("up");
116+
break;
117+
case $.ui.keyCode.RIGHT:
118+
drilldown.drilldown("down");
119+
break;
120+
case $.ui.keyCode.DOWN:
121+
menu.next();
122+
event.preventDefault();
123+
break;
124+
case $.ui.keyCode.ENTER:
125+
case $.ui.keyCode.TAB:
126+
menu.select();
127+
drilldown.drilldown("hide");
128+
event.preventDefault();
129+
break;
130+
case $.ui.keyCode.ESCAPE:
131+
drilldown.drilldown("hide", event);
132+
break;
133+
default:
134+
clearTimeout(menu.filterTimer);
135+
var prev = menu.previousFilter || "";
136+
var character = String.fromCharCode(event.keyCode);
137+
var skip = false;
138+
if (character == prev) {
139+
skip = true;
140+
} else {
141+
character = prev + character;
142+
}
143+
144+
var match = menu.widget().children("li").filter(function() {
145+
return new RegExp("^" + character, "i").test($("a", this).text());
146+
});
147+
var match = skip && match.index(menu.active.next()) != -1 ? match.next() : match;
148+
if (!match.length) {
149+
character = String.fromCharCode(event.keyCode);
150+
match = menu.widget().children("li").filter(function() {
151+
return new RegExp("^" + character, "i").test($(this).text());
152+
});
153+
}
154+
if (match.length) {
155+
menu.activate(match);
156+
if (match.length > 1) {
157+
menu.previousFilter = character;
158+
menu.filterTimer = setTimeout(function() {
159+
delete menu.previousFilter;
160+
}, 1000);
161+
} else {
162+
delete menu.previousFilter;
163+
}
164+
} else {
165+
delete menu.previousFilter;
166+
}
167+
}
168+
});
169+
});
170+
</script>
171+
<style>
172+
body { font-size:62.5%; }
173+
.ui-menu { width: 200px; height: 170px; }
174+
.ui-menu .ui-menu { position: absolute; }
175+
.ui-menu .ui-icon { float: right; }
176+
</style>
177+
</head>
178+
<body>
179+
180+
<div id="drilldown">
181+
<h3>Make a selection...</h3>
182+
<ul>
183+
<li>
184+
<a href="#">Amsterdam</a>
185+
<ul>
186+
<li><a href="#">Aberdeen</a></li>
187+
<li><a href="#">Ada</a></li>
188+
<li>
189+
<a href="#">Adamsville</a>
190+
<ul>
191+
<li><a href="#">Anaheim</a></li>
192+
<li>
193+
<a href="#">Cologne</a>
194+
<ul>
195+
<li><a href="#">Mberdeen</a></li>
196+
<li><a href="#">Mda</a></li>
197+
<li><a href="#">Mdamsville</a></li>
198+
<li><a href="#">Mddyston</a></li>
199+
<li><a href="#">Mmesville</a></li>
200+
</ul>
201+
</li>
202+
<li><a href="#">Frankfurt</a></li>
203+
</ul>
204+
</li>
205+
<li><a href="#">Addyston</a></li>
206+
<li><a href="#">Amesville</a></li>
207+
</ul>
208+
</li>
209+
<li><a href="#">Anaheim</a></li>
210+
<li><a href="#">Cologne</a></li>
211+
<li><a href="#">Frankfurt</a></li>
212+
<li>
213+
<a href="#">Magdeburg</a>
214+
<ul>
215+
<li><a href="#">Mberdeen</a></li>
216+
<li><a href="#">Mda</a></li>
217+
<li><a href="#">Mdamsville</a></li>
218+
<li><a href="#">Mddyston</a></li>
219+
<li><a href="#">Mmesville</a></li>
220+
</ul>
221+
</li>
222+
<li><a href="#">Munich</a></li>
223+
<li><a href="#">Utrecht</a></li>
224+
<li><a href="#">Zurich</a></li>
225+
</ul>
226+
<a href="#">Go back</a>
227+
</div>
228+
229+
<div class="ui-widget" style="margin-top:2em; font-family:Arial">
230+
Log:
231+
<div id="log" style="height: 400px; width: 300px; overflow: auto;" class="ui-widget-content"></div>
232+
</div>
233+
234+
</body>
235+
</html>

0 commit comments

Comments
 (0)