Skip to content

fix(list-key-manager): align matching logic with native listbox #7212

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 3, 2017

Conversation

crisbeto
Copy link
Member

Currently the typeahead option of the ListKeyManager looks for matches from start to end which can lead to some weird behavior where the user might be half-way down the list, but be sent up to the first item (e.g. in a list of b, a, ba it would always find b). These changes align the behavior closer to the native listbox by looking for the next match after the active item. If no match is found, the selection wraps around and starts looking from the beginning.

@crisbeto crisbeto added Accessibility This issue is related to accessibility (a11y) pr: needs review labels Sep 20, 2017
@googlebot googlebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label Sep 20, 2017
} else if (!hasWrapped && startIndex > 0 && i === total - 1) {
i = -1;
total = startIndex;
hasWrapped = true;
Copy link
Member

@jelbourn jelbourn Sep 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use mod instead of manually wrapping?

const items = this._items.toArray();

// Start at 1 because we want to start searching at the item immediately
// following the current active item.
for (let i = 1; i < items.length; i++) {
  const index = (this._activeItemIndex + i) % items.length;
  if (items[index].getLabel!().toUpperCase().trim().indexOf(inputString) === 0) {
    this.setActiveItem(index);
    break;
  }
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm interesting. It doesn't seem to work on smaller lists though, E.g. on one of the unit tests we have a list of one, two, three but it never reaches three.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This always does what I'd expect:

var items = ['one', 'two', 'three'];
var activeIndex = 1;
for (let i = 1; i < items.length; i++) {
  const index = (activeIndex + i) % items.length;
  console.log(index, ' ', items[index]);
}

You mean for it to always skip the active item, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's supposed to skip it but then wrap around if it doesn't find anything else. I got it working like this:

for (let i = 1; i < items.length + 1; i++) {
  const index = (this._activeItemIndex + i) % items.length;
  if (items[index].getLabel!().toUpperCase().trim().indexOf(inputString) === 0) {
    this.setActiveItem(index);
    break;
  }
}

Also I think you had a typo. The this.setActiveItem(i) was supposed to be this.setActiveItem(index).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I did have that typo.

@crisbeto crisbeto force-pushed the list-key-manager-typeahead-improve branch from e122fba to c7068ba Compare September 26, 2017 20:24
Copy link
Member

@jelbourn jelbourn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jelbourn jelbourn added pr: lgtm action: merge The PR is ready for merge by the caretaker and removed pr: needs review labels Sep 26, 2017
@andrewseguin
Copy link
Contributor

Please rebase

Currently the typeahead option of the `ListKeyManager` looks for matches from start to end which can lead to some weird behavior where the user might be half-way down the list, but be sent up to the first item (e.g. in a list of `b, a, ba` it would always find `b`). These changes align the behavior closer to the native `listbox` by looking for the next match after the active item. If no match is found, the selection wraps around and starts looking from the beginning.
@crisbeto crisbeto force-pushed the list-key-manager-typeahead-improve branch from c7068ba to e7a0e5b Compare September 30, 2017 09:50
@kara kara merged commit 846cc13 into angular:master Oct 3, 2017
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 7, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Accessibility This issue is related to accessibility (a11y) action: merge The PR is ready for merge by the caretaker cla: yes PR author has agreed to Google's Contributor License Agreement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants