Skip to content

Commit

Permalink
feat(dialog): value for md-dialog-close button
Browse files Browse the repository at this point in the history
* Values can be bound to the md-dialog-close directive and the value will be returned automatically to the `DialogRef`.

Closes angular#4421
  • Loading branch information
devversion committed May 8, 2017
1 parent 525ce1e commit c5f33eb
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 11 deletions.
8 changes: 7 additions & 1 deletion src/lib/dialog/dialog-content-directives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,21 @@ import {MdDialogRef} from './dialog-ref';
@Directive({
selector: 'button[md-dialog-close], button[mat-dialog-close]',
host: {
'(click)': 'dialogRef.close()',
'(click)': 'dialogRef.close(dialogResult)',
'[attr.aria-label]': 'ariaLabel',
'type': 'button', // Prevents accidental form submits.
}
})
export class MdDialogClose {
/** Result that will be returned to the dialog opener. */
@Input('md-dialog-close') dialogResult: any;

/** Screenreader label for the button. */
@Input('aria-label') ariaLabel: string = 'Close dialog';

/** Dialog close input for compatibility mode. */
@Input('mat-dialog-close') _matDialogClose(value: any) { this.dialogResult = value; }

constructor(public dialogRef: MdDialogRef<any>) { }
}

Expand Down
47 changes: 37 additions & 10 deletions src/lib/dialog/dialog.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -558,46 +558,69 @@ describe('MdDialog', () => {

describe('dialog content elements', () => {
let dialogRef: MdDialogRef<ContentElementDialog>;
let closeDialogButton: HTMLButtonElement;
let closeDialogDiv: HTMLElement;

beforeEach(() => {
dialogRef = dialog.open(ContentElementDialog);
viewContainerFixture.detectChanges();

closeDialogButton = overlayContainerElement
.querySelector('button') as HTMLButtonElement;
closeDialogDiv = overlayContainerElement.querySelector('#dialog-close-div') as HTMLElement;
});

it('should close the dialog when clicking on the close button', async(() => {
expect(overlayContainerElement.querySelectorAll('.mat-dialog-container').length).toBe(1);

(overlayContainerElement.querySelector('button[md-dialog-close]') as HTMLElement).click();
closeDialogButton.click();
viewContainerFixture.detectChanges();

viewContainerFixture.whenStable().then(() => {
expect(overlayContainerElement.querySelectorAll('.mat-dialog-container').length).toBe(0);
});
}));

it('should close the dialog with the specified value on the close button', async(() => {
const afterCloseCallback = jasmine.createSpy('afterClose callback');

// Subscribe to the afterClosed observable to keep track of the close value.
dialogRef.afterClosed().subscribe(afterCloseCallback);

expect(overlayContainerElement.querySelectorAll('.mat-dialog-container').length).toBe(1);

// Set the result for the close button to some value.
dialogRef.componentInstance.closeResult = 'Works';
viewContainerFixture.detectChanges();

closeDialogButton.click();
viewContainerFixture.detectChanges();

viewContainerFixture.whenStable().then(() => {
expect(afterCloseCallback).toHaveBeenCalledWith('Works');
expect(overlayContainerElement.querySelectorAll('.mat-dialog-container').length).toBe(0);
});
}));

it('should not close the dialog if [md-dialog-close] is applied on a non-button node', () => {
expect(overlayContainerElement.querySelectorAll('.mat-dialog-container').length).toBe(1);

(overlayContainerElement.querySelector('div[md-dialog-close]') as HTMLElement).click();
closeDialogDiv.click();

expect(overlayContainerElement.querySelectorAll('.mat-dialog-container').length).toBe(1);
});

it('should allow for a user-specified aria-label on the close button', async(() => {
let button = overlayContainerElement.querySelector('button[md-dialog-close]');

dialogRef.componentInstance.closeButtonAriaLabel = 'Best close button ever';
viewContainerFixture.detectChanges();

viewContainerFixture.whenStable().then(() => {
expect(button.getAttribute('aria-label')).toBe('Best close button ever');
expect(closeDialogButton.getAttribute('aria-label')).toBe('Best close button ever');
});
}));

it('should override the "type" attribute of the close button', () => {
let button = overlayContainerElement.querySelector('button[md-dialog-close]');

expect(button.getAttribute('type')).toBe('button');
expect(closeDialogButton.getAttribute('type')).toBe('button');
});

});
Expand Down Expand Up @@ -713,13 +736,17 @@ class PizzaMsg {
<h1 md-dialog-title>This is the title</h1>
<md-dialog-content>Lorem ipsum dolor sit amet.</md-dialog-content>
<md-dialog-actions>
<button md-dialog-close [aria-label]="closeButtonAriaLabel">Close</button>
<div md-dialog-close>Should not close</div>
<button [md-dialog-close]="closeResult" [aria-label]="closeButtonAriaLabel"
id="dialog-close-button">
Close
</button>
<div md-dialog-close id="dialog-close-div">Should not close</div>
</md-dialog-actions>
`
})
class ContentElementDialog {
closeButtonAriaLabel: string;
closeResult: any;
}

@Component({
Expand Down

0 comments on commit c5f33eb

Please sign in to comment.