1
votes

I am generating an array based on a number that is input by the user:

      <div class="form-group">
        <input type="number"
          class="form-control"
          id="numPeople"
          [(ngModel)]="numPeople"
          name="numPeople"
          required>
      </div>

With this number, I generate an array of [['name', 'gender'],*number...]. I am then trying to use ngForm to bind directly into this array and I wanted to have a gender set as default but having trouble with it in two ways:

1) is not working so I can't have a default value in the select, and required is not forcing an entry so you can press submit without selecting an option even with the required flag set.

2) I am getting this error when I delete the placeholder text being read in from 2 way databinding into the input box, and if I try insert a blank string, i.e. by putting '' into the array on the backend: [ '', '' ]

EXCEPTION: Error in ./SellTicketComponent class SellTicketComponent - inline template:373:28 caused by: If ngModel is used within a form tag, either the name attribute must be set or the form control must be defined as 'standalone' in ngModelOptions.

  Example 1: <input [(ngModel)]="person.firstName" name="first">
  Example 2: <input [(ngModel)]="person.firstName" [ngModelOptions]="{standalone: true}"> ErrorHandler.handleError @

error_handler.js:54 next @ application_ref.js:359 schedulerFn @ async.js:93 SafeSubscriber.__tryOrUnsub @ Subscriber.js:223 SafeSubscriber.next @ Subscriber.js:172 Subscriber._next @ Subscriber.js:125 Subscriber.next @ Subscriber.js:89 Subject.next @ Subject.js:55 EventEmitter.emit @ async.js:79 NgZone.triggerError @ ng_zone.js:331 onHandleError @ ng_zone.js:292 ZoneDelegate.handleError @ zone.js:246 Zone.runTask @ zone.js:154 ZoneTask.invoke @ zone.js:345 error_handler.js:56 ORIGINAL EXCEPTION: If ngModel is used within a form tag, either the name attribute must be set or the form control must be defined as 'standalone' in ngModelOptions.

  Example 1: <input [(ngModel)]="person.firstName" name="first">
  Example 2: <input [(ngModel)]="person.firstName" [ngModelOptions]="{standalone: true}">

This is the code:

      <form (ngSubmit)="onSubmit(f)" #f="ngForm">
        <label> Enter the details of all your plus ones for the guest list: </label>
        <br>
         <div *ngFor="let guest of guests; let i = index;">
          <label> Enter First and Last Name:</label>
           <div class="form-group">
             <input type="text"
                    class="form-control"
                    id="{{guest[0]}}"
                    [(ngModel)]="guest[0]"
                    name="{{guest[0]}}"
                    required>
           </div>

           <div class="form-group">
           <label> Enter Gender: </label>
            <select
            class="form-control"
             id="{{i}}"
             name="{{i}}"
             [(ngModel)]="guest[1]"
             required>
            <option value="female" selected>
               female
             </option>
             <option value="male">
               male
             </option>
           </select>
         </div>
       </div>
     </form>
1

1 Answers

1
votes

Not really knowing how you generate your guests and how they look like.... since you seem to use [(ngModel)]="guests[0]", I would assume you'd want to use [(ngModel)]="guests[i]" instead. Here is an example using the latter.

If you want to use two way binding for the guest, when you generate the guests, you can preset the gender value to female, so that it will be preselected in the dropdown, e.g:

this.guests.push({name:'',gender:'female'}, {name:'',gender:'female'});

If you don't need the two way binding for guests, you can use e.g [(ngModel)]="selected", where in your component you have declared selected: string = 'female'. That will work as well.

So all in all your form could look like this:ยจ

<button (click)="generate()">Generate 2 Guests</button> <!-- dummy button -->

<form (ngSubmit)="onSubmit(f.value)" #f="ngForm">
  <label> Enter the details of all your plus ones for the guest list: </label>
  <div *ngFor="let guest of guests; let i = index;">
    <label> Enter First and Last Name:</label>
    <div>
      <input type="text" name="guest{{i}}" [(ngModel)]="guests[i].name" required>
    </div>

    <div>
      <label> Enter Gender: </label>
      <select name="gender{{i}}" [(ngModel)]="guests[i].gender" required>
        <option value="female">female</option>
        <option value="male">male</option>
      </select>
    </div>
  </div>
  <button type="submit">Submit</button>
</form>

This will check the validity of the fields. Here of course user can enter just white spaces, so you'd need to check that as well.

Here's a Demo Plunker (which does not check white spaces)

Hope this helps! :)