Why are the inputs and dropdowns not disabled until you press the Edit button as intended?

My HTML file:

<div class="main-wrapper" fxLayout="row" fxLayoutAlign="center center">
<mat-card class="box">
    <mat-card-header>
        <mat-card-title>Register</mat-card-title>
    </mat-card-header>

    <form [formGroup]="registerForm" (ngSubmit)="onSubmit()" novalidate>

        <!-- Username -->
        <mat-card-content>
            <mat-form-field class="example-full-width">
                <input matInput placeholder="Username" ngModel name="username" minlength="5"
                    formControlName="username" required [readOnly]="!enableEdit">
            </mat-form-field>
            <mat-error *ngIf="username.touched && !username.valid">
                <div *ngIf="username.errors.required">Username is required.</div>
                <div *ngIf="username.errors.minlength">Username should be minimum 5 characters.</div>
            </mat-error>

            <!-- Email -->
            <mat-form-field class="example-full-width">
                <input matInput placeholder="Email" ngModel name="email" minlength="5" [pattern]="emailPattern"
                    formControlName="email" required [readOnly]="!enableEdit">
            </mat-form-field>
            <mat-error *ngIf="email.touched && !email.valid">
                <div *ngIf="email.errors.required">Email is required.</div>
                <div *ngIf="email.errors.pattern">Email is not valid.</div>
            </mat-error>

            <!-- Password -->
            <mat-form-field class="example-full-width">
                <input matInput placeholder="Password" ngModel name="password" minlength="5"
                    formControlName="password" required [readOnly]="!enableEdit">
            </mat-form-field>
            <mat-error *ngIf="password.touched && !password.valid">
                <div *ngIf="password.errors.required">Password is required.</div>
                <div *ngIf="password.errors.minlength">Password should be minimum 5 characters.</div>
            </mat-error>

            <!-- Repeat Password -->
            <mat-form-field class="example-full-width">
                <input matInput placeholder="Confirm Password" ngModel name="confirmpassword" formControlName="confirmpassword"
                    required [readOnly]="!enableEdit">
            </mat-form-field>
            <mat-error *ngIf="confirmpassword.touched && confirmpassword.value != password.value"> Passwords do not match
            </mat-error>

            <ng-select [items]="items" bindLabel="name" ngModel name="dropdown" formControlName="dropdown" required [disabled]="!enableEdit"></ng-select>
            <div *ngIf="!dropdown" class="invalid-feedback">Dropdown is required</div>

        </mat-card-content>

        <button mat-button color="primary" class="btn-block" (click)="enableEdit = !enableEdit">Edit</button>
        <button mat-button color="primary" class="btn-block" type="submit" [disabled]="!registerForm.valid">Register</button>
    
    </form>
</mat-card>

My Typescript file:

import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-register-form',
  templateUrl: './register-form.component.html',
  styleUrls: ['./register-form.component.css']
})
export class RegisterFormComponent implements OnInit {

  emailPattern = "^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$";  //Pattern to check if email is correct
  
  registerForm;

  enabledEdit = false;


  constructor(private formBuilder: FormBuilder) {}

  
  ngOnInit() {
    this.registerForm = this.formBuilder.group({
      username: [''],
      email: [''],
      password: [''],
      confirmpassword: [''],
      dropdown:['']
    });
  } 

  items = [
    {
      id: 1,
      name: 'Option 1'
    }, 
    {
      id: 2,
      name: 'Option 2'
    }, {
      id: 3,
      name: 'Option 3'
    }, {
      id: 4,
      name: 'Option 4'
    },
  ]

 

  get username() {
    return this.registerForm.get('username');
  }
  get email() {
    return this.registerForm.get('email');
  }
  get password() {
    return this.registerForm.get('password');
  }
  get confirmpassword() {
    return this.registerForm.get('confirmpassword');
  }
  get dropdown() {
    return this.registerForm.get('dropdown');
  }


  onSubmit() {
    console.log(this.registerForm.value)
  }
}

All inputs and dropdown should be blocked (no possibility to write or select options) until you press the Edit button.

Why is it not working?

How can I achieve having only an Edit button that transforms into a Register button upon being clicked?

Answer №1

To specify the disabled attribute when declaring your forms, follow this example:

 this.disableForm = true;
 this.registerForm = this.formBuilder.group({
   username:[{value:'', disabled:this.disableForm}],
   ...
})

Instead of directly changing values on user click, bind your click event to a function like this:

enableEdit(){
    //change monitoring status for the form
    this.disableForm = !this.disableForm;
    // if form is enabled then disable it. else enable the form
    if(!this.disableForm) this.registerForm.disable();
    else this.registerForm.enable();
}

Some suggestions on the code that may be helpful:

  • Avoid using reactive forms and template driven forms together in one form as it can cause unpredictable behaviors.
  • Consider initializing the form in the constructor instead of OnInit.
  • Make sure the edit button has type="button" attribute (default is submit).

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Discover the power of Angular 4 with its *ngFor loop constraints, and enhance user interaction

<ul> <li *ngFor="let hero of heroes | slice:0:10;"> {{ hero.name }} </li> </ul> <p *ngIf="heroes.length > 10" (click)="showMore()">show more 10</p> I am looking to display additional hero names when clic ...

Strategies for implementing ID passing in Angular's Ngrx effects

To show the information of the selected list, I will be choosing a list first. ...

Is there a way to extract a specific item from a ListView by tapping on it in Nativescript?

Attempting to retrieve data from a tap event using angular2 + typescript: This is the html code for the component: <RadListView row="1" [items]="groceryList" [class.visible]="listLoaded" (tap)="seeItem($event)" swipeActions="true" (itemSwipeProgr ...

Connecting the mat-progress bar to a specific project ID in a mat-table

In my Job Execution screen, there is a list of Jobs along with their status displayed. I am looking to implement an Indeterminate mat-progress bar that will be visible when a Job is executing, and it should disappear once the job status changes to stop or ...

The element 'router-outlet' in Angular 9.0 is not recognized within a lazily loaded module

My attempt at adding a new lazyloaded module to the app component is running into an issue. When I try to include child routes for the new module, an error stating that 'router-outlet' is not a known element:in lazy loaded module is thrown. In t ...

Issue with Angular 6: Unable to match nested routes

I am working on a project to test nested routing in Angular. While the app-routes are functioning correctly, I am encountering an error stating that the children "cannot match any routes". After checking other solutions, I am still confused due to version ...

Experiencing problems with the Locale setting when utilizing the formatNumber function in Angular's core functionalities

I am having trouble formatting a number in Angular using the formatNumber function from the Angular documentation. Here is my code snippet: import {formatNumber} from '@angular/common'; var testNumber = 123456.23; var x = formatNumber(Numb ...

Navigating the complexities of applying CSS exclusively to child grids within Kendo Angular may seem challenging at first

This image illustrates the grid layout I have created an angular UI using kendo that features a nested grid. I am trying to apply CSS specifically to the child grid without affecting the parent grid. However, no matter what CSS I write, it ends up being a ...

The argument provided is of type 'string | null' which cannot be assigned to a parameter expecting only 'string' type. The value of 'null' is not compatible with the type 'string' in Angular 12

When trying to parse the stored session data using JSON.parse(sessionStorage.getItem('owner')), we may encounter an error stating: Argument of type 'string | null' is not assignable to parameter of type 'string'. This is becau ...

Analyzing a string using an alternative character

I want to convert the string "451:45" into a proper number. The desired output is 451.45. Any help would be appreciated! ...

Is the HTML templating mechanism compatible with Angular?

Trying to implement HTML templating in my Angular application, my code looks like the following: <script type='text/html' id="sampleId">...</script> However, upon loading the HTML, I noticed that the script block was not present in ...

What is the process for developing an interface adapter using TypeScript?

I need to update the client JSON with my own JSON data Client JSON: interface Cols { displayName: string; } { cols:[ { displayName: 'abc'; } ] } My JSON: interface Cols { label: string; } { cols:[ { label:&a ...

Why is Angular ng-block-ui not functioning properly in Angular 7?

Within my app.module.ts file import { BlockUIModule } from 'ng-block-ui'; imports: [ BrowserModule, BlockUIModule.forRoot(), ] Inside the dashboard component: import { BlockUI, NgBlockUI } from 'ng-block-ui'; export class Da ...

The NG8002 error has occurred, as it is not possible to connect to 'matDatepicker' because it is not a recognized attribute of 'input'

I've come across an issue while working on my Angular 15 application with Angular Material. I'm trying to incorporate a date picker, but after adding the code snippet below, I encountered an error. <mat-form-field appearance="outline" ...

Error occurred due to changed expression after validation

I am facing an issue in my Angular app while implementing checkboxes with ngModel. When I try to implement it, I encounter the following error message. Can someone please help me resolve this problem? Error core.js:5873 ERROR Error: ExpressionChangedAfter ...

Is there a way to create fresh instances of a class using Injector rather than utilizing a singleton pattern?

In my Angular application, I am working with two injectable classes. @Injectable() class B {} @Injectable() class A { constructor(b:B) { } } My goal is to make class A a Singleton and class B a Transient. I recently discovered that I can utilize Ref ...

The error message TS2339 in Angular service.component indicates that the property 'subscribe' is not recognized on the type 'Promise<Object>'

Currently, I am in the process of learning Angular by developing a web application for my parish. I have implemented a method for deleting items in the products-list.component.ts file which appears to be technically correct. However, when I attempt to run ...

ngclass is not functioning properly when used with dynamically generated components

I am experiencing an issue with the components I create using createComponent. Although some of them function properly, others lack the appropriate CSS classes. Despite using a function and [ngClass] to set the classes, they do not appear when inspected in ...

The continuity of service value across parent and child components is not guaranteed

My goal is to update a value in a service from one component and retrieve it in another. The structure of my components is as follows: parent => child => grandchild When I modify the service value in the first child component, the parent receives the cor ...

Angular class mapping of web API response

I have a web API action method that returns a chapter ID and chapter name. I would like to convert this into an Angular class with an additional field called 'Edit', which by default is set to false. export class Chapter { chapterid: number; ...