Components: Readonly CSS Styling: MatFormField should reflect css class 'mat-form-field-readonly' similar to 'mat-form-field-disabled'

Created on 13 Apr 2019  路  8Comments  路  Source: angular/components

Please describe the feature you would like to request.

The MatFormField component reflects a disabled MatInput directive via a dynamic css class 'mat-form-field-disabled'.

I suggest to implement a dynamic css class 'mat-form-field-readonly' similar to 'mat-form-field-disabled' which reflects the readonly state of the MatInput directive.

What is the use-case or motivation for this proposal?

My proposal would support better css styling. Eg. styling the child 'mat-form-field-underline' of the MatFormField (which is not a dom child of the MatInput directive).

Is there anything else we should know?

No special css styling is required to be implemented by you. Only the possibility to implement one by myself.

Temporary Workaround

Helper directive (ts):

import { Directive, Input, HostBinding } from '@angular/core';
import { MatFormField, MatInput } from '@angular/material';

/* Workaround to provide css class 'mat-form-field-readonly' similiar to 'mat-form-field-disabled'. 
 * Example Usage:
 *  <mat-form-field provideReadonly>
 *      <input matInput placeholder="Readonly Input" readonly="true" value="Some Value">
 *  </mat-form-field>
 */
@Directive({
    selector: 'mat-form-field[provideReadonly]',
    host: {
        '[class.mat-form-field-readonly]': 'isReadonlyInput()'
    }
})
export class ProvideMatFormFieldReadonlyDirective {
    constructor(private _matFormField: MatFormField) { }

    public isReadonlyInput(): boolean {
        const ctrl = this._matFormField._control;
        if (ctrl instanceof MatInput) {
            return ctrl.readonly;
        }
        return false;
    }
}

The directive must be assigned explicitly (html):

<mat-form-field provideReadonly>
    <input matInput placeholder="Readonly Input" readonly="true" value="Some Value">
</mat-form-field>

Which can be styled for example (css):

/* mat-form-field / matInput - readonly support */
.mat-form-field-appearance-legacy.mat-form-field-readonly .mat-form-field-underline {
    background-color: rgba(127, 127, 127, 0.25);
}

Thank You!

P3 materiaform-field feature

Most helpful comment

@devversion - with the upcoming work around adding types around ReactiveForms, is there any reason the 'ReadOnly' concept can't be added to AbstractControl similar to enabled/disabled?

Currently we have a lot of controls that are 'disabled', but really they should be 'readonly': styled more inline with that specification (https://material.io/components/text-fields#input-types), and should show up in .value (opposed to needing to call getRawValue()

All 8 comments

This would be a great feature to have.

I needed this today, thank you for the workaround directive! 馃憣

I have achieved this way

Thanks to @gerhard17

  • Added custom class to mat-form-field which is bind with a state
<!-- form.component.html -->
<mat-form-field floatLabel="never" [ngClass]="{'mat-form-field-readonly':!selection.isSelected(row)}">
    <span matPrefix>$&nbsp;</span>
    <input 
        matInput 
        placeholder="Discount" 
        formControlName="discountRate" 
        required
        [readonly]="!selection.isSelected(row)"
    >
</mat-form-field>
  • Added custom style in related stylesheet
//form.component.scss
::ng-deep .mat-form-field-appearance-legacy.mat-form-field-readonly 
    .mat-form-field-underline {
    background-color: rgba(127, 127, 127, 0.25);
       //any other styling 
}

The problem here is that the form-field technically doesn't care about the readonly state of controls. In fact, the form-field deals with abstract form controls and doesn't even known whether form controls support a readonly state or not.

If we'd want to toggle a class on the form-field for more convenience, then this would require us to proxy it through MatFormFieldControl (might be breaking). That might be confusing, and other control authors would ask for other states to be reflected too.

Generally I think this is a good feature request, but maybe it should be more generic so that individual controls (like matInput) can toggle classes on the form-field for improved styling. That might be generally useful for custom controls.

Also cc. @mmalerba for thoughts on this.

@devversion : Of course a real solution should be more generic. But the most common case needed to support readonly state are text input fields. For this case my workaround was made for. A more general built-in solution would be usefull and wellcomed! :-)

Generally I think this is a good feature request, but maybe it should be more generic so that individual controls (like matInput) can toggle classes on the form-field for improved styling. That might be generally useful for custom controls.

Yeah, I agree with that, would be a useful addition.

@devversion - with the upcoming work around adding types around ReactiveForms, is there any reason the 'ReadOnly' concept can't be added to AbstractControl similar to enabled/disabled?

Currently we have a lot of controls that are 'disabled', but really they should be 'readonly': styled more inline with that specification (https://material.io/components/text-fields#input-types), and should show up in .value (opposed to needing to call getRawValue()

Was this page helpful?
0 / 5 - 0 ratings

Related issues

julianobrasil picture julianobrasil  路  3Comments

vitaly-t picture vitaly-t  路  3Comments

alanpurple picture alanpurple  路  3Comments

shlomiassaf picture shlomiassaf  路  3Comments

LoganDupont picture LoganDupont  路  3Comments