Skip to content

Commit 6222205

Browse files
committed
decoupled ui.menu and ui.autocomplete
1 parent 7f4619a commit 6222205

File tree

3 files changed

+232
-30
lines changed

3 files changed

+232
-30
lines changed
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<title>jQuery UI Autocomplete - Categories</title>
6+
<link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">
7+
<script src="../../jquery-1.5.1.js"></script>
8+
<script src="../../ui/jquery.ui.core.js"></script>
9+
<script src="../../ui/jquery.ui.widget.js"></script>
10+
<script src="../../ui/jquery.ui.position.js"></script>
11+
<script src="../../ui/jquery.ui.menu.js"></script>
12+
<script src="../../ui/jquery.ui.autocomplete.js"></script>
13+
<link rel="stylesheet" href="../demos.css">
14+
<style>
15+
16+
.ui-autocomplete-table {
17+
border-spacing: 0;
18+
}
19+
20+
.ui-autocomplete-table td, .ui-autocomplete-table th {
21+
padding: 0;
22+
border: 0 none;
23+
}
24+
25+
.ui-autocomplete-category {
26+
vertical-align: top;
27+
}
28+
29+
.ui-autocomplete-category h3 {
30+
color: #aaa;
31+
font-size: 100%;
32+
font-weight: normal;
33+
34+
text-align: right;
35+
margin: 0;
36+
37+
/* same as .ui-menu-item a */
38+
padding: .2em .4em;
39+
line-height: 1.5;
40+
}
41+
42+
.ui-autocomplete-category th {
43+
border-right: 1px solid #ddd;
44+
}
45+
46+
.ui-autocomplete-category td {
47+
background-color: #fbfbfb;
48+
border-top: 1px solid #ddd;
49+
}
50+
51+
.ui-autocomplete-category:first-child td {
52+
border-top: 0 none;
53+
}
54+
55+
.ui-autocomplete-category:nth-child(2n) td {
56+
background-color: #f4f4f4;
57+
}
58+
59+
.ui-autocomplete-category ul {
60+
list-style: none;
61+
padding: 0;
62+
margin: 0;
63+
}
64+
65+
.ui-autocomplete-category td img {
66+
border: 1px solid #fff;
67+
outline: 1px solid #ddd;
68+
margin-right: .4em;
69+
vertical-align: top;
70+
}
71+
</style>
72+
<script>
73+
$.widget( "custom.catmenu", $.ui.menu, {
74+
_findSubmenus: function() {
75+
return $([]);
76+
},
77+
_findNewItems: function(root) {
78+
return root.find( "li:not(.ui-menu-item)" );
79+
},
80+
_menuItems: function(menu) {
81+
return menu.find("ul").children(".ui-menu-item");
82+
},
83+
_prevItems: function() {
84+
var previous = this.active.prevAll(".ui-menu-item")
85+
.add(
86+
this.active
87+
.closest(".ui-autocomplete-category")
88+
.prevAll(".ui-autocomplete-category")
89+
.find(".ui-menu-item"));
90+
91+
// HACK: $.fn.add sorts by DOM-order, but not on .add([])
92+
// so we re-sort it using $.unique
93+
return $($.unique(previous).get().reverse());
94+
},
95+
_nextItems: function() {
96+
return this.active.nextAll(".ui-menu-item")
97+
.add(
98+
this.active
99+
.closest(".ui-autocomplete-category")
100+
.nextAll(".ui-autocomplete-category")
101+
.find(".ui-menu-item"));
102+
}
103+
});
104+
105+
$.widget( "custom.catcomplete", $.ui.autocomplete, {
106+
menuWidget: "catmenu",
107+
menuRoot: "<div></div>",
108+
109+
_renderItem: function( ul, item ) {
110+
var listItem = $( "<li></li>" )
111+
.data( "item.autocomplete", item )
112+
.append( $( "<a></a>" ).text( item.label ) )
113+
.appendTo( ul );
114+
115+
if( item.category == "Artists" ) {
116+
listItem.find('a').prepend("<img src='http://dummyimage.com/40x30/09f/fff&text=x' width='40' />");
117+
} else if (item.category == "Albums") {
118+
listItem.find('a').prepend("<img src='http://dummyimage.com/40x40/f90/fff&text=a' width='40' />");
119+
}
120+
121+
return listItem;
122+
},
123+
124+
_renderMenu: function( ul, items ) {
125+
var self = this,
126+
currentCategory = "",
127+
categoryList = null;
128+
129+
var table = $("<table class='ui-autocomplete-table'></table>").appendTo(ul);
130+
131+
$.each( items, function( index, item ) {
132+
if ( item.category != currentCategory ) {
133+
var src = "<tr class='ui-autocomplete-category'><th><h3></h3></th><td><ul></ul></td></tr>";
134+
categoryList = $(src).appendTo(table)
135+
.find('h3')
136+
.text(item.category)
137+
.end()
138+
.find('ul');
139+
currentCategory = item.category;
140+
}
141+
self._renderItem( categoryList, item );
142+
});
143+
}
144+
});
145+
</script>
146+
<script>
147+
$(function() {
148+
var data = [
149+
{ label: "anders", category: "Artists" },
150+
{ label: "andreas", category: "Artists" },
151+
{ label: "antal", category: "Artists" },
152+
{ label: "radio - anders", category: "Albums" },
153+
{ label: "drummer - another beat", category: "Albums" },
154+
{ label: "singer - antal", category: "Albums" },
155+
{ label: "andere musik", category: "Tags" },
156+
{ label: "standup", category: "Tags" }
157+
];
158+
159+
$( "#search" ).catcomplete({
160+
delay: 0,
161+
source: data
162+
});
163+
});
164+
</script>
165+
</head>
166+
<body>
167+
168+
<div class="demo">
169+
<label for="search">Search: </label>
170+
<input id="search" />
171+
</div><!-- End demo -->
172+
173+
174+
175+
<div class="demo-description">
176+
<p>A categorized search result. Try typing "a" or "n".</p>
177+
</div><!-- End demo-description -->
178+
179+
</body>
180+
</html>

ui/jquery.ui.autocomplete.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ $.widget( "ui.autocomplete", {
3434
},
3535

3636
pending: 0,
37+
menuWidget: "menu",
38+
menuRoot: "<ul></ul>",
3739

3840
_create: function() {
3941
var self = this,
@@ -138,7 +140,7 @@ $.widget( "ui.autocomplete", {
138140
this.response = function() {
139141
return self._response.apply( self, arguments );
140142
};
141-
this.menu = $( "<ul></ul>" )
143+
this.menu = $( this.menuRoot )
142144
.addClass( "ui-autocomplete" )
143145
.appendTo( $( this.options.appendTo || "body", doc )[0] )
144146
// prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
@@ -165,7 +167,7 @@ $.widget( "ui.autocomplete", {
165167
clearTimeout( self.closing );
166168
}, 13);
167169
})
168-
.menu({
170+
[this.menuWidget]({
169171
// custom key handling for now
170172
input: $(),
171173
focus: function( event, ui ) {
@@ -215,7 +217,7 @@ $.widget( "ui.autocomplete", {
215217
})
216218
.zIndex( this.element.zIndex() + 1 )
217219
.hide()
218-
.data( "menu" );
220+
.data( this.menuWidget );
219221
if ( $.fn.bgiframe ) {
220222
this.menu.element.bgiframe();
221223
}

0 commit comments

Comments
 (0)