Skip to content
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

feat(select): add md-select-header directive #3211

Closed
wants to merge 5 commits into from

Conversation

crisbeto
Copy link
Member

Adds a md-select-header component, which is a fixed header above the select's options. It allows for the user to project an input to be used for filtering long lists of options.

Note: This component only handles the positioning, styling and exposes the panel id for a11y. The functionality is up to the user to handle.

Fixes #2812.

@googlebot googlebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label Feb 20, 2017
@fxck
Copy link
Contributor

fxck commented Feb 21, 2017

Would it be worth adding an example in the demo showing a bit more reactive way of doing that filtering (could also be used as async search example)?

I could try putting something together.

Also I think md-select-header should take care of autofocusing the search input.

// edit this could be a start fxck@f0dd2ec

@fxck
Copy link
Contributor

fxck commented Mar 21, 2017

@kara hi, I know you are probably busy with whatever you are currently working on on material2 and form improvements in angular itself as well as preparing for upcoming conferences, but could you perhaps please take a look at these two #3211 #3341 select-related PRs from @crisbeto? They are not big changes in the codebase itself and both are very desirable features of the select box I'm sure many many people would appreciate.. Thank you.

@@ -19,7 +19,7 @@ import {
} from '@angular/forms';
import {ViewportRuler} from '../core/overlay/position/viewport-ruler';

describe('MdSelect', () => {
fdescribe('MdSelect', () => {
Copy link

Choose a reason for hiding this comment

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

I believe the build is failing because of the f before describe

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 is, but it's not the only issue. I'll get it passing once I get some feedback on it.

@Eernie
Copy link

Eernie commented Mar 24, 2017

@kara Do you have an ETA for this pull request. I'd love see this merged 👍

@Jagpreet16
Copy link

@kara By when can we expect this feature to be available?

@gedclack
Copy link

excuse me, is md-select-header implemented on beta.3 ?

@fxck
Copy link
Contributor

fxck commented Apr 11, 2017

@gedclack as you can see, this PR is not merged, not even reviewed, so no

@badre429
Copy link

please work on this pr

@fxck
Copy link
Contributor

fxck commented Apr 23, 2017

Any chance this will get implemented in the next like.. 4 months? It's a little unpleasant to have to maintain my own build of material2 because of these two(#3211 #3341) rather small, but pretty important for interfaces of any serious application, features that are like 20 LOC of actual non breaking changes to the codebase in total.

@kara @crisbeto @jelbourn could these please get some attention?

@fxck
Copy link
Contributor

fxck commented May 25, 2017

😰

@zyarnold
Copy link

any news for this yet?

@fxck
Copy link
Contributor

fxck commented Jun 9, 2017

Any updates? It's been four months.

@jelbourn
Copy link
Member

jelbourn commented Jun 9, 2017

We still plan on doing this, it's just been on the back-burner as other things have been higher priority

@fxck
Copy link
Contributor

fxck commented Jun 10, 2017

@jelbourn while I totally understand that there were/are things with higher priority, wouldn't it be worth dedicating, say, one day in a month to review and merge these small PRs that are low in effort and pretty damn high in value for consumers?

What are you using to decide the priority? Are you using one of these (1, 2) by any chance? Are you planning on involving the community in the decision in any way in the future?

@jelbourn
Copy link
Member

The reason this one in particular was back-burnered was that we needed to figure out what the a11y story for this feature is. It would be very easy for someone to break the a11y of the select this this, which is something we want to put some effort into avoiding.

@irackley-mc
Copy link

@jelbourn Thanks for the update on this. Had been waiting a while wondering why there was no traction on this. Guess I'll have to do a custom build for now but hopefully some priority can be added to this, as I agree with @fxck and it is a great value add.

Adds a `md-select-header` component, which is a fixed header above the select's options. It allows for the user to project an input to be used for filtering long lists of options.

**Note:** This component only handles the positioning, styling and exposes the panel id for a11y. The functionality is up to the user to handle.

Fixes angular#2812.
@crisbeto
Copy link
Member Author

@jelbourn I've cleaned up and rebased this one.

<md-card *ngIf="showSelect">
<md-select placeholder="Drink" [(ngModel)]="currentDrink" #selectWitHeader="mdSelect">
<md-select-header>
<input type="search" [(ngModel)]="searchTerm" role="combobox" [attr.aria-owns]="selectWitHeader.panelId"
Copy link
Member

Choose a reason for hiding this comment

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

In this demo, if I select a value and then try to type into the input then the focus leaves the text input on every keypress

Copy link
Member Author

@crisbeto crisbeto Jun 18, 2017

Choose a reason for hiding this comment

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

Hmm you're right. This complicates things a lot, because it means that we'd need two different key handling strategies depending on whether the select has a header (FocusKeyManager by default and ActiveDescendantKeyManager if there's a header), which in turn will complicate the select even more, because it would have to delegate to the header in some cases but not in others. I can see how it can turn into a huge mess pretty quickly since we'd need to sprinkle if (this.header) all over the place and there would be a MdSelect <-> MdSelectHeader dependency. It might be best if we park and rethink whether we want to do this or recommend that people use md-autocomplete instead.

Copy link
Contributor

Choose a reason for hiding this comment

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

or recommend that people use md-autocomplete instead.

just not this, please, searching is not the sole use case for the select header and even if it was, autocomplete has it's own problems that make it hard to use as a select.. #3334

<md-card *ngIf="showSelect">
<md-select placeholder="Drink" [(ngModel)]="currentDrink" #selectWitHeader="mdSelect">
<md-select-header>
<input type="search" [(ngModel)]="searchTerm" role="combobox" [attr.aria-owns]="selectWitHeader.panelId"
Copy link
Member

Choose a reason for hiding this comment

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

Did you try this out in a screen reader w/ this role/aria-owns? I'm not sure it will work as expected
(what I had been talking about the other day was that to do this property you would need to revamp how the roles on select are set up completely)

<ng-content select="md-select-header, mat-select-header"></ng-content>
</div>

<div class="mat-select-content" [attr.id]="panelId" [@fadeInContent]="'showing'"
Copy link
Member

Choose a reason for hiding this comment

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

I think just [id] should work here

@@ -35,7 +35,12 @@
[style.transformOrigin]="_transformOrigin"
[class.mat-select-panel-done-animating]="_panelDoneAnimating">

<div class="mat-select-content" [@fadeInContent]="'showing'" (@fadeInContent.done)="_onFadeInDone()">
<div [@fadeInContent]="'showing'">
Copy link
Member

Choose a reason for hiding this comment

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

I think you could replace this div with an ng-container

border-bottom: solid 1px;
box-sizing: border-box;

input {
Copy link
Member

Choose a reason for hiding this comment

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

I'd lean toward omitting this style in the select itself, since the select header is mean to be a generic container that's not necessarily used for this style of filter (even if that is the most common use case)

Copy link
Member Author

@crisbeto crisbeto Jun 15, 2017

Choose a reason for hiding this comment

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

The issue with allowing anything inside the header is that, with the way it is currently set up, the positioning won't work with anything that isn't 48px high. Alternatively, I can hard-code the header height.

Copy link
Member

Choose a reason for hiding this comment

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

I'd rather do that for now and then revisit the positioning to make it more flexible in the future.

@crisbeto crisbeto added the needs: discussion Further discussion with the team is needed before proceeding label Jun 18, 2017
@fxck
Copy link
Contributor

fxck commented Jul 17, 2017

So is this on hold now again? @jelbourn @crisbeto

@crisbeto
Copy link
Member Author

It is until we can figure out a decent way to handle the accessibility.

@benb7760
Copy link

benb7760 commented Aug 17, 2017

@crisbeto Have found a few more issues that haven't been mentioned above when using this;

  1. With two or more options with the same key, and one is selected, when option is filtered out and then unfiltered again, the first option with that value is selected and the other(s) ignored. This behaviour doesn't present in normal select as the options are never removed. Should an error be thrown when providing multiple options with same value?
  2. In multiple mode, if I select some options then apply a filter which hides some of the selected options, then select a new option, when i remove the filter, any that were selected but hidden are no longer selected. This is probably because the selection model is updated based on the options property, which does not contain options when filtered out

I am keeping my own branch for this PR, updated to master, with a basic fix for the focus issue mentioned by jelbourn. I intend to fix the other two issues also, as I need the feature. Would it be useful for me to make a PR for this when done?

@crisbeto
Copy link
Member Author

@benb7760 it's not the functionality that stopped this from being pushed through, but rather the accessibility story. I have a task on my list to refactor the select focus management so it can handle having a header.

crisbeto added a commit to crisbeto/material2 that referenced this pull request Sep 5, 2017
* Refactors the select to use `aria-activedescendant` to announce the highlighted item to screen readers. Previously we would this through focus, however using focus prevents us from being able to do things like angular#3211.
* Fixes a hack that was used to get a hold of the panel element using `querySelector`. Now it properly uses a `ViewChild` query, however this meant some tests had to be updated.

Relates to angular#3211.
Fixes angular#6690.
crisbeto added a commit to crisbeto/material2 that referenced this pull request Sep 6, 2017
* Refactors the select to use `aria-activedescendant` to announce the highlighted item to screen readers. Previously we would this through focus, however using focus prevents us from being able to do things like angular#3211.
* Fixes a hack that was used to get a hold of the panel element using `querySelector`. Now it properly uses a `ViewChild` query, however this meant some tests had to be updated.

Relates to angular#3211.
Fixes angular#6690.
crisbeto added a commit to crisbeto/material2 that referenced this pull request Sep 13, 2017
* Refactors the select to use `aria-activedescendant` to announce the highlighted item to screen readers. Previously we would this through focus, however using focus prevents us from being able to do things like angular#3211.
* Fixes a hack that was used to get a hold of the panel element using `querySelector`. Now it properly uses a `ViewChild` query, however this meant some tests had to be updated.

Relates to angular#3211.
Fixes angular#6690.
crisbeto added a commit to crisbeto/material2 that referenced this pull request Sep 19, 2017
* Refactors the select to use `aria-activedescendant` to announce the highlighted item to screen readers. Previously we would this through focus, however using focus prevents us from being able to do things like angular#3211.
* Fixes a hack that was used to get a hold of the panel element using `querySelector`. Now it properly uses a `ViewChild` query, however this meant some tests had to be updated.

Relates to angular#3211.
Fixes angular#6690.
crisbeto added a commit to crisbeto/material2 that referenced this pull request Sep 23, 2017
* Refactors the select to use `aria-activedescendant` to announce the highlighted item to screen readers. Previously we would this through focus, however using focus prevents us from being able to do things like angular#3211.
* Fixes a hack that was used to get a hold of the panel element using `querySelector`. Now it properly uses a `ViewChild` query, however this meant some tests had to be updated.

Relates to angular#3211.
Fixes angular#6690.
crisbeto added a commit to crisbeto/material2 that referenced this pull request Sep 29, 2017
* Refactors the select to use `aria-activedescendant` to announce the highlighted item to screen readers. Previously we would this through focus, however using focus prevents us from being able to do things like angular#3211.
* Fixes a hack that was used to get a hold of the panel element using `querySelector`. Now it properly uses a `ViewChild` query, however this meant some tests had to be updated.

Relates to angular#3211.
Fixes angular#6690.
crisbeto added a commit to crisbeto/material2 that referenced this pull request Sep 30, 2017
* Refactors the select to use `aria-activedescendant` to announce the highlighted item to screen readers. Previously we would this through focus, however using focus prevents us from being able to do things like angular#3211.
* Fixes a hack that was used to get a hold of the panel element using `querySelector`. Now it properly uses a `ViewChild` query, however this meant some tests had to be updated.

Relates to angular#3211.
Fixes angular#6690.
kara pushed a commit that referenced this pull request Oct 3, 2017
@fxck
Copy link
Contributor

fxck commented Oct 6, 2017

Looks like this can now be done, now that #6856 is in?

@crisbeto
Copy link
Member Author

crisbeto commented Oct 6, 2017

Yes the a11y shouldn't be an issue anymore. I might have to resubmit it though since it'll take a while to rebase this.

@badre429
Copy link

badre429 commented Oct 8, 2017

@crisbeto is there any timeline for this feature

@crisbeto
Copy link
Member Author

Closing in favor of #7835.

@crisbeto crisbeto closed this Oct 16, 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 8, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
cla: yes PR author has agreed to Google's Contributor License Agreement needs: discussion Further discussion with the team is needed before proceeding
Projects
None yet
Development

Successfully merging this pull request may close these issues.

feat(select): Add select header to the md-select