Question/Bug
I don't know if the current is the right behavior but I see some discrepancies between the behaviors of the input and the slide-toggle.
Slide-toggle gets its errors even when is pristine or not touched. The input gets the errors only when is not pristine/touched or when you try to submit the form.
go to: https://plnkr.co/edit/uofeSTyA2xAHEHR8RMq0?p=preview
and simply look at the difference.
The slide-toggle already has its errors.
angular version: 4.3.5
material version: 2.0.0-beta.8-6cdbf36
Am I missing something? Is this the right procedure? Don't you think it is better to create a container like md-input-container for the checkbox and slide-toggle?
The behavior seems to be different due to the ErrorStateMatcher approach for inputs.
Under the hood both form controls are having the required error set.
For the input it just doesn't show up because the errorStateMatcher is hiding the <md-error> elements inside of the input container.
cc. @mmalerba @willshowell
The errorStateMatcher logic belongs specifically to the input (and soon the select https://github.com/angular/material2/pull/6147). I dunno the future of the MdFormField, but it seems like if there's a way to capture error logic there, that would be great!
<md-form-field>
<md-slide-toggle formControlName="termsToggle">
I agree to terms and conditions
</md-slide-toggle>
<md-error>You must agree</md-error>
</md-form-field>
As I recall from point 1 of https://github.com/angular/material2/pull/4750#issuecomment-307525083, it was https://github.com/angular/material2/pull/4757 that "Moves the _isErrorState logic to the input child to avoid a circular dependency".
cc @crisbeto too
@willshowell Yeah I agree that this would be a nice way to handle errors here.
In regards to the form field, I'm not sure how well it would play together since the md-form-field element normally supports bindings like floatPlaceholder (would probably cause an ambiguous API)
I think the mat-slide-toggle (and all material form controls) should use the ErrorStateMatcher, but I don't think its a good fit to go in mat-form-field. I as actually thinking about creating a directive to set the ErrorStateMatcher that targets the [matErorrStateMatcher] selector. That way we could apply it to any element to switch out the provider for all of its children. Then we would't have to add separate inputs to every component and we could also add it on <div>s and things
inside validators.d.ts there are 2 Required Validator, one for "any controls" and one for "checkbox controls"
i think mat-slide-toggle should use CheckboxRequiredValidator instead of RequiredValidator
/**
* A Directive that adds the `required` validator to any controls marked with the
* `required` attribute, via the {@link NG_VALIDATORS} binding.
*
* ### Example
*
* ```
* <input name="fullName" ngModel required>
* ```
*
* @stable
*/
export declare class RequiredValidator implements Validator {
private _required;
private _onChange;
required: boolean | string;
validate(c: AbstractControl): ValidationErrors | null;
registerOnValidatorChange(fn: () => void): void;
}
/**
* A Directive that adds the `required` validator to checkbox controls marked with the
* `required` attribute, via the {@link NG_VALIDATORS} binding.
*
* ### Example
*
* ```
* <input type="checkbox" name="active" ngModel required>
* ```
*
* @experimental
*/
export declare class CheckboxRequiredValidator extends RequiredValidator {
validate(c: AbstractControl): ValidationErrors | null;
}
Most helpful comment
I think the
mat-slide-toggle(and all material form controls) should use theErrorStateMatcher, but I don't think its a good fit to go inmat-form-field. I as actually thinking about creating a directive to set theErrorStateMatcherthat targets the[matErorrStateMatcher]selector. That way we could apply it to any element to switch out the provider for all of its children. Then we would't have to add separate inputs to every component and we could also add it on<div>s and things