1


since I got a form with a lot of different input fields, to avoid having a gigantic html template I want to put the fields data inside objects and create the template dynamically using ngFor.
This is my code until now.

stub.ts - this is where I store my data

export const MY_DATA = [
  { placeholder: 'First name', name: 'name', model: 'model.name'},
  { placeholder: 'Last name', name: 'lastName', model: 'model.lastName'},
  { placeholder: 'Age', name: 'age', model: 'model.age'}
];

component.ts

import { Component, OnInit } from '@angular/core';
import {MY_DATA} from './stub';

@Component({
  selector: 'app-valutazione-insert',
  templateUrl: './valutazione-insert.component.html',
  styleUrls: ['./valutazione-insert.component.css']
})
export class ValutazioneInsertComponent implements OnInit {

  model: any = {};
  data = MY_DATA;

  constructor() { }

  ngOnInit() {}

  submit() {
      console.log('Data submitted: ', this.model);
    }

}

template.html

<div id="datiRichiesta" [hidden]="datiRichiestaClicked" >
        <div class="form-group" *ngFor="let d of data">
          <input type="text" class="form-control" placeholder="{{d.placeholder}}" [(ngModel)]=d.model name="{{d.name}}"
                onfocus="this.placeholder = ''" (blur)="this.placeholder = d.placeholder"/>
        </div>
      </div>

These are the input fields I got: enter image description here

This is the rendered html code: enter image description here

Now, I got some things that don't work:

  1. even if on the rendered html all attributes are correctly set, the placeholder value takes the model value
  2. the behaviour of the placeholder onfocus and onblur is not working
  3. most important, if I try to submit some values these are not passed to the controller

Now every problem disappear if I use an input type with all properties set statically. Is there any way to achieve what I want?

Thanks!

1 Answer 1

3

stubs.ts

It is better to renamed model to modelPropName to make it more clear.

This means First name will be set in the name property of the model: any = {} object, and so on.

export const MY_DATA = [
  { placeholder: 'First name', name: 'name', modelPropName: 'name'},
  { placeholder: 'Last name', name: 'lastName', modelPropName: 'lastName'},
  { placeholder: 'Age', name: 'age', modelPropName: 'age'}
];

template.html

<form id="datiRichiesta" [hidden]="datiRichiestaClicked" (submit)="submit()">
    <div class="form-group" *ngFor="let d of data">
        <input type="text" 
            class="form-control" 
            placeholder="{{d.placeholder}}" 
            [(ngModel)]="model[d.modelPropName]"
            name="{{d.name}}"
            (focus)="$event.target.placeholder = ''" 
            (blur)="$event.target.placeholder = d.placeholder"/>
    </div>
    <button>Submit</button>
</form>

When you submit the form you should in the console:

Data submitted: Object {name: "...", lastName: "...", age: "..."}

Sign up to request clarification or add additional context in comments.

2 Comments

This is simple and perfect. Thank you.
I want to create one but my object has 2 levels {name: "...", lastName: "...", age: "...", 2level: {other: "...",other2:"..."}} Can be done?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.