Open 1619digital opened 7 years ago
Maybe the cdk could have some flexibility to allow the end developer do this. The expansion panel follows the specs and should stay like that. An improvement in cdk docs, like a guide would be welcome, IMO.
I think #5250 is more specific about the Guide.
I've achieved that closing the expansion on click for elements that are not .mat-expansion-indicator
:
<mat-expansion-panel #matExpansionPanel>
<mat-expansion-panel-header (click)="expandPanel(matExpansionPanel, $event)">
<mat-panel-title>title</mat-panel-title>
</mat-expansion-panel-header>
...
</mat-expansion-panel>
expandPanel(matExpansionPanel: MatExpansionPanel, event: Event): void {
event.stopPropagation(); // Preventing event bubbling
if (!this._isExpansionIndicator(event.target)) {
matExpansionPanel.close(); // Here's the magic
}
}
private _isExpansionIndicator(target: EventTarget): boolean {
const expansionIndicatorClass = 'mat-expansion-indicator';
return (target.classList && target.classList.contains(expansionIndicatorClass) );
}
See Plunker http://plnkr.co/edit/Q54a57?p=preview
PS: You can add some CSS to change the cursor:default/pointer
@leocaseiro, thnx but this method have a bug. Yes, you can open panel on button only, but close on over panel . how can i to programme close only on button too?
Bump.
Noticed the same issue.
@BoJIbFbI4 This can be fixed using
matExpansionPanel.toggle();
istead of
matExpansionPanel.close();
@leocaseiro
This helps, but i find when the mat expansion header is focused, space and enter trigger the collapse, and i tried binding the key events to the same method but am unable to get the toggle event to stop.
Just a quick note/workaround if you only care about not triggering the panel for extra buttons in the header: Just use $event.stopPropagation(); on the button, i.e.
`
</button>
`
I'd still prefer a setting on the control as per this issue. Thanks.
Thanks for the workarround
I occured this issue 👍 ERROR in src/app/layout/components/factor-table/factor-table.component.ts(11,34): error TS2304: Cannot find name 'MatExpansionPanel'. src/app/layout/components/factor-table/factor-table.component.ts(21,20): error TS2339: Property 'classList' does not exist on type 'EventTarget'. src/app/layout/components/factor-table/factor-table.component.ts(21,40): error TS2339: Property 'classList' does not exist on type 'EventTarget'.
any ideau
I occured this issue 👍 ERROR in src/app/layout/components/factor-table/factor-table.component.ts(11,34): error TS2304: Cannot find name 'MatExpansionPanel'. src/app/layout/components/factor-table/factor-table.component.ts(21,20): error TS2339: Property 'classList' does not exist on type 'EventTarget'. src/app/layout/components/factor-table/factor-table.component.ts(21,40): error TS2339: Property 'classList' does not exist on type 'EventTarget'.
any ideau
Running into the same issue.
The EventTarget is HTMLElement so cast it as HTMLElement
if (!this._isExpansionIndicator(event.target as HTMLElement)) {
...
private _isExpansionIndicator(target: HTMLElement): boolean {
With CSS we can solve this problem. If we put a transparent mask on the header leaving some space for the button on right side, it will work. Here is the solution example:
HTML
<mat-accordion>
<div class="wrapper">
<div class="mask">
</div>
<mat-expansion-panel>
<mat-expansion-panel-header [expandedHeight]="'48px'">
<mat-panel-title>
Title
</mat-panel-title>
</mat-expansion-panel-header>
<p>Hello</p>
</mat-expansion-panel>
</div>
</mat-accordion>
CSS
.wrapper{
position: relative;
}
.mask{
position: absolute;
background: transparent;
width: calc(100% - 50px);
z-index: 1;
height: 48px;
}
I got a lot of expansion panels in a single page, so I can't grab each panel using Element Ref. Moreover, each panel has select or text box in header which makes me unable to put CSS layer over header. I too want similar experience of toggling expansion panel upon clicking arrow only. Is there help for me?
@rafayabedi If you put the Select or Input element inside the 'div .mask' and with css if you place the elements properly will it solve your problem? Like this...
<mat-accordion>
<div class="wrapper">
<div class="mask">
<input placeholder="Name">
</div>
<mat-expansion-panel>
<mat-expansion-panel-header [expandedHeight]="'48px'">
<mat-panel-title>
Title
</mat-panel-title>
</mat-expansion-panel-header>
<p>Hello</p>
</mat-expansion-panel>
</div>
</mat-accordion>
.wrapper{
position: relative;
}
.mask{
position: absolute;
background: transparent;
width: calc(100% - 50px);
z-index: 1;
height: 48px;
}
.mask input{
float: right;
margin: 15px
}
Issues with solutions above:
@leocaseiro - event expandedChange
fires 2 times
@SubhasisDebsharma - because of position: absolute
my layout completely crashed. Don't want to fix it
My solution easy-peasy solution:
mat-expansion-panel-header {
pointer-events: none; // ignore all mouse events on parent
}
.mat-expansion-indicator {
pointer-events: all; // but allow all mouse events on child indicator icon
}
Maybe it could fit someone's case
the only issue - content of mat-expansion-panel-header
becomes untouchable
also, you may want to subscribe on<mat-expansion-panel /> click()
event
if you wanna only expand do like this
<mat-expansion-panel *ngFor="let account of accounts" (opened)="expandPanel(account)">
I've achieved that closing the expansion on click for elements that are not
.mat-expansion-indicator
:<mat-expansion-panel #matExpansionPanel> <mat-expansion-panel-header (click)="expandPanel(matExpansionPanel, $event)"> <mat-panel-title>title</mat-panel-title> </mat-expansion-panel-header> ... </mat-expansion-panel>
expandPanel(matExpansionPanel: MatExpansionPanel, event: Event): void { event.stopPropagation(); // Preventing event bubbling if (!this._isExpansionIndicator(event.target)) { matExpansionPanel.close(); // Here's the magic } } private _isExpansionIndicator(target: EventTarget): boolean { const expansionIndicatorClass = 'mat-expansion-indicator'; return (target.classList && target.classList.contains(expansionIndicatorClass) ); }
See Plunker http://plnkr.co/edit/Q54a57?p=preview
PS: You can add some CSS to change the
cursor:default/pointer
I have used this approach which stops the toggle on header click but i have controller in the header only which has an expand icon on clicking on which i want this to toggle how to do that?
i am using a mat-slide-toggle on mat expansion which resulted in opening of mat expansion even if i toggle the mat-slide. I used @
Just a quick note/workaround if you only care about not triggering the panel for extra buttons in the header: Just use $event.stopPropagation(); on the button, i.e.
<mat-panel-description> <button mat-icon-button (click)="doMyButtonThing();$event.stopPropagation();"> <mat-icon>refresh</mat-icon> </button> </mat-panel-description>
I'd still prefer a setting on the control as per this issue. Thanks.
Thanks alot for this, i was using mat-slide toggle on mat expansion which was causing the problem. using stopPropgation on mat-slide toggle works. thanks
I works for me by replacing matExpansionPanel.close(); with matExpansionPanel.toggle(); `<mat-expansion-panel #matExpansionPanel> <mat-expansion-panel-header (click)="expandPanel(matExpansionPanel, $event)">
... `
`expandPanel(matExpansionPanel: MatExpansionPanel, event: Event): void { event.stopPropagation(); if (!this._isExpansionIndicator(event.target)) { matExpansionPanel.toggle(); // just use toggle() instead of close() } }
private _isExpansionIndicator(target: EventTarget): boolean { const expansionIndicatorClass = 'mat-expansion-indicator'; return (target['classList'] && target['classList'].contains(expansionIndicatorClass) ); }`
I know this thread is very old but it is still open so i guess others could benefit from this reply, this worked for me by simply doing this
HTML
<mat-panel-title (click)="onPanelTitleClick($event)"></mat-panel-title>
TS
onPanelTitleClick(event: Event){
event.stopPropagation();
}
Bug, feature request, or proposal:
Feature request
What is the expected behavior?
Ability to optionally only open / close expansion panel when up/down arrow is selected rather than the entire panel title
What is the current behavior?
The entire title triggers the behaviour
What is the use-case or motivation for changing an existing behavior?
e.g. Outlook.com user interface - selecting a 'folder' is an action (e.g. edit the folder) - toggling its slider-like display requires action on the up/down button. Seems to make sense from a user interaction point of view. This can't be reproduced with the material expansion panel. It's useful when selecting the title implies 'more information' on this panel.
Is there anything else we should know?
Workaround (untested) - add click handler to mat-panel-title and do not propagate the event