From 9c9425ac48378d7357caebdf52fb2ec98e069b8b Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sun, 31 Jul 2011 23:40:42 +0200 Subject: [PATCH] fixed: optimize element creation fixed: wrapper element is now fixed, fixes: https://github.com/fnagel/jquery-ui/issues/80 --- themes/base/jquery.ui.selectmenu.css | 3 +- ui/jquery.ui.selectmenu.js | 101 +++++++++++++++------------ 2 files changed, 57 insertions(+), 47 deletions(-) diff --git a/themes/base/jquery.ui.selectmenu.css b/themes/base/jquery.ui.selectmenu.css index 7f1b42fec..829401939 100644 --- a/themes/base/jquery.ui.selectmenu.css +++ b/themes/base/jquery.ui.selectmenu.css @@ -2,7 +2,8 @@ ----------------------------------*/ .ui-selectmenu { display: block; display: inline-block; position: relative; height: 2.2em; vertical-align: middle; text-decoration: none; overflow: hidden; zoom: 1; } .ui-selectmenu-icon { position:absolute; right:6px; margin-top:-8px; top: 50%; } -.ui-selectmenu-menu { padding:0; margin:0; list-style:none; position:absolute; top: 0; display: none; overflow: auto; z-index: 1005;} /* z-index: 1005 to make selectmenu work with dialog */ +.ui-selectmenu-menu { padding:0; margin:0; position:absolute; display: none; z-index: 1005;} /* z-index: 1005 to make selectmenu work with dialog */ +.ui-selectmenu-menu ul { padding:0; margin:0; list-style:none; position: relative; overflow: auto; overflow-y: auto ; overflow-x: hidden; } .ui-selectmenu-open { display: block; } .ui-selectmenu-menu-popup { margin-top: -1px; } .ui-selectmenu-menu-dropdown { } diff --git a/ui/jquery.ui.selectmenu.js b/ui/jquery.ui.selectmenu.js index 7c9818597..58d480a08 100644 --- a/ui/jquery.ui.selectmenu.js +++ b/ui/jquery.ui.selectmenu.js @@ -31,7 +31,7 @@ $.widget("ui.selectmenu", { icons: null, format: null, bgImage: function() {}, - wrapperElement: "" + wrapperElement: "
" }, _create: function() { @@ -47,25 +47,34 @@ $.widget("ui.selectmenu", { this._safemouseup = true; // create menu button wrapper - this.newelement = $('') - .insertAfter(this.element); - this.newelement.wrap(o.wrapperElement); - + this.newelement = $( '', { + 'class': this.widgetBaseClass + ' ui-widget ui-state-default ui-corner-all', + 'id' : this.ids[0], + 'role': 'button', + 'href': '#', + 'tabindex': '0' , + 'aria-haspopup': true, + 'aria-owns': this.ids[1] + }); + this.newelementWrap = $( o.wrapperElement ) + .append( this.newelement ) + .insertAfter( this.element ); + // transfer tabindex - var tabindex = this.element.attr('tabindex'); + var tabindex = this.element.attr( 'tabindex' ); if (tabindex) { - this.newelement.attr('tabindex', tabindex); + this.newelement.attr( 'tabindex', tabindex ); } // save reference to select in data for ease in calling methods - this.newelement.data('selectelement', this.element); + this.newelement.data( 'selectelement', this.element ); // menu icon - this.selectmenuIcon = $('') - .prependTo(this.newelement); + this.selectmenuIcon = $( '' ) + .prependTo( this.newelement ); // append status span to button - this.newelement.prepend(''); + this.newelement.prepend( '' ); // make associated form label trigger focus $( 'label[for="' + selectmenuId + '"]' ) @@ -169,10 +178,19 @@ $.widget("ui.selectmenu", { // hide original selectmenu element this.element.hide(); - // create menu portion, append to body - this.list = $('').appendTo('body'); - this.list.wrap(o.wrapperElement); - + // create menu portion, append to body + this.list = $( '
    ', { + 'class': 'ui-widget ui-widget-content', + 'aria-hidden': true, + 'role': 'listbox', + 'aria-labelledby': this.ids[0], + 'id': this.ids[1] + }); + this.listWrap = $( o.wrapperElement ) + .addClass( self.widgetBaseClass + '-menu' ) + .append( this.list ) + .appendTo( 'body' ); + // transfer menu click to menu button this.list .bind("keydown.selectmenu", function(event) { @@ -372,13 +390,13 @@ $.widget("ui.selectmenu", { // reset height to auto this.list.css("height", "auto"); - var listH = this.list.height(); + var listH = this.listWrap.height(); // calculate default max height - if ( o.maxHeight && o.maxHeight < listH) { + if ( o.maxHeight && o.maxHeight < listH ) { this.list.height( o.maxHeight ); } else { var winH = $( window ).height() / 3; - if ( winH < listH ) this.list.height( winH ); + if ( winH < listH ) this.list.height( winH ); } // save reference to actionable li's (not group label li's) @@ -413,14 +431,10 @@ $.widget("ui.selectmenu", { $( 'label[for=' + this.newelement.attr('id') + ']' ) .attr( 'for', this.element.attr( 'id' ) ) .unbind( '.selectmenu' ); - - if ( this.options.wrapperElement ) { - this.newelement.find( this.options.wrapperElement ).remove(); - this.list.find( this.options.wrapperElement ).remove(); - } else { - this.newelement.remove(); - this.list.remove(); - } + + this.newelementWrap.remove(); + this.listWrap.remove(); + this.element.show(); // call widget destroy function @@ -496,29 +510,25 @@ $.widget("ui.selectmenu", { }, open: function(event) { - var self = this; - if ( this.newelement.attr("aria-disabled") != 'true' ) { - this._closeOthers(event); - this.newelement + var self = this, o = this.options; + if ( self.newelement.attr("aria-disabled") != 'true' ) { + self._closeOthers(event); + self.newelement .addClass('ui-state-active'); - if (self.options.wrapperElement) { - this.list.parent().appendTo('body'); - } else { - this.list.appendTo('body'); - } + + self.listWrap.appendTo( o.appendTo ); - this.list.addClass(self.widgetBaseClass + '-open') - .attr('aria-hidden', false); + self.listWrap.addClass( self.widgetBaseClass + '-open' ); - selected = this.list.find('li:not(.' + self.widgetBaseClass + '-group):eq(' + this._selectedIndex() + ') a'); + selected = self.list.attr('aria-hidden', false).find('li:not(.' + self.widgetBaseClass + '-group):eq(' + self._selectedIndex() + ') a'); if (selected.length) selected[0].focus(); - if ( this.options.style == "dropdown" ) { - this.newelement.removeClass('ui-corner-all').addClass('ui-corner-top'); + if ( o.style == "dropdown" ) { + self.newelement.removeClass('ui-corner-all').addClass('ui-corner-top'); } - this._refreshPosition(); - this._trigger("open", event, this._uiHash()); + self._refreshPosition(); + self._trigger("open", event, self._uiHash()); } }, @@ -526,9 +536,8 @@ $.widget("ui.selectmenu", { if ( this.newelement.is('.ui-state-active') ) { this.newelement .removeClass('ui-state-active'); - this.list - .attr('aria-hidden', true) - .removeClass(this.widgetBaseClass + '-open'); + this.listWrap.removeClass(this.widgetBaseClass + '-open'); + this.list.attr('aria-hidden', true); if ( this.options.style == "dropdown" ) { this.newelement.removeClass('ui-corner-top').addClass('ui-corner-all'); } @@ -797,7 +806,7 @@ $.widget("ui.selectmenu", { zIndex: zIndexElement }); } - this.list.position({ + this.listWrap.position({ // set options for position plugin of: o.positionOptions.of || this.newelement, my: o.positionOptions.my, -- 2.39.5