Home > other >  Angular Required Form Input with ngIf
Angular Required Form Input with ngIf

Time:03-04

Edit: altered example code to include relevant typescript

I have a form with different buttons for the user to select. The button to submit the form is disabled until the user selects a button. The trick here is that I would like one of the options to not enable the submission button, but to instead show a textbox. The button should then be enabled if the user enters something into the textbox. At the moment, my HTML looks a little something like this:

<h1>Do you like sandwiches?</h1>
<form id="my-form" action="onSubmit()">
  <div>
    <button *ngFor="let option of myOptions"
            
            (click)="selectThisButton(option)">{{ option }}</button>
    <div id="other-input" *ngIf="showInput">
      <label for="text-input">Please elaborate.</label>
      <input id="text-input" type="text" required>
    </div>
  </div>
</form>

<!--...some other code...-->

<button id="submit-button" form="my-form" type="submit" disabled="!my-form.valid">Next</button>

The typescript class is fairly straightforward as well:

selectedOption: string
showInput = false
needsExplanation = false
myOptions = ["Yes", "No", "I don't understand", "Other"]

selectThisButton(option: string){
  this.selectedOption = option
  this.needsExplanation = (option === "I don't understand")
  this.showInput = (option === "Other")
}

onSubmit(){
  if(this.selectedOption === "Other"){
    this.selectedOption = (document.getElementById("text-input") as HTMLInputElement).value
  }
  continueAndDoOtherStuff()
}

All of this works except for the last step, i.e. entering something into the textbox doesn't enable the "next" button when it should. I've also tried not using a form and just putting an EventListener on the textbox after the ngIf has rendered to listen for a keyup event, but that didn't work either.

Any help would be appreciated, especially suggestions that don't rely on jQuery.

CodePudding user response:

a little bit short on time, so I'll work this answer further out later if you would like me to do so.

Why don't you add a (keyup.enter)-event in the input-box, e.g. (Angular 6 add input on enter key)?

The method you link to this event in the html-template, use it in the typescript template to switch a boolean true/false and link that boolean to the submit-button you want to enable/disable. (Like you're already doing.)

Please let me know: (i) if you want this answer to be worked out (ii) if it didn't help you (and what happened).

Take care and good luck.

(Sorry for the limited answer.)

CodePudding user response:

Is there a motivation for using plain buttons instead of radio buttons?

Then, why don't you use the the APIs that Angular gives you?

First of all you could use [(ngModel)] instead of the selectThisButton function:

<form id="my-form" #form="ngForm">
  <div>
    <input type="radio"  [(ngModel)]="selectedValue" value="yes" id="yes" name="selection" />
    <label for="yes">Yes</label>

    <input type="radio"  [(ngModel)]="selectedValue" value="no" id="no" name="selection" />
    <label for="no">No</label>

    <input type="radio"  [(ngModel)]="selectedValue" value="dont-understand" id="dont-understand" name="selection" />
    <label for="dont-understand">I don't understand the question</label>

    <input type="radio"  [(ngModel)]="selectedValue" value="other" id="other" name="selection" />
    <label for="other">Other</label>

    <div id="other-input" *ngIf="selectedValue === 'other'">
      <label for="text-input">Please elaborate.</label>
      <input id="text-input" type="text" required>
    </div>
  </div>
</form>

<!--...some other code...-->

<button id="submit-button" form="my-form" type="submit" [disabled]="!form.valid">Next</button>

The only thing you need on your component.ts file is the selectedValue field:

@Component({
  selector: ...,
  templateUrl: './....component.html',
})
export class YourComponent {
  selectedValue: string = undefined;
}

And your text input should be shown only when the other button is selected

  • Related