tying [inactive] to a specific attribute

I have successfully implemented the functionality to disable the button when the email is in the correct format, as shown in my code below.

Now, I am looking to implement the following scenario:

  • The Get Started button should be disabled by default
  • If a user inputs a valid email, the Get Started button will enable
  • Clicking the Get Started button will disable it
  • The button will only enable again if the user changes the input in the email field to a valid one
  • This will create a cycle of enabling and disabling the button

How can this be achieved in Angular? Is there a more efficient way or technique to accomplish this?

View Input box example

HTML Code

 <div fxLayout="column">
                            <mat-form-field class="full-width" appearance="fill" style="margin-top: 20px;">
                                <mat-label>Email</mat-label>
                                <input type="email" matInput autocomplete="emailAddress" matInput formControlName="emailAddress" />
                                    <mat-error *ngIf="modelForm.get('emailAddress').hasError('email')">
                                        Email is in invalid format.
                                    </mat-error>
                                    <mat-error *ngIf="modelForm.get('emailAddress').hasError('required')">
                                        Email is required.
                                    </mat-error>
                            </mat-form-field>
                        </div>
                        <form (click)="getStarted()">
                        <div style="text-align:right;margin-top: 19.0px;">
                            <button [disabled]="modelForm?.get('emailAddress').invalid" mat-flat-button color="primary"
                                 class="v-btn-sml" id="get-started-button">
                                Get Started
                            </button>
                        </div>
                      </form>

TS Code

ngOnInit(): void {
    this.initFormGroup();
  }



    
  initFormGroup() {
    this.modelForm = this.formBuilder.group({
      id: [this.model.id || 0],
      emailAddress:[this.model.emailAddress,[Validators.required, Validators.email]],
      firstName: [this.model.firstName,Validators.required],
      roleId: this.model.roleId,
      lastName: [this.model.lastName,Validators.required],
      phoneNumber: this.model.phoneNumber,
      companyName: [this.model.companyName,Validators.required],
      ssocredentials: this.model.ssocredentials || '',
      accountId: this.accountId,
      title: this.model.title,
      isSso: this.model.isSso || '',
    });
  }

Answer №1

To disable the button based on certain conditions, you can bind the disabled property to two indicators. If either of these indicators is true, the button will be disabled:

  1. If the email form-control is invalid (i.e.
    modelForm?.get('emailAddress').invalid
    )
  2. A variable named isDisabled (default value should be true for disabled state), which will change under two circumstances:
  • Set to false when the email field is changed
    (ngModelChange)="isDisalbed = false"
  • Set to true when the button is clicked (e.g., in the getStarted method).

You can implement this with the following code snippet:

<form [formGroup]="modelForm">
    <div fxLayout="column">
        <mat-form-field class="full-width" appearance="fill" style="margin-top: 20px">
            <mat-label>Email</mat-label>
            <input type="email" matInput autocomplete="emailAddress" matInput formControlName="emailAddress"
                (ngModelChange)="isDisDisalbedabled = false" />
            <mat-error *ngIf="modelForm.get('emailAddress').hasError('email')">
                Email is in invalid format.
            </mat-error>
            <mat-error *ngIf="modelForm.get('emailAddress').hasError('required')">
                Email is required.
            </mat-error>
        </mat-form-field>
    </div>
    <div style="text-align: right; margin-top: 19px">
        <button [disabled]="modelForm?.get('emailAddress').invalid || isDisabled" mat-flat-button color="primary"
            class="v-btn-sml" id="get-started-button" (click)="getStarted()">
            Get Started
        </button>
    </div>
</form>

In your component class, include the following:

isDisabled = true;

getStarted() {
  this.isDisabled = true;
  // Add your logic here
}

Answer №2

To add more functionality, you can bind [disabled] to either a property or a function. However, keep in mind that you should avoid placing time-consuming logic within the disabled check, as Angular will execute it frequently. Here is an example:

HTML:

<button [disabled]="isDisabled" mat-flat-button color="primary"
                             class="v-btn-sml" id="get-started-button">
                            Get Started
                        </button>
                    </div>
                  </form>

Typescript:

get isDisabled(): boolean {
     if (!this.modelForm.valid) {
         return true;
     }
     const vals = this.modelForm.value;
     return this.model.emailAddress == vals['emailAddress'];
     
  }

Answer №3

To ensure the app recognizes when the button is clicked, consider using a variable such as submitted.

The Get Started button starts off disabled by default -> submitted=false

If the user enters a valid email address, the Get Started button will become enabled ->

check if the form field is valid using formControls

Once the user clicks the Get Started button, it will then be disabled -> submitted=true

The button will only re-enable after clicking if the user updates the email input field with a valid email -> repeast the second one, after submission, reset the form to retain this functionality.

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

A colleague's dependency is taking precedence over an NX Library

I'm working in a monorepo environment with nx, structured as follows: apps | - my-app libs | - common | - my-client After deployment, the libraries are published on npm with the names @my-org/my-client and @my-org/common. I have set up path ali ...

Modify the code to use a BehaviorSubject subscribing to an Observable

Currently, I am in the process of learning Angular2 and RxJS by studying someone else's application. The application consists of two modules: asObservable.ts export function asObservable(subject: Subject) { return new Observable(fn => subject ...

Error: The function concat() is not valid for messagesRef.current

I'm currently developing an app that enables users to interact with AI by asking questions related to the uploaded PDF file. However, I've encountered a problem while interacting with AI on the client side - I keep receiving the error 'TypeE ...

Implementing SAML Authentication in Angular and .NET WebAPI

I am in the process of setting up a website that utilizes Angular for the user interface, .NET for the backend APIs, and integrates SAML for authentication with a third-party Azure AD. I'm finding it challenging to grasp how each component interacts w ...

Anguar 9 is experiencing issues with loading datatable pagination, search, and sorting functionalities

My problem lies in the pagination, search, and sorting functions not loading properly in my data table despite the data binding correctly. I have provided my html, component, and service files for reference. .html <table class="table table-striped ...

TypeORM does not have the capability to effectively remove a row when there is a ManyToOne or

I'm currently grappling with a problem that has me stumped. I've spent countless hours trying to find a solution, but to no avail. I'm using MS-SQL on Azure. The structure of my entities is as follows: Customer and Visits: OneToMany (Prima ...

What is the process for choosing nested colors from a theme in Material UI?

I have a question regarding how to select a nested style from my theme when creating a Button. Below is the snippet of code that illustrates my dilemma: const buttonStyle: SxProps<Theme> = { '&:hover': { backgroundColor: 'bac ...

Prisma and Next.js: Changes to content require re-deployment for updates to take effect

Just recently, I launched a new website on Vercel. My web application is being built with Prisma and Next.js. However, I'm currently facing an issue where the content doesn't update in real-time unless I manually re-deploy the application. Here&a ...

When attempting to display the title of a route in an Angular header component, it consistently results in undefined

I am facing a seemingly simple issue. I have a header component that needs to display the title of the currently active route. To achieve this, I am injecting the ActivatedRoute into the header component and attempting to display the route title using the ...

Is AngularJS Easy to Pick Up After Mastering Angular 2+?

Starting with the rationale, numerous companies have been utilizing AngularJS for years and are not yet inclined to upgrade to version 4 or higher. This indicates market demand as well as the necessity for Angular developers to be proficient in both versio ...

The status code 0 was returned for the null URL

I am facing an issue with my Ionic 3 application that is using the same API as my previous versions of Ionic apps. After logging in, I encountered the following error: Response with status: 0 for URL: null I have researched online and found suggestion ...

issues arise with tests following the transition from Angular 9 to Angular 10

Recently, I encountered an issue with my jest-tests after updating Angular from version 9 to 10. These tests were working perfectly fine before the update. Can someone guide me on how to resolve this issue? Below is one of the tests that is causing troubl ...

Avoid nesting subscriptions in Rxjs

I am working with an array of objects and I need to extract an array of IDs from it. After that, I have to make calls to 2 different APIs before closing the modal window. Below is my code snippet: from(this.alerts) .pipe(map(alert => alert._id)) ...

Tips on eliminating expansion upon button click in header within an Angular application

While utilizing Angular Materials, I encountered a challenge with the mat-expansion component. Every time I click on the buttons within the expansion panel, it closes due to the default behavior of mat-panel. Requirement - The panel should remain expanded ...

Angular 7 - ngForm and ngSubmit: Resubmitting outdated data

I have a form in Angular 7 set up like this: <form #payForm="ngForm" (ngSubmit)="onSubmit(payForm, $event)" method="POST" action="POST URL HERE"> <input type="hidden" name="requestParameter" [value]="stringToSend" /> <div class= ...

Combining and consolidating a unique observable array that originated from the ngrx state tree

Upon making an API call, the data is retrieved and processed through ngrx-effects before being stored in the state tree. From there, I can access the data in my angular component's constructor and utilize rxjs methods like mergeMap and reduce to forma ...

Tips for validating dates in Angular 4

Recently, I have started working with Angular and in my application I am facing a challenge regarding date validation. I need to validate a date input and display an error message based on the validation criteria. To achieve this, I am utilizing ngx-boots ...

typescript undefined subscription to observable

After making an http request to fetch some data, I am facing issues in displaying it as intended. The dropdown select for entriesPerPage, and the left and right cursors for switching page in pagination are working fine. However, upon switching a page, I en ...

What is the best way to resolve the unusual resolution issue that arises when switching from Next.js 12 to 13

Previously, I created a website using nextjs 12 and now I am looking to rebuild it entirely with nextjs 13. During the upgrade process, I encountered some strange issues. For example, the index page functions properly on my local build but not on Vercel. ...

The two-way binding does not connect the property and event halves to the same target

I am trying to create a two-way binding using reactive forms in Angular. I need to exchange data between the child component and the parent component seamlessly. This is the HTML code for my child component: <input type="text" #name class=&qu ...