Lee Harris Lee Harris - 7 months ago 33
Javascript Question

How to dynamically generate X amount of new <input> based on the value of a <select> (within Angular2)?

I'll try to make this as simple as possible.

Problem:

I've got a page where I need to have X amount of

<input>
tags generated depending on the value chosen in a
<select>
.

Stack/Tech: Angular2/Javascript

Example:

The dropdown asks, "How many kids do you have?"

If the user selects 3 in the
<select>
dropdown, then 3 total
<input>
fields are generated and inserted in the
<div>
right after the question.

What I've Tried:

I've successfully pulled it off already but it's semi-unreliable and I don't feel like this is the "proper" way to do things.

Failure 1:

I tried using
*ngFor
with conventional
for
loop logic. I just did something like this:

for(let i = 0; i < selectValue; i++)


It didn't like that. Apparently
*ngFor
is mostly used to iterate through arrays and objects and can't be used with conventional
for
logic.

Failure 2:

I tried to pre-generate an array of objects, a multidimensional array, and a JSON-style object with empty but pre-filled fields.

My goal was to generate X objects in an array where X corresponds to the
select
number that the user chose. Then the
*ngFor
could iterate through this "pre-filled" array, display the inputs, and then I would fill that object later to be sent over HTTP.

Basically when the
<select>
changes it would call a function while passing the number the user chose. That function would generate a new array with X amount of objects.

No idea why this didn't work.

Success (but isn't ideal):

I tried binding
[innerHTML] = generatedHTML
and then filled the generatedHTML variable with traditional Javascript. This made
<input>
that seemed to worked fine, but this seems like a HORRIBLE way to do this. Plus I need to create event binders on each of these new
<input>
and I'm not sure if manually inserted [innerHTML] will work properly within Angular2's zones if I insert it in such a terrible fashion.

Bonus Question

After getting the inputs added I'd like to access their values in the easiest and most complete way possible. Is it possible to add multiple data inputs to ONE ngModel and then access each individual input through iteration? Or do I need to figure out another way to do this? Could I just put all those inputs under one
<form>
and then tie that
<form>
to a single data model?

Thanks for the help everyone! Pretty new to Angular 2 but digging it a lot so far :)

Answer

I would do it like this:

  1. Assign a ng-change function to your select
  2. Process the ng-model bound value of the select in that function (to create a new Array with n-Elements)
  3. Add whatever info to each inputArray element you need later to decorate the input boxes
  4. Do a ng-repeat over that array to create your input's

HTML:

<select [(ngModel)]="number" (ngModelChange)="nrChanged()">
  <option *ngFor="let nr of numbers" [value]="nr">{{nr}}</option>
</select>
<input *ngFor="let inputInfo of inputArr" type="text" placeholder="text" />

Component:

private numbers = [1,2,3,4,5,6,7];
private number;
private inputArr = [];

 nrChanged()
 {
  this.inputArr = [];
  for(var i = 0; i < this.number; i++){

      /*here you can assign any information you need for creating the concrete input */
      this.inputArr[i] = {neededInfo: 'I am the ' + i + 'Element'};
  }
Comments