Formularios en Angular

  • Autor Autor ulises2010
  • Fecha de inicio Fecha de inicio
U

ulises2010

Beta
¡Usuario con pocos negocios! ¡Utiliza siempre saldo de Forobeta!
Estoy pasando de AngularJS a Angular y la verdad es que me esta costando. Cosas muy simples como mandar un formulario o hacer una funcion global me cuestan mucho. Yo usaba para ciertas funciones y variables que quería usar en varias páginas $rootScope, pero todo eso ha desaparecido con Angular y por lo visto se usan servicios para hacerlo, pero sinceramente me parece muy complicado y sólo encuentro información en inglés y me está costando... alguien puede hacerme un resumen en español de como puedo hacerlo?

Por otro lado, para enviar el contenido de un formulario tampoco doy con ello.

Tengo este html:

HTML:
<form novalidate
      [formGroup]="myform">


<div class="form-group dropdown">
    <span class="selLabel">Select Hospital</span>
    <input type="hidden">
    <ul class="dropdown-list form-control"
            formControlName="language">
      <li *ngFor="let hospital of hospitals; let i = index" data-value="hospital.id">
        <span>{{hospital.name}}</span>
      </li>
    </ul>
  </div>

  <div class="form-group">
    <label>Language</label>
    <select class="form-control"
            formControlName="language">
      <option value="">Please select a language</option>
      <option *ngFor="let lang of langs"
              [value]="lang">{{lang}}
      </option>
    </select>
  </div>

  <pre>{{myform.value | json}}</pre>
</form>

y este .ts

Insertar CODE, HTML o PHP:
import { Component, OnInit } from '@angular/core';
import {
    ReactiveFormsModule,
    FormsModule,
    FormGroup,
    FormControl,
    Validators,
    FormBuilder
} from '@angular/forms';

@Component({
  selector: 'app-bookappointment',
  templateUrl: './bookappointment.component.html',
  styleUrls: ['./bookappointment.component.css']
})
export class BookappointmentComponent implements OnInit {
  
  langs: string[] = [
    'English',
    'French',
    'German',
  ];
  myform: FormGroup;

  hospitals: any[] = [{id: '001', name: 'Clinic'}, {id: '002', name: 'Other Clinc'}];

  constructor() {
    this.hospitals 
     console.log(this.hospitals);
  }


  ngOnInit() {
    
     this.myform = new FormGroup({
      hospital: new FormControl(),
      language: new FormControl()
    });
  }

}

y aunque me lee lo seleccionado en Lang, no lo hace en hospital, supongo que tiene que ver que uno esta listado como option y otro como li, pero necesito listarlo así por cuestión de diseño.... se os ocurre alguna idea?

Gracias
 
Son varias consultas, aunque entrelazadas, trataré de responder lo que pueda, Ya que llevo bastante sin usar Angular, pero si hay algo que la gente de Angular hizo bien, fue la creación de servicios, cuando leí la documentación (fue casi a principios de 2017, de hecho, recién había salido la 2) algo se me quedó pegado, un servicio puede ser cualquier cosa, no tienen estructura definida.

Yo te recomiendo que crees un servicio en donde cargues los hospitales y despues esa "lista" la puedes llamar desde donde la necesites con la inyección de dependencias que aplica Angular,

Angular Docs

ahí un ejemplo de cómo puedes realizar la llamada, (si es que estas consumiendo json)

También preguntas sobre cómo hacer funciones globales, También te sirve crearla como un servicio, como te digo, un servicio puede poseer una llamada http, una funcion, una constante, y lo que se te ocurra, y lo puedes usar en cualquier lado.

Para hacer sumbit a un formulario la forma más fácil es con el data binding. Angular tiene lo que se llama el two way data binding. Para enviar data, se usan los paréntesis, y para recibir, los parentesis cuadrados o "corchetes".
En tu caso sería

Insertar CODE, HTML o PHP:
<form novalidate
      [formGroup]="myform" (ngSubmit)="MiFuncionGenial(myform)">


Ya que myform es el nombre de tu grupo debes pasarlo como parametro, y en tu documento typescript del componente
Insertar CODE, HTML o PHP:
MiFuncionGenial(myform) {
    this.atributo1 = myform.atributo1;
    this.atributo2 = myform.atributo2;
  }

obviamente atributo1 y atributo2 deben estar declarados en el constructor/onInit

Espero haberte podido ayudar un poco aunque sea. Cualquier cosa veremos si podemos ayudar, saludos!
 
Muchísimas gracias maximusk10.

Efectivamente son muchas cosas así que ire por partes, así que de momento estoy centrado en el formulario que es lo que más me quita el sueño.

He seguido tus instrucciones y efectivamente le botón submit dispara la MiFuncionGenial(myform) que tiene este código:

Insertar CODE, HTML o PHP:
  MiFuncionGenial(myform) {
    console.log(myform.controls);
  }

y efetivamente recibe los dos, hospitals y language, pero el value del language si que lo coge (el que tenga seleccionado cada vez) pero el de hospitals me llega siempre vacio aunque haya algo seleccionado.

Sigo creyendo que tiene algo que ver con que en uno tenga puesto el ngFor en un <option> y el otro en un <li>, pero lo necesito por diseño.

Vuelvo a pegar el contenido del html que creo que es donde esta el fallo.

Insertar CODE, HTML o PHP:
<form novalidate [formGroup]="myform" (ngSubmit)="MiFuncionGenial(myform)">>

<div class="form-group">
<div class="dropdown">
    <span class="selLabel">Select Hospital</span>
    <input type="hidden" class="form-control" formControlName="hospital">
    <ul class="dropdown-list">
      <li *ngFor="let hospital of hospitals"
              [value]="lang" >
        <span>{{ hospital.name }}</span>
      </li>
    </ul>
  </div>
  </div>


  <div class="form-group">
    <label>Language</label>
    <select class="form-control"
            formControlName="language">
      <option value="">Please select a language</option>
      <option *ngFor="let lang of langs"
              [value]="lang">{{lang}}
      </option>
    </select>
  </div>
 <input type="submit" value="Submit">
  <pre>{{myform.value | json}}</pre>
</form>

Gracias por vuestra ayuda
 
De acuerdo a la documentación hay 2 maneras de crear formularios, por plantillas o reactivamente.
Recomendacion, Hazlo paso a paso, linea por linea.

Te falto asignar correctamente el value a la variable hospital

<!-- Original -->
<div class="form-group">
<div class="dropdown">
<span class="selLabel">Select Hospital</span>
<input type="hidden" class="form-control" formControlName="hospital">
<ul class="dropdown-list">
<li *ngFor="let hospital of hospitals"
[value]="lang" >
<span>{{ hospital.name }}</span>
</li>
</ul>
</div>
</div>


<!-- Arreglado -->

<div class="form-group">
<div class="dropdown">
<span class="selLabel">Select Hospital</span>
<input type="hidden" class="form-control" formControlName="hospital">
<ul class="dropdown-list">
<li *ngFor="let hospital of hospitals"
[value]="hospital" >
<span>{{ hospital.name }}</span>
</li>
</ul>
</div>
</div>
 
Utiliza esto Online VS Code IDE for Modern Web Applications - StackBlitz, sube tu código y será mas fácil ayudarte en cualquier ayuda.

De todas formas es un poco extraño lo que quieres hacer pero dices que es por diseño entonces intente medio solucionarte lo más rápido que pude porque ando en horario de trabajo xD Y Aquí tienes :encouragement:angular-tjceq3 - StackBlitz

P.D.: antes utilizaba AngularJS y cuando salio Angular 2 fue lo más raro y confuso para mi y ahora es lo que me da de comer y me gusta mucho más de lo que me gusto Angular JS :encouragement:
 
Atrás
Arriba