The Angular Button fails to display when all input conditions are met

I'm currently working on validating a form using this link. The requirement is simple - when an input field is invalid, the `save` button should be disabled. Conversely, when all input fields are valid, the `SAVE` button should be enabled/shown. The 'Add' functionality is working as expected, but I'm facing issues with the 'Update' functionality. The 'SAVE' button is not appearing when all input fields are valid, and I'm unsure why.

<!--upd-->
<div *ngIf="updateEnable" align="center">
  <form align="center" ngNativeValidate>
    id: <input disabled name="id" #updId="ngModel" [value]="selectedStudent.id" [(ngModel)]="selectedStudent.id" class="form-control" required/>

    <br> name: <input name="name" #updName="ngModel" [value]="selectedStudent.name" [(ngModel)]="selectedStudent.name" class="form-control" required [rangeLength]="[3, 30]" />{{updName.valid}}, {{updName.touched}}, {{updName.pristine}}
    <p *ngIf="updName.invalid || updName.errors?.rangeLength">Name must be filled and must be between 3-30 characters long</p>

    <br> year: <input name="year" #updYear="ngModel" [value]="selectedStudent.year" [(ngModel)]="selectedStudent.year" class="form-control" required digits/>{{updYear.valid}}, {{updYear.touched}}, {{updYear.pristine}}
    <p *ngIf="updYear.invalid || updYear.errors?.digits">Year must be filled and must be a number</p>

    <br> semester: <input name="semester" #updSemester="ngModel" [value]="selectedStudent.semester" [(ngModel)]="selectedStudent.semester" class="form-control" required digits/>{{updSemester.valid}}, {{updSemester.touched}}, {{updSemester.pristine}}
    <p *ngIf="updSemester.invalid || updSemester.errors?.digits">Semester must be filled and must be a number</p>

    <br>Major:
    <select name="major" #updMajor="ngModel" [value]="selectedStudent.major" [(ngModel)]="selectedStudent.major" class="form-control" required>{{updMajor.valid}}
              <option class="form-control" value="Computer Science">Computer Science</option>
              <option class="form-control" value="Politic">Politic</option>
              <option class="form-control" value="Accounting">Accounting</option>  
            </select>
    <p *ngIf="updMajor.invalid">Major must be filled</p>

    <br> score: <input name="score" #updScore="ngModel" [value]="selectedStudent.score" [(ngModel)]="selectedStudent.score" class="form-control" required digits [range]="[0, 101]" />{{updScore.valid}}, {{updScore.touched}}, {{updScore.pristine}}
    <p *ngIf="updScore.invalid || updScore.errors?.digits || updScore.errors?.range">Score must be filled, must be a number, and must be between 0-100</p>

    <br> email: <input name="email" #updEmail="ngModel" [value]="selectedStudent.email" [(ngModel)]="selectedStudent.email" class="form-control" required email/>{{updEmail.valid}}, {{updEmail.touched}}, {{updEmail.pristine}}
    <p *ngIf="updEmail.invalid || updEmail.errors?.email">Email must be filled and must contain @ and domain</p>
    <br>

    <div *ngIf="updId.invalid || updName.invalid || updYear.invalid || updSemester.invalid || updMajor.invalid || updScore.invalid || updEmail.invalid">
      <button disabled class="btn btn-warning" title="Cannot save, please check error message above" type="button" (click)="updStudent(updId.value , updName.value, updYear.value, updSemester, updMajor.value , updScore.value, updEmail.value)" data-dismiss="modal">SAVE</button>
    </div>

    <div *ngIf="updId.valid && updName.valid && updYear.valid && updSemester.valid && updMajor.valid && updScore.valid && updEmail.valid">
      <button disabled class="btn btn-warning" type="button" (click)="updStudent(updId.value , updName.value, updYear.value, updSemester, updMajor.value , updScore.value, updEmail.value)" data-dismiss="modal">SAVE</button>
    </div>

    <button class="btn btn-secondary" #notSaved type="button" data-dismiss="modal">CANCEL</button>

  </form>
</div>

Here is the form for inserting data that is functioning correctly.

<form align="center" ngNativeValidate>       
        ID: 
        <input #newId="ngModel" name="id" class="form-control" [(ngModel)]="newId.value" required digits/>Valid?{{newId.valid}}, Clean?{{newId.pristine}}, Touched?{{newId.touched}}
        <p *ngIf="newId.invalid || newId.errors?.digits">ID must be filled and must be numbers</p>

        <br>Name: 
        <input #newName="ngModel" name="name" class="form-control" [(ngModel)]="newName.value" required [rangeLength]="[3, 30]"/>Valid?{{newName.pristine}}, Clean?{{newName.pristine}}, Touched?{{newName.touched}}
        <p *ngIf="newName.invalid || newName.errors?.rangeLength">Name must be filled and must be between 3-30 characters long</p>
        
        <br>Year: 
        <input #newYear="ngModel" name="year" class="form-control" [(ngModel)]="newYear.value" required digits/>Valid?{{newYear.valid}}, Clean?{{newYear.pristine}}, Touched?{{newYear.touched}}
        <p *ngIf="newYear.invalid || newYear.errors?.digits">Year must be filled and must be numbers</p>

        <br>Semester:
        <input #newSemester="ngModel" name="semester" class="form-control" [(ngModel)]="newSemester.value" required digits/>Valid?{{newSemester.valid}}, Clean?{{newSemester.pristine}}, Touched?{{newSemester.touched}}
        <p *ngIf="newSemester.invalid || newSemester.errors?.digits">Semester must be filled and must be numbers</p>"
        
        <br>Major:
        <select #newMajor="ngModel" name="major" [(ngModel)]="newMajor.value" class="form-control" required>Valid?{{newMajor.valid}}, Clean?{{newMajor.pristine}}, Touched?{{newMajor.touched}}
          <option value="Computer Science">Computer Science</option>
          <option value="Politician">Political Science</option>
          <option value="Accounting">Accounting</option>  
        </select>
        <p *ngIf="newMajor.invalid">Major must be filled</p>

        <br>Score: 
        <input #newScore="ngModel" name="score" class="form-control" [(ngModel)]="newScore.value" required digits [range]="[0, 101]">Valid?{{newScore.valid}}, Clean?{{newScore.pristine}}, Touched?{{newScore.touched}}
        <p *ngIf="newScore.invalid || newScore.errors?.digits || newScore.errors?.range">Score must be filled, must be numbers, and must be between 0-100</p>

        <br>Email:
        <input #newEmail="ngModel" name="email" class="form-control" [(ngModel)]="newEmail.value" required email/>Valid?{{newEmail.valid}}, Clean?{{newEmail.pristine}}, Touched?{{newEmail.touched}}
        <p *ngIf="newEmail.invalid || newEmail.errors?.email">Email must contain @ and domain</p>

          <!--if condition invalid-->
          <div *ngIf="newId.invalid || newName.invalid || newYear.invalid || newSemester.invalid || newMajor.invalid || newScore.invalid || newEmail.invalid">
            <br><button disabled title="Cannot save, please check error message above" class="btn btn-primary" type="submit" (click)="addStudent(newId.value, newName.value, newYear.value, newSemester.value, newMajor.value, newScore.value, newEmail.value)">SAVE</button>
          </div>
    
          <!--if condition valid-->
          <div *ngIf="newId.valid && newName.valid && newYear.valid && newSemester.valid && newMajor.valid && newScore.valid && newEmail.valid">
            <br><button class="btn btn-primary" type="submit" (click)="addStudent(newId.value, newName.value, newYear.value, newSemester.value, newMajor.value, newScore.value, newEmail.value)" data-dismiss="modal">SAVE</button>
          </div>

          <button class="btn btn-secondary" data-dismiss="modal">CANCEL</button>

          </form>


<div *ngIf="updateEnable" align="center">
            <form align="center" ngNativeValidate>
            id: <input disabled name="id" #updId="ngModel" [value]="selectedStudent.id" [(ngModel)]="selectedStudent.id" class="form-control" required/>
        
            <br>
            name: <input name="name" #updName="ngModel" [value]="selectedStudent.name" [(ngModel)]="selectedStudent.name" class="form-control" required [rangeLength]="[3, 30]"/>{{updName.valid}}, {{updName.touched}}, {{updName.pristine}}
            <p *ngIf="updName.invalid || updName.errors?.rangeLength">Name must be filled and must be between 3-30 characters long</p>
        
            <br>
            year: <input name="year" #updYear="ngModel" [value]="selectedStudent.year" [(ngModel)]="selectedStudent.year" class="form-control" required digits/>{{updYear.valid}}, {{updYear.touched}}, {{updYear.pristine}}
            <p *ngIf="updYear.invalid || updYear.errors?.digits">Year must be filled and must be a number</p>"  

            <br>
            semester: <input name="semester" #updSemester="ngModel" [value]="selectedStudent.semester" [(ngModel)]="selectedStudent.semester" class="form-control" required digits/>{{updSemester.valid}}, {{updSemester.touched}}, {{updSemester.pristine}}
            <p *ngIf="updSemester.invalid || updSemester.errors?.digits">Semester must be filled and must be a number</p>
        
            <br>Major:
            <select name="major" #updMajor="ngModel" [value]="selectedStudent.major" [(ngModel)]="selectedStudent.major" class="form-control" required>{{updMajor.valid}}
              <option class="form-control" value="Computer Science">Computer Science</option>
              <option class="form-control" value="Political Science">Political Science</option>
              <option class="form-control" value="Accounting">Accounting</option>  
            </select>
            <p *ngIf="updMajor.invalid">Major must be filled</p>
        
            <br>
            score: <input name="score" #updScore="ngModel" [value]="selectedStudent.score" [(ngModel)]="selectedStudent.score" class="form-control" required digits [range]="[0, 101]"/>{{updScore.valid}}, {{updScore.touched}}, {{updScore.pristine}}
            <p *ngIf="updScore.invalid || updScore.errors?.digits || updScore.errors?.range">Score must be filled, must be a number, and must be between 0-100</p>

            <br>
            email: <input name="email" #updEmail="ngModel" [value]="selectedStudent.email" [(ngModel)]="selectedStudent.email" class="form-control" required email/>{{updEmail.valid}}, {{updEmail.touched}}, {{updEmail.pristine}}
            <p *ngIf="updEmail.invalid || updEmail.errors?.email">Email must be filled and must contain @ and domain</p>
            <br>

            <div *ngIf="updId.invalid || updName.invalid || updYear.invalid || updSemester.invalid || updMajor.invalid || updScore.invalid || updEmail.invalid">
              <button disabled class="btn btn-warning" title="Cannot save, please check error message above" type="button" (click)="updStudent(updId.value , updName.value, updYear.value, updSemester, updMajor.value , updScore.value, updEmail.value)" data-dismiss="modal">SAVE</button>
            </div>

            <div *ngIf="updId.valid && updName.valid && updYear.valid && updSemester.valid && updMajor.valid && updScore.valid && updEmail.valid">
              <button disabled class="btn btn-warning" type="button" (click)="updStudent(updId.value , updName.value, updYear.value, updSemester, updMajor.value , updScore.value, updEmail.value)" data-dismiss="modal">SAVE</button>
            </div>
            
            <button class="btn btn-secondary" #notSaved type="button" data-dismiss="modal">CANCEL</button> 

            </form>
        </div>

If you need more snippets or information, feel free to ask. Thank you!

Answer â„–1

After some tinkering, I found the solution by updating updId.valid to

selectedStudent.id.value == valid
. Surprisingly, only this change was needed for everything to work perfectly :D.

The save button functionality now depends on the validity of input fields - it will be disabled if any field is invalid and enabled when all fields are valid.

<span *ngIf="selectedStudent.id.value == valid && updName.valid && updYear.valid && updSemester.valid && updMajor.valid && updScore.valid && updEmail.valid">
              <button class="btn btn-warning" type="button" (click)="updStudent(updId.value, updName.value, updYear.value, updSemester.value, updMajor.value, updScore.value, updEmail.value)" data-dismiss="modal">SAVE</button>
            </span>

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

The formatting directive fails to keep pace with speedy input

I am working on a feature to automatically format the input field as the user types, transforming the letters into valid initials in uppercase with dots in between. The formatting needs to happen in real-time as the user inputs characters, rather than aft ...

Issue with aliasing in tsconfig.app.json not functioning correctly in Angular 11

I'm facing a problem with aliasing after migrating my application to an Angular project. None of my imports are functioning properly with the ""@app"" alias. mainApp │ package.json │ tsconfig.json │ angular.json │ └─┠...

Troubleshooting video streaming loading issues caused by 404 errors in URL paths with videojs

I've been successfully using the video.js library to stream live video. Everything was going well until after a while, the URL started throwing a 404 error during streaming, causing the entire player to get stuck on loading. Now I'm looking for a ...

Displaying object properties in React and rendering them on the user interface

Within my React application, I am retrieving data from an API using the following code snippet: function PlayerPage() { interface PlayerDataType { id: number; handle: string; role: string; avatar: string; specialAbilities: null; s ...

Angular version 2 has a directive called "ng2-nvd3" which seems to be undefined

I am attempting to incorporate a graph similar to the one shown in this Plunker example: Plunker Here is the corresponding code hosted on GitHub: GitHub However, I encountered an error: Uncaught (in promise): Unexpected directive value 'undefined ...

Enums are not recognized by TypeScript when used within an array

I have defined an enum as follows: export enum Roles { ADMIN, NONE; } An object is being used which utilizes this enum. The structure of the object is: export interface User { name: string; roles: Roles[]; } Upon fetching this object via a web r ...

I am encountering an issue in Vue3 where the parent event handler arguments are not being typed with the child's defineEmits definition. Can anyone explain this to me

I am struggling to correctly type the parent event handler based on the child definition, but no matter what I try, I always end up with `any` as the event type. Here is a code example: <script setup lang="ts"> // Child component type Even ...

The Angular Validator Pattern may be effective in HTML, but it seems to encounter limitations when

In the world of HTML, Regular Expressions can be quite useful as demonstrated in the example below: <input type="text" formControlName="mgmtIP" class="input-text" pattern="([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]& ...

Encountering an emscripten error when using MediaInfo.js with Angular 16

Trying to integrate mediainfo.js with Angular 16 based on the documentation found at https://github.com/buzz/mediainfo.js. Following the documentation, we have installed the necessary dependencies : Installation : "@types/emscripten": "^1. ...

Struggling to run my Pact tests using Karma and Angular

I'm struggling to run pact tests with Karma in my Angular app setup. Below is the relevant snippet from my package.json. "@angular/core": "~13.3.6", "@pact-foundation/karma-pact": "^3.1.0", "@pact-foundatio ...

Numerous instances of Duplicate Identifier errors were encountered during testing of the TypeScript application

After spending all morning searching for a solution... I am using TypeScript with node, npm, bower, and gulp. Whenever I run gulp serve or gulp test, I keep getting the same error message hundreds of times: src\app\main\common\dialogs ...

Guide to utilizing Angular's translate i18n key as a dynamic parameter within HTML

Looking to pass an i18n translate service key as a parameter function on an HTML component. Attempted the following, but instead of getting the text, it's returning the key value. Created a variable assigned with the title in the component.ts file. ...

The specified file path '.../node_modules/@nomicfoundation/hardhat-core/src' could not be located

I have successfully set up a TypeScript hardhat project, but I encountered an issue in /***/node_modules/@nomicfoundation/hardhat-chai-matchers/src/tsconfig.json: { "extends": "../../../config/typescript/tsconfig.json", "compil ...

Issue with intrinsic attributes detected in Typescript for the component

Hey, I'm encountering an issue that says, "The type '{ data: dataProp[]; }' cannot be assigned to type 'IntrinsicAttributes & dataProp'. A property 'data' does not exist on type 'IntrinsicAttributes & dataPro ...

What are the steps for rearranging a table column?

I am trying to show a text file in a table and allocate some code to each entry. I can display the text file. I can assign the code for each record (though this part is still under development). However, I have encountered an issue. The columns of the t ...

Halt of dispatcher playback occurs after a duration of 10 minutes with discord.js

Currently, I've been working on a music bot using discord.js. To handle audio streaming, I'm utilizing @discordjs/opus and ytdl-core-discord. Everything runs smoothly when testing the bot locally on my machine - songs from YouTube are played with ...

Is it possible to combine JavaScript objects using TypeScript?

Currently, I am dealing with two objects: First Object - A { key1 : 'key1', key2 : 'key2' } Second Object - B { key1 : 'override a' } I am looking to combine them to create the following result: The Merged Re ...

I had high hopes that TypeScript's automatic type inference for constructor parameters would do the trick, but it seems to have let

You can experiment with the given code snippet at the online playground to confirm it. Consider this code: class Alpha { private beta; constructor(b: Beta) { this.beta = b; } doSomething() { ...

What steps do I need to take to ensure my TypeScript module in npm can be easily used in a

I recently developed a module that captures keypressed input on a document to detect events from a physical barcode reader acting as a keyboard. You can find the source code here: https://github.com/tii-bruno/physical-barcode-reader-observer The npm mod ...

Challenges when building a production version of an Expo app with Typescript

Attempting to perform a local production build, I ran expo start --no-dev --minify. Only the initial template file displays, stating "Open up App.tsx to start working on your app," and none of my work is visible... Has anyone else encountered this issue a ...