How to make a formControl readonly

心已入冬 提交于 2019-12-30 02:42:19

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!