Opened 7 years ago

Closed 4 years ago

#16266 closed defect (patchwelcome)

Toolbar: overrides TextBox etc. arrow key behavior (ToolbarGroup enhancement)

Reported by: noxryan Owned by: bill
Priority: high Milestone: 1.13
Component: Dijit Version: 1.8.0
Keywords: Cc: Becky Gibson, mikeb
Blocked By: Blocking:

Description (last modified by bill)

When you create a dijit.Toolbar that contains a dijit.TextBox, the arrow key behavior from _KeyNavContainer overrides the TextBox's default behavior. This makes it so you can't move the cursor's position using the arrow keys within the TextBox.

Example: http://jsfiddle.net/VrtRe/2/

  1. Type something in the TextBox
  2. Press arrow keys

Attachments (2)

test_Toolbar.html (2.4 KB) - added by bill 7 years ago.
prototype of separate Toolbar and ToolbarGroup widgets, showing how to achieve against 1.8 code base (put in dijit/tests directory, overriding current test_Toolbar.html file)
test_Toolbar.2.html (2.7 KB) - added by bill 7 years ago.
updated test with minimal Toolbar widget prototype, and experiment in alternate styling of wrapping groups in a border

Download all attachments as: .zip

Change History (12)

comment:1 Changed 7 years ago by bill

Cc: Becky Gibson mikeb added
Description: modified (diff)
Owner: changed from bill to noxryan
Status: newpending
Summary: dijit.Toolbar overrides dijit.TextBox arrow key behaviorToolbar: overrides dijit.TextBox arrow key behavior

Yes, that's right.

How would you like it to work? I don't see a practical solution to make arrows work inside a TextBox in a Toolbar while still being able to navigate to the other widgets in the Toolbar. So, I'm tempted to close this as wontfix, saying that you can't have a TextBox in a Toolbar.

I did compare to MSOffice... in that software, you can use arrow keys to navigate within ComboBox type widgets in the toolbar, but you can't use arrows to navigate across buttons in the toolbar. That means the Toolbar is not accessible, but that's OK because the menu above the Toolbar is accessible.

We could take that approach too, requiring that all web apps built with dojo have a menu in addition to a toolbar, but it doesn't seem realistic that app developers would actually do that. I'm sure there are lots of apps with only toolbars and no corresponding menus.

comment:2 Changed 7 years ago by noxryan

Status: pendingnew

I understand that there is no great fix for this. Possibly just a property for the toolbar to disable key navigation for people who have TextBoxes in their toolbars.

comment:3 Changed 7 years ago by bill

Milestone: tbd2.0
Owner: changed from noxryan to bill
Status: newassigned
Summary: Toolbar: overrides dijit.TextBox arrow key behaviorToolbar: overrides TextBox etc. arrow key behavior
Version: 1.8.0

Fair enough.

I checked http://test.cita.illinois.edu/aria/toolbar/index.php a.k.a. http://oaa-accessibility.org/examplep/toolbar1/, and like dojo, it uses arrows to navigate between buttons. However, it uses tabs to navigate between groups of buttons, or technically speaking, what visually looks like one toolbar is semantically multiple toolbars (with multiple role=toolbar designations), and the tab key navigates between them.

It makes me think that long term (I guess for 2.0), we might want to make toolbar groups inside of toolbars, like what's visually achieved by the ToolbarSeparator in Dojo 0.4 (and in other products like Microsoft Word). Maybe some sort of syntax like:

<div data-dojo-type="dijit/Toolbar">
     <div data-dojo-type="dijit/ToolbarGroup">
          ...
     </div>
     <div data-dojo-type="dijit/ToolbarGroup">
          ...
     </div>
</div>

dijit/Toolbar would probably just be CSS, literally just assigning the dijitToolbar class to the DOMNode. dijit/ToolbarGroup would have the left/right arrow key handling, and no CSS except maybe for a fieldset-like border around the group.

It turns out that you can hack this yourself with the current 1.8 release, by defining your own ToolbarGroup class:

ToolbarGroup = declare([_Widget, _KeyNavContainer], {
        postCreate: function(){
                this.inherited(arguments);

                this.set("tabIndex", this.tabIndex);    // otherwise not set, see #7381
                this.connectKeyNavHandlers(
                        this.isLeftToRight() ? [keys.LEFT_ARROW] : [keys.RIGHT_ARROW],
                        this.isLeftToRight() ? [keys.RIGHT_ARROW] : [keys.LEFT_ARROW]
                );
        }
});

and then using it:

<div id="toolbar1" class="dijitToolbar" role="presentation">
        <span id="toolbar1Group1" data-dojo-type="ToolbarGroup">
                <button id="toolbar1.cut" data-dojo-type="dijit/form/Button" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut", showLabel:false'>Cut</button>
                <button id="toolbar1.copy" data-dojo-type="dijit/form/Button" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy", showLabel:true'>Copy</button>
        </span>
        <div data-dojo-type="dijit/ToolbarSeparator"></div>

        <label for="tb">the textbox:</label>
        <input id="tb" value="hi"/>
        <div data-dojo-type="dijit/ToolbarSeparator"></div>

        <span id="toolbar1Group2" data-dojo-type="ToolbarGroup">
                <button id="toolbar1.bold" data-dojo-type="dijit/form/ToggleButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconBold", showLabel:false'>Bold</button>
                <button id="toolbar1.italic" data-dojo-type="dijit/form/ToggleButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconItalic", showLabel:false'>Italic</button>
        </span>
</div>

Does that work for you? I'll attach the full source code for the workaround.

I'm thinking that workaround is enough to defer this problem until 2.0, so marking this ticket as 2.0 for now.

Changed 7 years ago by bill

Attachment: test_Toolbar.html added

prototype of separate Toolbar and ToolbarGroup widgets, showing how to achieve against 1.8 code base (put in dijit/tests directory, overriding current test_Toolbar.html file)

comment:4 Changed 7 years ago by bill

Summary: Toolbar: overrides TextBox etc. arrow key behaviorToolbar: overrides TextBox etc. arrow key behavior (ToolbarGroup enhancement)

Changed 7 years ago by bill

Attachment: test_Toolbar.2.html added

updated test with minimal Toolbar widget prototype, and experiment in alternate styling of wrapping groups in a border

comment:5 Changed 7 years ago by bill

Priority: undecidedhigh

comment:6 Changed 7 years ago by musicdemo

I solved this by catching the arrow keys as well as the home and end keys in the textbox onKeyPress method and using "stopPropagation()" like this:

            var searchTextBox = new Textbox({
                class: SEARCH_TEXT_CLASS,
                onKeyPress: function (e) {
                    if ((e.which && e.which == 37) || (e.keyCode && e.keyCode == 37)
                        || (e.which && e.which == 39) || (e.keyCode && e.keyCode == 39)
                        || (e.which && e.which == 35) || (e.keyCode && e.keyCode == 35)
                        || (e.which && e.which == 36) || (e.keyCode && e.keyCode == 36)) {
                        e.stopPropagation();
                    }
                }
            });

comment:7 Changed 6 years ago by Karl Tiedt

FWIW, this also affects dijit/form/Select in a toolbar - if you navigate to a Select while using the keyboard you get trapped there

Figured I would toss that out as well since this was still open and could potentially be covered by a related fix.

comment:8 in reply to:  1 Changed 6 years ago by Karl Tiedt

Replying to bill:

Yes, that's right.

How would you like it to work? I don't see a practical solution to make arrows work inside a TextBox in a Toolbar while still being able to navigate to the other widgets in the Toolbar. So, I'm tempted to close this as wontfix, saying that you can't have a TextBox in a Toolbar.

I did compare to MSOffice... in that software, you can use arrow keys to navigate within ComboBox type widgets in the toolbar, but you can't use arrows to navigate across buttons in the toolbar. That means the Toolbar is not accessible, but that's OK because the menu above the Toolbar is accessible.

We could take that approach too, requiring that all web apps built with dojo have a menu in addition to a toolbar, but it doesn't seem realistic that app developers would actually do that. I'm sure there are lots of apps with only toolbars and no corresponding menus.

I would need to do some testing to remember the exact fix, but when I was working with IBM we had tackled a similar problem with textbox in Toolbar by adding additional logic to test for the cursor position in the textbox widget and allowing arrow keys to work natively if the cursor was at the respective limit for that direction.... IE: cursor pos = 0 LEFT goes to previous toolbar item, cursor pos = LEN - RIGHT arrow goes to next item.

comment:9 Changed 6 years ago by bill

this also affects dijit/form/Select in a toolbar - if you navigate to a Select while using the keyboard you get trapped there

Thanks, sounds like Select is calling evt.stopPropagation() for the left and right arrows (or for all keys) when it shouldn't be. I filed #17859 to track it.

IE: cursor pos = 0 LEFT goes to previous toolbar item, cursor pos = LEN - RIGHT arrow goes to next item.

That would be a way to solve it in 1.x. Complicated to implement, but would work well. I'm not sure how to get the caret position though.

comment:10 Changed 4 years ago by dylan

Milestone: 2.01.12
Resolution: patchwelcome
Status: assignedclosed

Given that no one has shown interest in creating a patch in the past 2+ years, I'm closing this as patchwelcome.

Note: See TracTickets for help on using tickets.