ejemplo - Categoría de Autocompletar de jQuery UI Cómo saltar encabezados de categoría
jquery ui download (2)
Esta línea:
ul.append( "<li class=''ui-menu-item ui-category''>" + item.category + "</li>" );
está causando el problema
Internamente , el widget usa los elementos de la lista con un elemento ui-menu-item
class para distinguir si un li
es o no un elemento real del menú que se puede seleccionar. Cuando presiona la tecla ''abajo'', el widget encuentra el siguiente elemento con una clase ui-menu-item
y se mueve hacia él.
Elimine la clase y su código funciona como usted lo desea:
ul.append( "<li class=''ui-category''>" + item.category + "</li>" );
Aquí está funcionando:
Tengo un campo de autocompletar en funcionamiento en mi aplicación web y estoy buscando una manera de aumentar la usabilidad del campo omitiendo automáticamente los campos de categoría cuando se utiliza una tecla de flecha para desplazar hacia abajo las opciones disponibles (después de escribir un término de búsqueda parcial).
Por ejemplo, si un usuario comienza a escribir "an", el autocompletar mostrará dos categorías con elementos en cada uno. El usuario desea seleccionar uno de los elementos en la lista debajo de "Personas". Usan la tecla de flecha para moverse hacia abajo en la lista. Actualmente, este código inserta las categorías en los resultados como un elemento de la lista. Cuando utilice las teclas de flecha, debe moverlas para pasarlas a fin de resaltar y seleccionar un resultado. De cualquier forma, la aplicación podría omitir automáticamente los encabezados de categoría?
$.widget( "custom.catcomplete", $.ui.autocomplete, {
_renderMenu: function( ul, items ) {
var self = this,
currentCategory = "";
$.each( items, function( index, item ) {
if ( item.category != currentCategory ) {
ul.append( "<li class=''ui-menu-item ui-category''>" + item.category + "</li>" );
currentCategory = item.category;
}
self._renderItem( ul, item );
});
}
});
var data = [
{ label: "annk K12", category: "Products" },
{ label: "annttop C13", category: "Products" },
{ label: "anders andersson", category: "People" },
{ label: "andreas andersson", category: "People" },
{ label: "andreas johnson", category: "People" }
];
$( "#textfield" ).catcomplete({
source: data,
select: function(event, ui) {
window.location.hash = "id_"+escape(ui.item.id);
}
});
Como la respuesta aceptada no funciona en las últimas versiones de jQueryUI (> 1.10.4) publicaré mi hack, quizás alguien lo encuentre útil.
Estoy usando jQueryUI 1.12.0
Mientras agregué la categoría agregué una nueva clase, la llamé "categoryItem":
ul.append( "<li class=''ui-autocomplete-category categoryItem''>" + "Category" + "</li>" );
Algunas de las funciones de jQueryUI también deben ser reemplazadas para forzar a jquery a ignorar los elementos con la clase "categoryItem" (se cambian dos líneas).
$.widget("ui.menu", $.extend({}, $.ui.menu.prototype, {
refresh: function() {
var menus, items, newSubmenus, newItems, newWrappers,
that = this,
icon = this.options.icons.submenu,
submenus = this.element.find( this.options.menus );
this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length );
// Initialize nested menus
newSubmenus = submenus.filter( ":not(.ui-menu)" )
.hide()
.attr( {
role: this.options.role,
"aria-hidden": "true",
"aria-expanded": "false"
} )
.each( function() {
var menu = $( this ),
item = menu.prev(),
submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true );
that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon );
item
.attr( "aria-haspopup", "true" )
.prepend( submenuCaret );
menu.attr( "aria-labelledby", item.attr( "id" ) );
} );
this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" );
menus = submenus.add( this.element );
items = menus.find( this.options.items );
// Initialize menu-items containing spaces and/or dashes only as dividers
items.not( ".ui-menu-item" ).each( function() {
var item = $( this );
if ( that._isDivider( item ) ) {
that._addClass( item, "ui-menu-divider", "ui-widget-content" );
}
} );
// Don''t refresh list items that are already adapted
newItems = items.not( ".ui-menu-item, .ui-menu-divider" ).not(".categoryItem");
newWrappers = newItems.children()
.not( ".ui-menu" )
.uniqueId()
.attr( {
tabIndex: -1,
role: this._itemRole()
} );
this._addClass( newItems, "ui-menu-item" )
._addClass( newWrappers, "ui-menu-item-wrapper" );
// Add aria-disabled attribute to any disabled menu item
items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
// If the active item has been removed, blur the menu
if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
this.blur();
}
},
_move: function( direction, filter, event ) {
var next;
if ( this.active ) {
if ( direction === "first" || direction === "last" ) {
next = this.active
[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
.eq( -1 );
} else {
next = this.active
[ direction + "All" ]( ".ui-menu-item" )
.eq( 0 );
}
}
if ( !next || !next.length || !this.active ) {
next = this.activeMenu.find( this.options.items ).not(".categoryItem")[ filter ]();
}
this.focus( event, next );
}
}));