Selectmenu: Code review #492

Closed
wants to merge 292 commits into
from

Projects

None yet

9 participants

@fnagel
Member
fnagel commented Oct 10, 2011

Request for code review (in accordance with Jörn).

There some open issues being discussed, see the Wiki:
http://wiki.jqueryui.com/w/page/12138056/Selectmenu

@jzaefferer
Owner

I'd say its about time to start with unit tests. Most of the visual tests should be unit tests.

Member

I agree. Only problem is to find some time to get into the test unit scripts :-/

@gnarf gnarf and 1 other commented on an outdated diff Oct 10, 2011
ui/jquery.ui.selectmenu.js
+ if ( !this.opened ) this.list.menu( "select", event );
+ },
+
+ _getSelectedItem: function() {
+ return this.list.find( "li" ).not( '.ui-selectmenu-optgroup' ).eq( this.element[0].selectedIndex );
+ },
+
+ _toggle: function( event ) {
+ if ( this.opened ) {
+ this.close( event );
+ } else {
+ this.open( event );
+ }
+ },
+
+ _newelementEvents: {
gnarf
gnarf Oct 10, 2011 Owner

_newElementEvents?

fnagel
fnagel Oct 10, 2011 Member

Named that way because the events are bound to this.newelement. Variable names (this.list, this.newelement, etc.) are taken over from the old branch. The naming of the vars should be discussed anyway :-)

Owner
gnarf commented Oct 10, 2011

I'm seeing a lot of uses of var that = this; where its not event needed. We are trying to avoid this wherever possible now...

Should probably just replace with this in most cases, as we clean up most of these, we can look at a better workaround for any cases left over.

@jzaefferer jzaefferer and 1 other commented on an outdated diff Oct 10, 2011
ui/jquery.ui.selectmenu.js
+ selectmenuId = that.element.attr( 'id' ) || 'ui-selectmenu-' + Math.random().toString( 16 ).slice( 2, 10 );
+
+ // quick array of button and menu id's
+ that.ids = [ selectmenuId, selectmenuId + '-button', selectmenuId + '-menu' ];
+
+ // set current value
+ if ( options.value ) {
+ that.element[0].value = options.value;
+ } else {
+ options.value = that.element[0].value;
+ }
+
+ // catch click event of the label
+ that._bind({
+ 'click': function( event ) {
+ that.newelement.focus();
jzaefferer
jzaefferer Oct 10, 2011 Owner

Can just use this within a _bind callback. Should remove need for that inside _create completely.

jzaefferer
jzaefferer Oct 10, 2011 Owner

Should also rename newelement to something like button or trigger. The latter would match what we have in Popup.

fnagel
fnagel Oct 10, 2011 Member
  1. Ahh I did get that wrong. Will be changed soon.
  2. Agree, button seems legit. Should we change this.list to this.menu? I will change the wrapper var too.
jzaefferer
jzaefferer Oct 10, 2011 Owner

Sounds good.

fnagel
fnagel Oct 11, 2011 Member

Done, pushed soon.

@jzaefferer jzaefferer and 1 other commented on an outdated diff Oct 10, 2011
ui/jquery.ui.selectmenu.js
+ that._addList();
+ that.refresh();
+ },
+
+ _addNewelement: function() {
+ var that = this,
+ options = this.options,
+ tabindex = this.element.attr( 'tabindex' );
+
+ // hide original select tag
+ that.element.hide();
+
+ // create button
+ that.newelement = $( '<a />', {
+ href: '#' + that.ids[ 0 ],
+ tabindex: ( tabindex ? tabindex : that.element.attr( 'disabled' ) ? 1 : 0 ),
jzaefferer
jzaefferer Oct 10, 2011 Owner

tabindex 1 for disabled elements? Shouldn't that be -1?

fnagel
fnagel Oct 11, 2011 Member

Correct.

@jzaefferer jzaefferer and 1 other commented on an outdated diff Oct 10, 2011
ui/jquery.ui.selectmenu.js
+ // callbacks
+ open: null,
+ focus: null,
+ select: null,
+ close: null,
+ change: null
+ },
+
+ _create: function() {
+ var that = this,
+ options = this.options,
+ // set a default id value, generate a new random one if not set by developer
+ selectmenuId = that.element.attr( 'id' ) || 'ui-selectmenu-' + Math.random().toString( 16 ).slice( 2, 10 );
+
+ // quick array of button and menu id's
+ that.ids = [ selectmenuId, selectmenuId + '-button', selectmenuId + '-menu' ];
jzaefferer
jzaefferer Oct 10, 2011 Owner

That's certainly more convenient to define then an object literal, but ids[ x ] gets pretty annoying to look up.

fnagel
fnagel Oct 11, 2011 Member

Should be changed to associative array?

@jzaefferer jzaefferer and 1 other commented on an outdated diff Oct 10, 2011
ui/jquery.ui.selectmenu.js
+ // catch click event of the label
+ that._bind({
+ 'click': function( event ) {
+ that.newelement.focus();
+ event.preventDefault();
+ }
+ });
+
+ that._addNewelement();
+ that._bind( that.newelement, that._newelementEvents );
+
+ that._addList();
+ that.refresh();
+ },
+
+ _addNewelement: function() {
jzaefferer
jzaefferer Oct 10, 2011 Owner

We're using _draw eleswhere for these kind of methods, maybe use that also as the prefix here?

@jzaefferer jzaefferer and 1 other commented on an outdated diff Oct 10, 2011
ui/jquery.ui.selectmenu.js
+ var setWidth = that.newelement.outerWidth();
+ } else {
+ var text = that.newelement.find( "span.ui-button-text");
+ var setWidth = text.width() + parseFloat( text.css( "padding-left" ) ) + parseFloat( text.css( "margin-left" ) );
+ }
+
+ // wrap list
+ that.listWrap = $( '<div />' )
+ .addClass( 'ui-selectmenu-menu' )
+ .width( setWidth )
+ .append( that.list )
+ .appendTo( options.appendTo );
+
+ // init menu widget
+ that.list
+ .data( 'element.selectelemenu', that.element )
jzaefferer
jzaefferer Oct 10, 2011 Owner

Can't you just use that.list whereever you need a reference to it?

fnagel
fnagel Oct 11, 2011 Member

I currenlty need this refernce to close all other open menus. See first lines in method open (edit: you commented below).
Perhaps there is a better way to do this?

fnagel
fnagel Oct 17, 2011 Member

Fixed.

@jzaefferer jzaefferer and 1 other commented on an outdated diff Oct 10, 2011
ui/jquery.ui.selectmenu.js
+ event.preventDefault();
+ that.close( event, true);
+ }
+ },
+ focus: function( event, ui ) {
+ var item = ui.item.data( "item.selectmenu" );
+ if ( that.focus !== undefined && item.index != that.focus ) that._trigger( "focus", event, { item: item } );
+ that.focus = item.index;
+ }
+ });
+
+ // document click closes menu
+ that._bind( document, {
+ 'mousedown': function( event ) {
+ if ( that.opened && !$( event.target ).is( that.list ) ) {
+ window.setTimeout( function() {
jzaefferer
jzaefferer Oct 10, 2011 Owner

You can use _delay instead of setTimeout, it'll give you this back to the right context. And inside _bind this is already referring to the instance.

@jzaefferer jzaefferer and 1 other commented on an outdated diff Oct 10, 2011
ui/jquery.ui.selectmenu.js
+
+ if ( item.index != that.element[0].selectedIndex ) flag = true;
+
+ that._setOption( "value", item.value );
+ that._trigger( "select", event, { item: item } );
+
+ if ( flag ) that._trigger( "change", event, { item: item } );
+
+ if ( that.opened ) {
+ event.preventDefault();
+ that.close( event, true);
+ }
+ },
+ focus: function( event, ui ) {
+ var item = ui.item.data( "item.selectmenu" );
+ if ( that.focus !== undefined && item.index != that.focus ) that._trigger( "focus", event, { item: item } );
jzaefferer
jzaefferer Oct 10, 2011 Owner

Needs line breaks and braces. Same for all other if-statements.

fnagel
fnagel Oct 11, 2011 Member

No "shorthand" clauses at all?

@jzaefferer jzaefferer and 1 other commented on an outdated diff Oct 10, 2011
ui/jquery.ui.selectmenu.js
+ if ( that.opened && !$( event.target ).is( that.list ) ) {
+ window.setTimeout( function() {
+ that.close( event );
+ }, 200 );
+ }
+ }
+ });
+ },
+
+ refresh: function() {
+ var that = this,
+ options = this.options;
+
+ that.list.empty();
+
+ that._initSource();
jzaefferer
jzaefferer Oct 10, 2011 Owner

Should rename this - it was similar to autocomplete's, but it isn't anymore. _readItems or something.

fnagel
fnagel Oct 11, 2011 Member

Renamed to _readOptions.

@jzaefferer jzaefferer and 1 other commented on an outdated diff Oct 10, 2011
ui/jquery.ui.selectmenu.js
+ });
+
+ // document click closes menu
+ that._bind( document, {
+ 'mousedown': function( event ) {
+ if ( that.opened && !$( event.target ).is( that.list ) ) {
+ window.setTimeout( function() {
+ that.close( event );
+ }, 200 );
+ }
+ }
+ });
+ },
+
+ refresh: function() {
+ var that = this,
@jzaefferer jzaefferer and 1 other commented on an outdated diff Oct 10, 2011
ui/jquery.ui.selectmenu.js
+ // transfer disabled state
+ if ( that.element.attr( 'disabled' ) ) {
+ that.disable();
+ } else {
+ that.enable()
+ }
+ },
+
+ open: function( event ) {
+ var that = this,
+ options = this.options,
+ currentItem = that._getSelectedItem();
+
+ if ( !options.disabled ) {
+ // close all other selectmenus
+ $( '.ui-selectmenu-open' ).not( that.newelement ).each( function() {
jzaefferer
jzaefferer Oct 10, 2011 Owner

Is there some other way to achieve the same effect? Click on the trigger should propagate to document, other selectmenu's (or popups or anything that's popping up) should handle the event.

fnagel
fnagel Oct 11, 2011 Member

Ahhh I mentioned to find another way to do so when you asked above to remove the data binding. But you're right seems useless at all.

fnagel
fnagel Oct 11, 2011 Member

Mhh its needed and I did not manage to handle the window event correct. Played arround with event.stopImmediatePropagation(), stopPropagation(), preventDefault() but with no success.

jzaefferer
jzaefferer Oct 12, 2011 Owner

Take a look at how Popup handles that, with a $(document).bind("click")

fnagel
fnagel Oct 12, 2011 Member

When using click event on window only a click on the button should fire the window click event too and I cant get this working (see post above).

fnagel
fnagel Oct 17, 2011 Member

Fixed.

@jzaefferer jzaefferer and 1 other commented on an outdated diff Oct 10, 2011
ui/jquery.ui.selectmenu.js
+ _toggle: function( event ) {
+ if ( this.opened ) {
+ this.close( event );
+ } else {
+ this.open( event );
+ }
+ },
+
+ _newelementEvents: {
+ mousedown: function( event ) {
+ this._toggle( event );
+ event.stopImmediatePropagation();
+ },
+ click: function( event ) {
+ // return false needed to prevent browser from following the anchor
+ return false;
jzaefferer
jzaefferer Oct 10, 2011 Owner

Should be just event.preventDefault, otherwise it'll also stop propagation, see above regarding 'closing other selectmenus'.

fnagel
fnagel Oct 12, 2011 Member

Changed.

@jzaefferer jzaefferer and 1 other commented on an outdated diff Oct 10, 2011
ui/jquery.ui.selectmenu.js
+
+ if ( key === "appendTo" ) {
+ this.listWrap.appendTo( $( value || "body", this.element[0].ownerDocument )[0] );
+ }
+ if ( key === "value" && value !== undefined ) {
+ this.element[0].value = value;
+ this.newelement.children( '.ui-button-text' ).text( this.items[ this.element[0].selectedIndex ].label );
+ }
+ if ( key === "disabled" ) {
+ this.newelement.button( "option", "disabled", value );
+ if ( value ) {
+ this.element.attr( "disabled", "disabled" );
+ this.newelement.attr( "tabindex", -1 );
+ } else {
+ this.element.removeAttr( "disabled" );
+ this.newelement.attr( "tabindex", 1 );
jzaefferer
jzaefferer Oct 10, 2011 Owner

Should be tabindex 0, as in _addNewelement?

fnagel
fnagel Oct 12, 2011 Member

Corrcected.

Owner

Nice: Showing 13 changed files with 1,000 additions and 0 deletions.

Member
fnagel commented Oct 17, 2011

Ive updated the branch with a new version which gets rid of the unneeded data binding and has some other minor improvements.

Its tested on Win7 with FF7, IE9, latest Chrome, Safari 5.0.x, IE8, IE7 on VM and IE6 standalone. Looks good so far. IE6 has some icon positioning issues which should be reported to Menu (if IE6 is still supported).

Owner

Update looks pretty good, nice to see the document-click-handling is now working properly.

What's the menu issue? Could you put that on the Menu wiki page? http://wiki.jqueryui.com/w/page/12137997/Menu

Member
fnagel commented Oct 18, 2011

Looks like the the IE6 icon problem I noticed was related to the standalone IE6, but I reported some other issues I noticed when rechecking with VM.

Member
fnagel commented Nov 22, 2011

There are currently some issues with focus handling and click event control.
Please try to use the selectmenu default demo with overflow (to see all problems pretty easy) or try to click on an item but do not release the button -- the first items is focused before releasing.

Im running into that kind of trouble since Jörn merged master into selectmenu branch so I assume the problem is about the changes to Menu. ( Im talking about this commit form Hans: 3c258bf )
Afaics I need to make use of the pop-up widget in order to make Selectmenu work again and improve focus handling and accessibility. Any comments on this?

Member
fnagel commented Nov 22, 2011

Problem seems to be related to line 83-85 in Menu.

"focus": function( event ) {
    this.focus( event, $( event.target ).children( ".ui-menu-item:first" ) );
},

It seems this will focus the first element every time before an item is clicked.

Owner

Looks like this is the actual commit: e16e99a

Owner

Also affects autocomplete. Need to make that an option, or find some other way for other widgets to disable it.

Owner

@kborchers will look into it.

Owner

Might be addressed here? e11efb3

Owner

OK, this should be corrected with 74a3f2c. It was the commit from Hans that caused this. I believe my changes still accomplish what he wanted and fix the issues that were caused.

Owner

Thanks @kborchers, looks good.

Member
fnagel commented Nov 28, 2011

Agree, Selectmenu works nice again! Thanks, @kborchers

Member
fnagel commented Nov 28, 2011

In my opinion the current implementation of isScrolling in Menu (mousover on item) causes some unwanted usability problems in Selectmenu when using overfow. After scrolling you need to mouse over at least one item before an item receives focus. It feels like an bug when using Selectmenu not like an feature.

Owner

Yeah, noticed that, too. @kborchers could you take a look?

Member
fnagel commented Nov 28, 2011

Sorry, I did check the latest commit again and must confess the "first item selected" problem is not solved. @kborchers The focus event mentioned above still seems like a problem to me. Problem is that the focus currently stays on the button when selectmenu is opened and the click fires the Menu focus event with first item as parameter.

Owner

@fnagel Hmmm, I am not seeing the issue. If I look at http://view.jqueryui.com/selectmenu/tests/visual/selectmenu/events.html, it seems to record the correct element as the item being focused when the button is clicked. Please let me know if I am missing something or not understanding. I will be looking into isScrolling tonight also.

Owner

@jzaefferer Do you remember the reason for implementing isScrolling? I have removed it locally and Menu, Selectmenu and Autocomplete all seem to work just fine without it. The mouseover events of course now fire during scroll but is that a problem? Any input would be appreciated.

Owner

The commit doesn't really provide any more details then we have in the comment there anyway: 9a274c0

Not sure what "prevent mouseover from firing inadvertently when scrolling the menu" means - maybe we addressed that in some other way? Or we were wrong on considering that an issue? No idea, if you can't reproduce the original issue, let's kick out the isScrolling code and keep an idea on it.

Owner

OK, I have removed the isScrolling code. We'll keep an eye on it.

Member
fnagel commented Nov 30, 2011

@kborchers
The isScrolling issue is fixed, thanks for that.

Regarding the "focus first item" problem:
Afaics the view.jquery.ui.com files are outdated. When using my local branch or download a fresh zip from GitHub the problem occurs.

Please test the default.hmtl demo. Open the second selectmenu (with overflow) by click and try to use the scrollbar.
When using the event.html demo you will notice another event after closing, which should not be fired.

Owner

@fnagel Yeah, I noticed the issue today when I clicked on the scroll bar. Working on a solution now.

Owner

@fnagel FYI, I made a change to Menu and renamed the "items" option to "menus". I looked through your code and it doesn't look like it affects you but just wanted you to be aware. I will merge master into this branch again now.

Member
fnagel commented Dec 1, 2011

@kborchers Agree, seems legit. Thanks for pinging!

Member
fnagel commented Dec 15, 2011

@kborchers
Any progress on the "focus first item" problem?

@kborchers
Owner

@fnagel Please take a look at these changes and let me know how selectmenu works as far as the focus issues are concerned. I think this should take care of it.

@kborchers
Owner

@fnagel OK, try this now. Sorry about that.

Member
fnagel commented Dec 20, 2011

@kborchers Works nice again, no issues in major browsers afaics. Thanks for fixing!

Owner

Good to hear!

Owner

Let's clean up the visual tests. They are useful while prototyping, but need to be replaced by unit tests. Units are all there, so let's remove most of the visual tests, maybe merge one from each into a composite one.

@jzaefferer jzaefferer and 1 other commented on an outdated diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
@@ -0,0 +1,452 @@
+/*!
+ * jQuery UI Selectmenu @VERSION
+ * http://jqueryui.com
+ *
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Selectmenu
jzaefferer
jzaefferer Nov 29, 2012 Owner

Should be http://api.jqueryui.com/selectmenu

@jzaefferer jzaefferer and 1 other commented on an outdated diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+ *
+ * http://docs.jquery.com/UI/Selectmenu
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.widget.js
+ * jquery.ui.position.js
+ * jquery.ui.menu.js
+ */
+(function( $, undefined ) {
+
+$.widget( "ui.selectmenu", {
+ version: "@VERSION",
+ defaultElement: "<select>",
+ options: {
+ dropdown: true,
jzaefferer
jzaefferer Nov 29, 2012 Owner

Options should be alphabetically ordered, then a line break, then callbacks, also alphabetically ordered.

@jzaefferer jzaefferer and 1 other commented on an outdated diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+ appendTo: "body",
+ position: {
+ my: "left top",
+ at: "left bottom",
+ collision: "none"
+ },
+ // callbacks
+ open: null,
+ focus: null,
+ select: null,
+ close: null,
+ change: null
+ },
+
+ _create: function() {
+ // make / set unique id
jzaefferer
jzaefferer Nov 29, 2012 Owner

Unnecessary comment, the purpose of uniqueId() should be clear.

@jzaefferer jzaefferer and 1 other commented on an outdated diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+ at: "left bottom",
+ collision: "none"
+ },
+ // callbacks
+ open: null,
+ focus: null,
+ select: null,
+ close: null,
+ change: null
+ },
+
+ _create: function() {
+ // make / set unique id
+ var selectmenuId = this.element.uniqueId().attr( "id" );
+
+ // array of button and menu id's
jzaefferer
jzaefferer Nov 29, 2012 Owner

Dunno if this comment is necessary, but at least its wrong, as this isn't an array anymore.

@jzaefferer jzaefferer and 1 other commented on an outdated diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+ open: null,
+ focus: null,
+ select: null,
+ close: null,
+ change: null
+ },
+
+ _create: function() {
+ // make / set unique id
+ var selectmenuId = this.element.uniqueId().attr( "id" );
+
+ // array of button and menu id's
+ this.ids = { id: selectmenuId, button: selectmenuId + "-button", menu: selectmenuId + "-menu" };
+
+ this._drawButton();
+ this._on( this.button, this._buttonEvents );
jzaefferer
jzaefferer Nov 29, 2012 Owner

Move this into _drawButton.

@jzaefferer jzaefferer and 1 other commented on an outdated diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+ var selectmenuId = this.element.uniqueId().attr( "id" );
+
+ // array of button and menu id's
+ this.ids = { id: selectmenuId, button: selectmenuId + "-button", menu: selectmenuId + "-menu" };
+
+ this._drawButton();
+ this._on( this.button, this._buttonEvents );
+ this._hoverable( this.button );
+ this._focusable( this.button );
+
+ this._drawMenu();
+
+ // document click closes menu
+ this._on( document, {
+ click: function( event ) {
+ if ( this.isOpen && !$( event.target ).closest( "li.ui-state-disabled, li.ui-selectmenu-optgroup, #" + this.ids.button ).length ) {
jzaefferer
jzaefferer Nov 29, 2012 Owner

Does this still run when the selectmenu gets disabled? If it should, pass the supressDisabledCheck flag (see ui.widget, was added recently).

Either way, let's move this handler into a documentClick method or something like that. Should remove the need for the comment above.

fnagel
fnagel Dec 12, 2012 Member

No, this does not run when a selectmenu is disabled as the selectmenu is closed on disabling. So do we need suppressDisabledCheck here?

I've added a _documentClick method.

@jzaefferer jzaefferer and 1 other commented on an outdated diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+ this.close( event );
+ }
+ }
+ });
+
+ if ( this.options.disabled ) {
+ this.disable();
+ }
+ },
+
+ _drawButton: function() {
+ var tabindex = this.element.attr( "tabindex" );
+
+ // fix existing label
+ this.label = $( "label[for='" + this.ids.id + "']" ).attr( "for", this.ids.button );
+ // catch click event of the label
jzaefferer
jzaefferer Nov 29, 2012 Owner

Unnecessary.

@jzaefferer jzaefferer commented on the diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+ click: function( event ) {
+ if ( this.isOpen && !$( event.target ).closest( "li.ui-state-disabled, li.ui-selectmenu-optgroup, #" + this.ids.button ).length ) {
+ this.close( event );
+ }
+ }
+ });
+
+ if ( this.options.disabled ) {
+ this.disable();
+ }
+ },
+
+ _drawButton: function() {
+ var tabindex = this.element.attr( "tabindex" );
+
+ // fix existing label
jzaefferer
jzaefferer Nov 29, 2012 Owner

Why do you need both this and a click handler? Should the updated for-attribute take care of the click-forwarding already?

fnagel
fnagel Nov 29, 2012 Member

This was added by Robert. I'm not quite sure why this was added.

jzaefferer
jzaefferer Nov 29, 2012 Owner

So Robert added the for-attribute-update, the click handler was already there?

If so: I think he added it to fix screenreaders reading the button label, I guess the for-attribute is more reliable then aria-labelledby. With that in place, the manual click binding can likely be removed. Can you give that a try?

fnagel
fnagel Dec 12, 2012 Member

You did something on that in your branch. Any need to test this for me any further?

@jzaefferer jzaefferer and 1 other commented on an outdated diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+
+ // fix existing label
+ this.label = $( "label[for='" + this.ids.id + "']" ).attr( "for", this.ids.button );
+ // catch click event of the label
+ this._on( this.label, {
+ "click": function( event ) {
+ this.button.focus();
+ event.preventDefault();
+ }
+ });
+
+ // hide original select tag
+ this.element.hide();
+
+ // create button
+ this.button = $( "<a />", {
jzaefferer
jzaefferer Nov 29, 2012 Owner

Why are we using an anchor here? Can it be a <button> or even just a <span>?

fnagel
fnagel Nov 29, 2012 Member

Good question. It was a anchor since the filaments group first selectmenu script.

I assume changing this will lead to different behavior in screenreaders.

jzaefferer
jzaefferer Nov 29, 2012 Owner

We used to require anchors in other places as well, I think old Safaris sucked at handling tabindex. That's why Accordion doesn't require anchors anymore, that was one of the big changes in 1.9. We should try to replace the anchor and see if that helps improving screenreader compat anywhere.

fnagel
fnagel Dec 12, 2012 Member

I can do that. Should I change it to a button element?

fnagel
fnagel Dec 12, 2012 Member

Sorry, I've just noticed you changed this in the aria-tweaks branch.

@jzaefferer jzaefferer and 1 other commented on an outdated diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+ // create button
+ this.button = $( "<a />", {
+ "class": "ui-button ui-widget ui-state-default ui-corner-all",
+ href: "#" + this.ids.id,
+ tabindex: ( tabindex ? tabindex : this.options.disabled ? -1 : 0 ),
+ id: this.ids.button,
+ width: this.element.outerWidth(),
+ role: "combobox",
+ "aria-expanded": false,
+ "aria-autocomplete": "list",
+ "aria-owns": this.ids.menu,
+ "aria-haspopup": true
+ });
+
+ this.button.prepend( $( "<span />", {
+ "class": "ui-icon " + ( ( this.options.dropdown ) ? "ui-icon-triangle-1-s" : "ui-icon-triangle-2-n-s" )
jzaefferer
jzaefferer Nov 29, 2012 Owner

Unnecessary parens around the option.

jzaefferer
jzaefferer Nov 29, 2012 Owner

Also, we should make this configurable as an icons option, similar to accordion's. Let's wait for @scottgonzalez on that, though.

fnagel
fnagel Nov 29, 2012 Member

We did discuss this earlier. The span is needed for CSS scope if a custom style should be added to this specific selectmenu.

jzaefferer
jzaefferer Nov 29, 2012 Owner

Wrong line? I didn't question the span, as far as I can tell. Was suggesting something like this:

"class": "ui-icon " + ( this.options.dropdown ? options.icons.dropdown : options.icons.popup )

Without the icons option, you should still remove the parens around this.options.dropdown

fnagel
fnagel Dec 12, 2012 Member

Sorry, I misunderstood.

Seems a nice idea. I will wait for @scottgonzalez response.

fnagel
fnagel Dec 18, 2012 Member

Implemented in 52fc8e3

@jzaefferer jzaefferer and 2 others commented on an outdated diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+
+ // create button
+ this.button = $( "<a />", {
+ "class": "ui-button ui-widget ui-state-default ui-corner-all",
+ href: "#" + this.ids.id,
+ tabindex: ( tabindex ? tabindex : this.options.disabled ? -1 : 0 ),
+ id: this.ids.button,
+ width: this.element.outerWidth(),
+ role: "combobox",
+ "aria-expanded": false,
+ "aria-autocomplete": "list",
+ "aria-owns": this.ids.menu,
+ "aria-haspopup": true
+ });
+
+ this.button.prepend( $( "<span />", {
jzaefferer
jzaefferer Nov 29, 2012 Owner

Use <span></span> for non-empty elements.

jzaefferer
jzaefferer Nov 29, 2012 Owner

There's four more of this below.

scottgonzalez
scottgonzalez Nov 29, 2012 Owner

Actually just <span> if all you're doing is creating the element.

@jzaefferer jzaefferer and 2 others commented on an outdated diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+ id: this.ids.button,
+ width: this.element.outerWidth(),
+ role: "combobox",
+ "aria-expanded": false,
+ "aria-autocomplete": "list",
+ "aria-owns": this.ids.menu,
+ "aria-haspopup": true
+ });
+
+ this.button.prepend( $( "<span />", {
+ "class": "ui-icon " + ( ( this.options.dropdown ) ? "ui-icon-triangle-1-s" : "ui-icon-triangle-2-n-s" )
+ }));
+
+ this.buttonText = $( "<span />", {
+ "class": "ui-selectmenu-text" ,
+ html: this.element.find( "option:selected" ).text() || "&nbsp;"
jzaefferer
jzaefferer Nov 29, 2012 Owner

In dialog we use &#160;. The result should be same as &nbsp;, not sure about the reason for one or the other.

scottgonzalez
scottgonzalez Nov 29, 2012 Owner

I don't remember the exact reason we used &#160; but I seem to remember there being a reason. I can say that it's more portable than &nbsp; as numeric values will work without additional definitions for named entities.

fnagel
fnagel Nov 29, 2012 Member

Seems to work without problems. Changed.

@jzaefferer jzaefferer commented on the diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+ "class": "ui-selectmenu-text" ,
+ html: this.element.find( "option:selected" ).text() || "&nbsp;"
+ })
+ .appendTo( this.button );
+
+ // wrap and insert new button
+ this.buttonWrap = $( "<span />", {
+ "class": "ui-selectmenu-button"
+ })
+ .append( this.button )
+ .insertAfter( this.element );
+ },
+
+ _drawMenu: function() {
+ var menuInstance,
+ that = this;
jzaefferer
jzaefferer Nov 29, 2012 Owner

@scottgonzalez that is needed here to use regular menu callbacks. Any idea how to replace it here?

scottgonzalez
scottgonzalez Nov 29, 2012 Owner

It's fine to use that in these situations, but if you really want to get rid of it, you would do so by using _on() to bind to the events instead of using callbacks.

@jzaefferer jzaefferer commented on the diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+
+ // Set ARIA active decendent
+ that.button.attr( "aria-activedescendant", that.menuItems.eq( item.index ).find( "a" ).attr( "id" ) );
+ },
+ // set ARIA role
+ role: "listbox"
+ })
+ .data( "ui-menu" );
+
+ // change menu styles?
+ if ( this.options.dropdown ) {
+ this.menu.addClass( "ui-corner-bottom" ).removeClass( "ui-corner-all" );
+ }
+
+ // make sure focus stays on selected item
+ menuInstance.delay = 999999999;
jzaefferer
jzaefferer Nov 29, 2012 Owner

This looks like it should get addressed in menu itself. What issue is this working around, is there a ticket? Ping @kborchers, too.

fnagel
fnagel Nov 29, 2012 Member

No, there is no ticket, but a a comment in this CR, see:

I agree, this should be handled in Menu.

jzaefferer
jzaefferer Nov 29, 2012 Owner

There is no link in your comment. Could you create a ticket and link to whatever is available? http://bugs.jqueryui.com/newticket

fnagel
fnagel Dec 3, 2012 Member

Ahh sorry: #492 (comment) and following

fnagel
fnagel Dec 15, 2012 Member

Mhh, wanted to add a ticket but some wild python tracelog appeared ;-)

fnagel
fnagel Dec 20, 2012 Member

The login system seems to have serious issues. I've needed to reset my password (again) and login ended up in a redirect loop.

Finally: http://bugs.jqueryui.com/ticket/8929

@jzaefferer jzaefferer and 2 others commented on an outdated diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+ // init menu widget
+ menuInstance = this.menu.menu({
+ select: function( event, ui ) {
+ var item = ui.item.data( "ui-selectmenu-item" );
+
+ that._select( item, event );
+
+ if ( that.isOpen ) {
+ event.preventDefault();
+ that.close( event );
+ }
+ },
+ focus: function( event, ui ) {
+ var item = ui.item.data( "ui-selectmenu-item" );
+
+ if ( that.focus !== undefined ) {
jzaefferer
jzaefferer Nov 29, 2012 Owner

Put these two if statements into one. if ( that.focus !== undefined && item.index !== that.focus ) {.

Also here a comment explaining the purpose would be nice.

scottgonzalez
scottgonzalez Nov 29, 2012 Owner

We very rarely check !== undefined, can't this just be != null?

jzaefferer
jzaefferer Dec 5, 2012 Owner

Still need to merge the two if statements. If it works, also replace !== undefined with != null.

fnagel
fnagel Dec 12, 2012 Member

I've merged these statements.

Check for undefined is needed as we need to call the Menu widget focus method on init. So test for undefined prevents focus from firing.

@jzaefferer jzaefferer and 1 other commented on an outdated diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+ if ( !that.isOpen ) {
+ that._select( item, event );
+ }
+ }
+ }
+ that.focus = item.index;
+
+ // Set ARIA active decendent
+ that.button.attr( "aria-activedescendant", that.menuItems.eq( item.index ).find( "a" ).attr( "id" ) );
+ },
+ // set ARIA role
+ role: "listbox"
+ })
+ .data( "ui-menu" );
+
+ // change menu styles?
jzaefferer
jzaefferer Nov 29, 2012 Owner

Weird comment. Should inform about WHY styles need to be changed.

@jzaefferer jzaefferer and 1 other commented on an outdated diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+ this._setSelected( item.data( "ui-selectmenu-item" ) );
+
+ // set disabled state
+ this._setOption( "disabled", this._getCreateOptions().disabled );
+ }
+ },
+
+ open: function( event ) {
+ if ( !this.options.disabled ) {
+ var _position = {
+ of: this.button
+ };
+
+ // make sure menu is refreshed on first init (needed at least for IE9)
+ if ( this.isOpen === undefined ) {
+ this.button.trigger( "focus" );
jzaefferer
jzaefferer Nov 29, 2012 Owner

So you trigger the focus handler to refresh the menu, and it'll also remove the focus handler, right? Can we remove a level of indirection here?

fnagel
fnagel Nov 29, 2012 Member

Any idea how?

jzaefferer
jzaefferer Nov 29, 2012 Owner

Nope, would've wrote it down otherwise. Let's try to come up with something.

fnagel
fnagel Dec 12, 2012 Member

I will do some tests and see whats possible.

fnagel
fnagel Dec 12, 2012 Member

After some tests I removed this snippet. It was needed once, but it seems bo be useless now.

@jzaefferer jzaefferer and 1 other commented on an outdated diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+
+ this.menu.menu( "refresh" );
+ this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" );
+
+ // select current item
+ item = this._getSelectedItem();
+ this.menu.menu( "focus", null, item );
+ this._setSelected( item.data( "ui-selectmenu-item" ) );
+
+ // set disabled state
+ this._setOption( "disabled", this._getCreateOptions().disabled );
+ }
+ },
+
+ open: function( event ) {
+ if ( !this.options.disabled ) {
jzaefferer
jzaefferer Nov 29, 2012 Owner

Use a guard clause:

if ( this.options.disabled ) {
    return;
}
...
@jzaefferer jzaefferer and 1 other commented on an outdated diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+ open: function( event ) {
+ if ( !this.options.disabled ) {
+ var _position = {
+ of: this.button
+ };
+
+ // make sure menu is refreshed on first init (needed at least for IE9)
+ if ( this.isOpen === undefined ) {
+ this.button.trigger( "focus" );
+ }
+
+ this.isOpen = true;
+ this._toggleAttr();
+ this.menu.menu( "focus", event, this._getSelectedItem() );
+
+ if ( this.items && !this.options.dropdown && this.options.position.my == "left top" && this.options.position.at == "left bottom" ) {
jzaefferer
jzaefferer Nov 29, 2012 Owner

This deserves a comment. Why do you need the position checks?

fnagel
fnagel Nov 29, 2012 Member

Added a comment.

Thats the check I talked about in my email.
With this check its possible to have custom positioned menus in popup style. Otherwise the
Only other solution would be to separate pop-up styling and positioning in two different options.

@jzaefferer jzaefferer and 2 others commented on an outdated diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+ this.menu.menu( "focus", event, this._getSelectedItem() );
+
+ if ( this.items && !this.options.dropdown && this.options.position.my == "left top" && this.options.position.at == "left bottom" ) {
+ var currentItem = this._getSelectedItem();
+ // center current item
+ if ( this.menu.outerHeight() < this.menu.prop( "scrollHeight" ) ) {
+ this.menuWrap.css( "left" , -10000 );
+ this.menu.scrollTop( this.menu.scrollTop() + currentItem.position().top - this.menu.outerHeight() / 2 + currentItem.outerHeight() / 2 );
+ this.menuWrap.css( "left" , "auto" );
+ }
+ _position.my = "left top" + ( this.menu.offset().top - currentItem.offset().top + ( this.button.outerHeight() - currentItem.outerHeight() ) / 2 );
+ _position.at = "left top";
+ }
+
+ this.menuWrap
+ .zIndex( this.element.zIndex() + 1 )
jzaefferer
jzaefferer Nov 29, 2012 Owner

Since the default for the appendTo option, which is used append the menuWrap element, is "body", we shouldn't have to set a z-index. If the selectmenu is used inside a dialog, it needs to be appended to the dialog, and the z-index on the dialog takes care of stacking. Is that correct @scottgonzalez?

scottgonzalez
scottgonzalez Nov 29, 2012 Owner

Yeah, we need to follow the .ui-front logic here and not set z-index directly.

fnagel
fnagel Nov 29, 2012 Member

Using

.addClass( "ui-front" )

instead of

.zIndex( this.element.zIndex() + 1 )

as Jörn said does not work when Selectmenu is inside a Dialog (see compatibility visual test). Do I need to adjust some CSS or something?

jzaefferer
jzaefferer Nov 29, 2012 Owner

Did you set appendTo: dialog? That should be all that's needed.

scottgonzalez
scottgonzalez Nov 29, 2012 Owner

No, you shouldn't set appendTo at all. Dialog should automatically be found because of .ui-front.

jzaefferer
jzaefferer Dec 5, 2012 Owner

This still needs to be addressed. See "z-index and stacking" for details on using ui-front here: http://wiki.jqueryui.com/w/page/12137737/Coding%20standards

fnagel
fnagel Dec 12, 2012 Member

What dialog?

Sorry but I still struggling to make this work. Any code example? I see that autocomplete and dialog use a _appendTo function but without making use of a ui-front class.

fnagel
fnagel Dec 15, 2012 Member

Please see 57ecee8

jzaefferer
jzaefferer Dec 15, 2012 Owner

That commit changes the appendTo logic, but the z-index is still set. Is it still necessary?

fnagel
fnagel Dec 16, 2012 Member

Nah, its not. Removed.

fnagel
fnagel Dec 18, 2012 Member

Fixed.

@jzaefferer jzaefferer and 1 other commented on an outdated diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+ this.menuWrap.css( "left" , "auto" );
+ }
+ _position.my = "left top" + ( this.menu.offset().top - currentItem.offset().top + ( this.button.outerHeight() - currentItem.outerHeight() ) / 2 );
+ _position.at = "left top";
+ }
+
+ this.menuWrap
+ .zIndex( this.element.zIndex() + 1 )
+ .position( $.extend( {}, this.options.position, _position ) );
+
+ this._trigger( "open", event );
+ }
+ },
+
+ close: function( event ) {
+ if ( this.isOpen ) {
jzaefferer
jzaefferer Nov 29, 2012 Owner

Let's make this a guard clause, too. Less indentation FTW!

@jzaefferer jzaefferer and 1 other commented on an outdated diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+ "class": "ui-selectmenu-optgroup" + ( item.element.parent( "optgroup" ).attr( "disabled" ) ? " ui-state-disabled" : "" ),
+ html: item.optgroup
+ }).appendTo( ul );
+ currentOptgroup = item.optgroup;
+ }
+ that._renderItem( ul, item );
+ });
+ },
+
+ _renderItem: function( ul, item ) {
+ var li = $( "<li />" ).data( "ui-selectmenu-item", item );
+ if ( item.disabled ) {
+ li.addClass( "ui-state-disabled" );
+ }
+ li.append( $( "<a />", {
+ html: item.label,
jzaefferer
jzaefferer Nov 29, 2012 Owner

The option is read as text, we should also set it as text. Same above for optgroup.

fnagel
fnagel Dec 13, 2012 Member

Partly reverted, otherwise &#160; will be displayed as string.

@jzaefferer jzaefferer commented on the diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+ },
+
+ _toggle: function( event ) {
+ if ( this.isOpen ) {
+ this.close( event );
+ } else {
+ this.open( event );
+ }
+ },
+
+ _buttonEvents: {
+ focus: function() {
+ // init Menu on first focus
+ this.refresh();
+ // reset focus class as its removed by ui.widget._setOption
+ this.button.addClass( "ui-state-focus" );
jzaefferer
jzaefferer Nov 29, 2012 Owner

Only because you use focusable together with disabling, right? If there's something accidentally removing the class, it should be reported there.

fnagel
fnagel Dec 3, 2012 Member

Yes. With reported there you mean Widget Wiki page?

jzaefferer
jzaefferer Dec 5, 2012 Owner

I meant, reported against the buggy component.

fnagel
fnagel Dec 12, 2012 Member

Im still not sure where to report. Sorry :-)

@jzaefferer jzaefferer and 1 other commented on an outdated diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+ // change native select element
+ this.element[ 0 ].selectedIndex = item.index;
+ this._setSelected( item );
+ this._trigger( "select", event, { item: item } );
+
+ if ( item.index !== oldIndex ) {
+ this._trigger( "change", event, { item: item } );
+ }
+ },
+
+ _setSelected: function( item ) {
+ // update button text
+ this.buttonText.html( item.label );
+ // change ARIA attr
+ this.menuItems.find( "a" ).attr( "aria-selected", false );
+ this._getSelectedItem().find( "a" ).attr( "aria-selected", true );
jzaefferer
jzaefferer Nov 29, 2012 Owner

Can't you use item here?

fnagel
fnagel Nov 29, 2012 Member

No, as we need the anchor within the menu. The item object contains the original option only.

@jzaefferer jzaefferer and 1 other commented on an outdated diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+ var oldIndex = this.element[ 0 ].selectedIndex;
+ // change native select element
+ this.element[ 0 ].selectedIndex = item.index;
+ this._setSelected( item );
+ this._trigger( "select", event, { item: item } );
+
+ if ( item.index !== oldIndex ) {
+ this._trigger( "change", event, { item: item } );
+ }
+ },
+
+ _setSelected: function( item ) {
+ // update button text
+ this.buttonText.html( item.label );
+ // change ARIA attr
+ this.menuItems.find( "a" ).attr( "aria-selected", false );
jzaefferer
jzaefferer Nov 29, 2012 Owner

Or filter on menuItems here with item.index? (regarding the below comment)

fnagel
fnagel Dec 3, 2012 Member

Yes, that works fine. Done.

@jzaefferer jzaefferer and 1 other commented on an outdated diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+ },
+
+ _setSelected: function( item ) {
+ // update button text
+ this.buttonText.html( item.label );
+ // change ARIA attr
+ this.menuItems.find( "a" ).attr( "aria-selected", false );
+ this._getSelectedItem().find( "a" ).attr( "aria-selected", true );
+ this.button.attr( "aria-labelledby", this.menuItems.eq( item.index ).find( "a" ).attr( "id" ) );
+ },
+
+ _setOption: function( key, value ) {
+ this._super( key, value );
+
+ if ( key === "appendTo" ) {
+ this.menuWrap.appendTo( $( value || "body", this.element[ 0 ].ownerDocument )[ 0 ] );
jzaefferer
jzaefferer Nov 29, 2012 Owner

Why is this handled differently compared to the appendTo call in _drawMenu?

To access the body element, use this.document[ 0 ].body.

fnagel
fnagel Dec 3, 2012 Member

I think I copied this from another widget and I have no idea why its different to to the appendTo call in _drawMenu. I will adopt autocomplete's code here, ok?

jzaefferer
jzaefferer Dec 5, 2012 Owner

Yep, let's do that.

@jzaefferer jzaefferer and 1 other commented on an outdated diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+ _toggleAttr: function(){
+ if ( this.options.dropdown ) {
+ this.button.toggleClass( "ui-corner-top", this.isOpen ).toggleClass( "ui-corner-all", !this.isOpen );
+ }
+ this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen );
+ this.menu.attr( "aria-hidden", !this.isOpen);
+ this.button.attr( "aria-expanded", this.isOpen);
+ },
+
+ _getCreateOptions: function() {
+ return { disabled: !!this.element.attr( "disabled" ) };
+ },
+
+ _readOptions: function( options ) {
+ var data = [];
+ $.each( options, function( index, item ) {
jzaefferer
jzaefferer Nov 29, 2012 Owner

Use options.each instead? Its a jQuery object.

@jzaefferer jzaefferer commented on the diff Nov 29, 2012
ui/jquery.ui.selectmenu.js
+ index: index,
+ value: option.attr( "value" ),
+ label: option.text() || "&nbsp;",
+ optgroup: optgroup.attr( "label" ) || "",
+ disabled: optgroup.attr( "disabled" ) || option.attr( "disabled" )
+ });
+ });
+ this.items = data;
+ },
+
+ _destroy: function() {
+ this.menuWrap.remove();
+ this.buttonWrap.remove();
+ this.element.show();
+ this.element.removeUniqueId();
+ this.label.attr( "for", this.ids.id );
jzaefferer
jzaefferer Nov 29, 2012 Owner

If element didn't have an id to start with, this will set the for attribute to a non-existing id. It won't be worse, but maybe there's something more useful to do? Not sure.

fnagel
fnagel Dec 3, 2012 Member

Perhaps this should be handled when working on Hans mail.

Owner

I'm through with my code review. In the beginning I commented on a few unnecessary line comments, there are a bunch more later. I'd prefer to have most of them removed, and leave comments only to document workarounds and other less obvious sausages.

fnagel and others added some commits Nov 29, 2012
@fnagel fnagel Selectmenu: updated documentation link 8a62210
@fnagel fnagel Selectmenu: alphabetical ordering of options and callback events b014bc6
@fnagel fnagel Selectmenu: remove unnecessary comments from _create 080b5bc
@fnagel fnagel Selectmenu: move button event binding in _drawButton 71e744a
@fnagel fnagel Selectmenu: remove unnecessary comments from _drawButton e581a13
@fnagel fnagel Selectmenu: improve element creation a177a92
@fnagel fnagel Selectmenu: replace placeholder entity with &#160; 1e6808a
@fnagel fnagel Selectmenu: improve comment in _drawMenu ac7b8f9
@fnagel fnagel Selectmenu: improve disabled check in open method f622428
@fnagel fnagel Selectmenu: added comment about popup positioning 18ecaf4
@fnagel fnagel Selectmenu tests: remove themeswitcher as its no longer available d1c9837
@fnagel fnagel Selectmenu tests: add button widget js file to fix compatibility test 6fd9d8f
@fnagel fnagel Selectmenu: make isOpen check a guard clause in close method 0d28263
@fnagel fnagel Selectmenu: close guard close should test for closed menu 04553a7
@fnagel fnagel Selectmenu: guard clause should not return false cba09da
@fnagel fnagel Selectmenu: use text() instead of html() as the option and optgroup i…
…s read as text
60e3302
@fnagel fnagel Selectmenu: fix jQuery UI framework icon demo 40b8567
@fnagel fnagel Selectmenu: use item.index instead of _getSelectedItem method aa60a9e
@fnagel fnagel Selectmenu: simplify $.each usage in _readOptions method e6aca63
@jzaefferer jzaefferer Selectmenu: Cleanup demo markup 7a05c65
@jzaefferer jzaefferer Selectmenu: Remove colons from labels, annoying for screenreader-user…
…s. Cleanup whitespace.
15032d1
@jzaefferer jzaefferer Selectmenu: Select value when closing with space 2845d38
@fnagel fnagel Selectmenu: improve option appendTo handling in appendTo method d1350f9
@fnagel fnagel Merge branch 'master' into selectmenu f6372bd
@fnagel fnagel Selectmenu: use method _documentClick for adding events to the document 0732835
@fnagel fnagel Selectmenu: fix comment typo 20aad07
@fnagel fnagel Selectmenu tests: improve focus event test so its possible to test fo…
…r too much focus events from menu widget
812a90f
@fnagel fnagel Selectmenu: merge and explain if statements in Menu focus event, remo…
…ve unneeded Menu focus method call in open
b15ae2a
@fnagel fnagel Selectmenu: removed ugly workaround for IE9 to make sure the menu is …
…built on first focus
ed422bd
@fnagel fnagel Selectmenu: revert change to text instead of html, otherwise the unic…
…ode special char wont be displayed
8901960
@fnagel fnagel Selectmenu: replace placeholder entity with &#160; c69d01b
@fnagel fnagel Selectmenu: fix closing of empty selects 1ea2256
@fnagel fnagel Selectmenu tests: improve and merge visual tests 21e46b8
Member
fnagel commented Dec 13, 2012

Let's clean up the visual tests. They are useful while prototyping, but need to be replaced by unit tests. Units are all there, so let's remove most of the visual tests, maybe merge one from each into a composite one.

Hey @jzaefferer, I know you want to get rid of the visual tests but they are very useful for testing issues and while developing. I've merged some again. Only three files left, hope thats ok.

Owner

Looking pretty good. Still need to ui-front and icons updates, pinged Scott about that. Also looking for @hanshillen to help with the aria tweaks. Once that is done, I'll rebase my branch and merge it in here.

Owner

.ui-front implementation in autocomplete: 80e46c9

Member
fnagel commented Dec 14, 2012

Thanks @scottgonzalez, I will take a look asap. For now, its "The Hobbit" time :-)

@scottgonzalez scottgonzalez commented on the diff Dec 18, 2012
demos/selectmenu/custom_render.html
+ <meta charset="utf-8">
+ <title>jQuery UI Selectmenu - Default functionality</title>
+ <link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">
+ <script src="../../jquery-1.8.3.js"></script>
+ <script src="../../ui/jquery.ui.core.js"></script>
+ <script src="../../ui/jquery.ui.widget.js"></script>
+ <script src="../../ui/jquery.ui.position.js"></script>
+ <script src="../../ui/jquery.ui.menu.js"></script>
+ <script src="../../ui/jquery.ui.selectmenu.js"></script>
+ <link rel="stylesheet" href="../demos.css">
+ <script>
+ $(function() {
+
+ $.widget( "custom.iconselectmenu", $.ui.selectmenu, {
+ _renderItem: function( ul, item ) {
+ var li = $( "<li />" ).data( "ui-selectmenu-item", item );
scottgonzalez
scottgonzalez Dec 18, 2012 Owner

no XML; use "<li>"

fnagel
fnagel Dec 18, 2012 Member

Fixed.

@scottgonzalez scottgonzalez commented on the diff Dec 18, 2012
demos/selectmenu/custom_render.html
+ <script src="../../ui/jquery.ui.core.js"></script>
+ <script src="../../ui/jquery.ui.widget.js"></script>
+ <script src="../../ui/jquery.ui.position.js"></script>
+ <script src="../../ui/jquery.ui.menu.js"></script>
+ <script src="../../ui/jquery.ui.selectmenu.js"></script>
+ <link rel="stylesheet" href="../demos.css">
+ <script>
+ $(function() {
+
+ $.widget( "custom.iconselectmenu", $.ui.selectmenu, {
+ _renderItem: function( ul, item ) {
+ var li = $( "<li />" ).data( "ui-selectmenu-item", item );
+ if ( item.disabled ) {
+ li.addClass( 'ui-state-disabled' ).text( item.label );
+ } else {
+ el = item.element;
scottgonzalez
scottgonzalez Dec 18, 2012 Owner

Never use el, use element. This is also never declared.

fnagel
fnagel Dec 18, 2012 Member

Fixed.

@scottgonzalez scottgonzalez commented on the diff Dec 18, 2012
demos/selectmenu/custom_render.html
+ <script src="../../ui/jquery.ui.widget.js"></script>
+ <script src="../../ui/jquery.ui.position.js"></script>
+ <script src="../../ui/jquery.ui.menu.js"></script>
+ <script src="../../ui/jquery.ui.selectmenu.js"></script>
+ <link rel="stylesheet" href="../demos.css">
+ <script>
+ $(function() {
+
+ $.widget( "custom.iconselectmenu", $.ui.selectmenu, {
+ _renderItem: function( ul, item ) {
+ var li = $( "<li />" ).data( "ui-selectmenu-item", item );
+ if ( item.disabled ) {
+ li.addClass( 'ui-state-disabled' ).text( item.label );
+ } else {
+ el = item.element;
+ $( "<a />", {
@scottgonzalez scottgonzalez commented on the diff Dec 18, 2012
demos/selectmenu/custom_render.html
+ <script src="../../ui/jquery.ui.position.js"></script>
+ <script src="../../ui/jquery.ui.menu.js"></script>
+ <script src="../../ui/jquery.ui.selectmenu.js"></script>
+ <link rel="stylesheet" href="../demos.css">
+ <script>
+ $(function() {
+
+ $.widget( "custom.iconselectmenu", $.ui.selectmenu, {
+ _renderItem: function( ul, item ) {
+ var li = $( "<li />" ).data( "ui-selectmenu-item", item );
+ if ( item.disabled ) {
+ li.addClass( 'ui-state-disabled' ).text( item.label );
+ } else {
+ el = item.element;
+ $( "<a />", {
+ html: icon = '<span style="' + el.attr("style") + '" class="ui-icon ' + el.attr("class") + '"></span>' + item.label,
scottgonzalez
scottgonzalez Dec 18, 2012 Owner

Strings always use double quotes.

scottgonzalez
scottgonzalez Dec 18, 2012 Owner

Don't assign inside an assignment like this. Don't build HTML strings from HTML.

fnagel
fnagel Dec 18, 2012 Member

Fixed. I've tried to get rid of all CGL issues in this file.

@scottgonzalez scottgonzalez commented on the diff Dec 18, 2012
demos/selectmenu/custom_render.html
+ <script src="../../ui/jquery.ui.menu.js"></script>
+ <script src="../../ui/jquery.ui.selectmenu.js"></script>
+ <link rel="stylesheet" href="../demos.css">
+ <script>
+ $(function() {
+
+ $.widget( "custom.iconselectmenu", $.ui.selectmenu, {
+ _renderItem: function( ul, item ) {
+ var li = $( "<li />" ).data( "ui-selectmenu-item", item );
+ if ( item.disabled ) {
+ li.addClass( 'ui-state-disabled' ).text( item.label );
+ } else {
+ el = item.element;
+ $( "<a />", {
+ html: icon = '<span style="' + el.attr("style") + '" class="ui-icon ' + el.attr("class") + '"></span>' + item.label,
+ href: '#'
scottgonzalez
scottgonzalez Dec 18, 2012 Owner

double quotes

fnagel
fnagel Dec 18, 2012 Member

Fixed.

Owner

Closing this PR since notification emails mostly lead to "outdated diff", so nowhere and its generally just crazy long. Will create a new one from the same branch.

@jzaefferer jzaefferer closed this Dec 18, 2012
This was referenced Dec 18, 2012
@scottgonzalez
Owner

@robertbeuligmann Can you please sign our CLA?

Contributor
Owner

Thanks Robert.

@scottgonzalez
Owner

@danwellman Can you please sign our CLA?

Contributor

Done :)

Owner

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment