Skip to content

Commit

Permalink
fix(checkbox): Add RequiredTrue validator for md-checkbox (#6006)
Browse files Browse the repository at this point in the history
* Try to make screenshot image size same as before

* change back to 1024 x 768

* Add MdCehckboxRequiredValidator

* extends CheckboxRequiredValidator

* Workaround for aot build error

* Add doc

* fix test
  • Loading branch information
tinayuangao authored and andrewseguin committed Jul 27, 2017
1 parent a87a000 commit 59319d0
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 4 deletions.
41 changes: 41 additions & 0 deletions src/lib/checkbox/checkbox-required-validator.ts
@@ -0,0 +1,41 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {
Directive,
forwardRef,
Provider,
} from '@angular/core';
import {
CheckboxRequiredValidator,
NG_VALIDATORS,
} from '@angular/forms';

export const _MdCheckboxRequiredValidator = CheckboxRequiredValidator;

export const MD_CHECKBOX_REQUIRED_VALIDATOR: Provider = {
provide: NG_VALIDATORS,
useExisting: forwardRef(() => MdCheckboxRequiredValidator),
multi: true
};

/**
* Validator for Material checkbox's required attribute in template-driven checkbox.
* Current CheckboxRequiredValidator only work with `input type=checkbox` and does not
* work with `md-checkbox`.
*/
@Directive({
selector:
'md-checkbox[required][formControlName],' +
'mat-checkbox[required][formControlName],' +
'md-checkbox[required][formControl],md-checkbox[required][ngModel],' +
'mat-checkbox[required][formControl],mat-checkbox[required][ngModel]',
providers: [MD_CHECKBOX_REQUIRED_VALIDATOR],
host: {'[attr.required]': 'required ? "" : null'}
})
export class MdCheckboxRequiredValidator extends _MdCheckboxRequiredValidator {}
47 changes: 46 additions & 1 deletion src/lib/checkbox/checkbox.spec.ts
Expand Up @@ -26,6 +26,7 @@ describe('MdCheckbox', () => {
SingleCheckbox,
CheckboxWithFormDirectives,
MultipleCheckboxes,
CheckboxWithNgModel,
CheckboxWithTabIndex,
CheckboxWithAriaLabel,
CheckboxWithAriaLabelledby,
Expand Down Expand Up @@ -735,6 +736,41 @@ describe('MdCheckbox', () => {
});
});

describe('with required ngModel', () => {
let checkboxInstance: MdCheckbox;
let inputElement: HTMLInputElement;
let testComponent: CheckboxWithNgModel;

beforeEach(() => {
fixture = TestBed.createComponent(CheckboxWithNgModel);
fixture.detectChanges();

let checkboxDebugElement = fixture.debugElement.query(By.directive(MdCheckbox));
let checkboxNativeElement = checkboxDebugElement.nativeElement;
testComponent = fixture.debugElement.componentInstance;
checkboxInstance = checkboxDebugElement.componentInstance;
inputElement = <HTMLInputElement>checkboxNativeElement.querySelector('input');
});

it('should validate with RequiredTrue validator', () => {
let checkboxElement = fixture.debugElement.query(By.directive(MdCheckbox));
let ngModel = checkboxElement.injector.get<NgModel>(NgModel);

testComponent.isRequired = true;
inputElement.click();
fixture.detectChanges();

expect(checkboxInstance.checked).toBe(true);
expect(ngModel.valid).toBe(true);

inputElement.click();
fixture.detectChanges();

expect(checkboxInstance.checked).toBe(false);
expect(ngModel.valid).toBe(false);
});
});

describe('with name attribute', () => {
beforeEach(() => {
fixture = TestBed.createComponent(CheckboxWithNameAttribute);
Expand Down Expand Up @@ -874,7 +910,7 @@ class SingleCheckbox {
onCheckboxChange: (event?: MdCheckboxChange) => void = () => {};
}

/** Simple component for testing an MdCheckbox with ngModel. */
/** Simple component for testing an MdCheckbox with ngModel in a form. */
@Component({
template: `
<form>
Expand All @@ -886,6 +922,15 @@ class CheckboxWithFormDirectives {
isGood: boolean = false;
}

/** Simple component for testing an MdCheckbox with required ngModel. */
@Component({
template: `<md-checkbox [required]="isRequired" [(ngModel)]="isGood">Be good</md-checkbox>`,
})
class CheckboxWithNgModel {
isGood: boolean = false;
isRequired: boolean = true;
}

/** Simple test component with multiple checkboxes. */
@Component(({
template: `
Expand Down
7 changes: 4 additions & 3 deletions src/lib/checkbox/index.ts
Expand Up @@ -11,15 +11,16 @@ import {CommonModule} from '@angular/common';
import {ObserveContentModule} from '@angular/cdk/observe-content';
import {MdRippleModule, MdCommonModule, FocusOriginMonitor} from '../core';
import {MdCheckbox} from './checkbox';

import {MdCheckboxRequiredValidator} from './checkbox-required-validator';

@NgModule({
imports: [CommonModule, MdRippleModule, MdCommonModule, ObserveContentModule],
exports: [MdCheckbox, MdCommonModule],
declarations: [MdCheckbox],
exports: [MdCheckbox, MdCheckboxRequiredValidator, MdCommonModule],
declarations: [MdCheckbox, MdCheckboxRequiredValidator],
providers: [FocusOriginMonitor]
})
export class MdCheckboxModule {}


export * from './checkbox';
export * from './checkbox-required-validator';

0 comments on commit 59319d0

Please sign in to comment.