问题
How to make a formControl in angular readonly
I know i can do it in html like
<input type="text" formControlName="xyz" readonly />
how to do it from JS Code and not html i.e in a model driven way
回答1:
If you are using Reactive Forms you can assign it dynamically like in the example code below (email field)
this.registerForm = this.formBuilder.group({
first_name: ['', Validators.required],
last_name: ['', Validators.required],
email: new FormControl({value: null, disabled: true}, Validators.required),
password: ['', Validators.compose([Validators.required, Validators.email])],
confirm_password: ['', Validators.required],
});
If you want to get all the values including disabled controls you should use:
this.registerForm.getRawValue();
View method comment on source code
/**
* The aggregate value of the `FormGroup`, including any disabled controls.
*
* If you'd like to include all values regardless of disabled status, use this method.
* Otherwise, the `value` property is the best way to get the value of the group.
*/
getRawValue(): any;
Enjoy coding!
回答2:
In my guess there is no use of READONLY in a Reactive Form (Angular 2+).
In a normal HTML, CSS based project
We use READONLY attribute to prevent user from type/select the form control but we get value from the input.
We use DISABLED attribute to prevent user from type/select the form control and we dont get value from the input.
In an Angular 2+ CLI based Projects
We don't need READONLY attribute to prevent user from type/select. Because DISABLED attribute is enough to prevent user from type/select and also you can get value from the disabled input/select/checkbox/radio field.
You can add disabled attribute to the field in model-driven way
While creating FormGroup
this.formGroupName = this.fb.group({
xyz: [{ value: '', disabled: true }, Validators.required]
});
At Runtime
this.formGroupName.get('xyz').disable({ onlySelf: true });
Getting values from FormGroup (Edited)
To get values from not disabled fields only
this.formGroupName.value;
To get values of all fields in the FormGroup
this.formGroupName.getRawValue();
So here you no need of READONLY attribute. Hope it helps.
回答3:
We can use any html attribute and bind it in angular using []
.
So,you can use attribute binding for the attribute readonly
in that control
e.g
<input type="text" formControlName="xyz" [readonly]="anyBooleanPropertyFromComponent" />
回答4:
For the reactive-forms
, if you want to make the fields readonly, one way to do so would be to do with plain old javascript using:
(document.getElementById('abc') as HTMLInputElement).setAttribute('readonly','true');
In addition to this, you can convert the code to more typescript and angular way. Use @ViewChild
to access the element and then set the readonly
property to true:
HTML
<input [formControl]='data' id='abc' #element [readonly]="data.disabled"/>
TS
@ViewChild('element',{static:true, read: ElementRef}) element : ElementRef ;
(this.element.nativeElement as HTMLInputElement).readOnly = true;
However, you will need to check for the status of the formControl before modifying the readonly property.
回答5:
formControl-based elements are readonly when set disabled:
this._formBuilder.group({
some: new FormControl(
{
value: parseInt(this.myobject.subObject.stringMember),
disabled: **true**
},
Validators.required
),
When I had to implement it, this was true for IE, and Chrome but not for Firefox ....
The right and simple solution is to set the formcontrol as not disabled:
this._formBuilder.group({
some: new FormControl(
{
value: parseInt(this.myobject.subObject.stringMember),
disabled: false
},
Validators.required
),
and, at the same time, to set the <input>
and/or <textarea>
as readonly:
- textarea:
<label> <span class="label">SomeLabel</span> <textarea maxlength="500" formControlName="some" readonly> </textarea> </label>
- input:
<input type="text" formControlName="name" />
A BAD and complex workaround that I could observe several times is to add a Firefox-specific transparent < div > over the input and to enable the input control on click over the transparent div:
css:
#wrapper {
position: relative;
&::after {
content: "%";
position: absolute;
right: 10px;
top: 10px;
}
}
#click {
width: 100%;
height: 35px;
position: absolute;
background: transparent;
}
html:
<label>
<span class="label">Name </span>
<div id="wrapper">
<div
*ngIf="isFirefox"
id="click"
(click)="enable('name')"
></div>-->
<input type="text" formControlName="name" readonly />
</div>
</label>
typescript:
export class MyObjectComponent implements OnInit {
@Input() public group: FormGroup;
isFirefox = /Firefox\//i.test(window.navigator.userAgent);
constructor() {}
ngOnInit() {}
enable(name) {
this.group.get(name).enable();
}
}
But this solution does only work with "< input >" elements and not with "< textarea >" elements nor whith "< input >" element if using nested FormControl.
来源:https://stackoverflow.com/questions/45452175/how-to-make-a-formcontrol-readonly