Conoce la importancia de los formularios para tu sitio web

1

¿Por qué aprender Angular Forms?

2

Presentación del proyecto: tour por los formularios de Platzi Store

3

Novedades de Angular 10: cómo migrar proyectos de Angular 8 o 9 a la versión 10

Primeros pasos con Angular Forms

4

Template Forms vs. Reactive Forms

5

Dominando el FormControl y sus estados

6

Cómo usar inputs de texto y la importancia del type

7

Manejo y binding de selects y selects múltiples

8

Manejo y binding de inputs radio y checkbox

9

Aplica validaciones a un FormControl

10

Integración y validaciones con CSS para mostrar errores

Descubre todas las validaciones de Angular Forms

11

Usando FormGroup para agrupar multiples campos

12

Reactive Forms con FormBuilder

13

Los 11 validadores de Angular (y expresiones regulares)

14

Manejando múltiples FormsGroups

15

Usando componentes de Angular Material

16

Errores comunes de usabilidad en formularios

17

Validaciones personalizadas: mejorando nuestro formulario de registro

Implemeta validaciones avanzadas en PlatziStore

18

Cómo hacer validaciones grupales en Angular Forms

19

Validaciones condicionadas y reactividad a variaciones en la UI

20

Proyecto: formulario para crear categorías de productos

21

Proyecto: conectando nuestro formulario y la API

22

Proyecto: subir imágenes a Firebase Storage

23

Validaciones asincrónicas

24

PatchValue: crear vs. editar

25

Proyecto: creando el método de editar categorías

Construye formularios dinámicos conectando una API

26

Smart vs. dumb components: un patrón para dividir responsabilidades

27

Implementando smart y dumb components en PlatziStore

28

Proyecto: mejorando nuestro formulario de productos

29

Select dinámico: carga opciones desde una API

30

Select dinámico: trabajando con objetos

31

¿Cómo crear campos on demand? Forms dinámicos con FormArray

Estrategias avanzadas y optimización de formularios

32

Crea tu propia librería de componentes con CVA o Control Value Accesor

33

Crea un buscador de gifs usando la API de Giphy

34

Optimiza un input de búsquedas con RxJS y debounce

35

Examina la accesibilidad de tus formularios

36

Siguientes pasos en tu carrera de desarrollo web profesional con Angular

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Usando componentes de Angular Material

15/36
Recursos

Aportes 6

Preguntas 6

Ordenar por:

Los aportes, preguntas y respuestas son vitales para aprender en comunidad. Regístrate o inicia sesión para participar.

Bueno así me quedo, como que el input de tipo color no me convence, tocaría checarle más la documentación de material haber si hay como darle un mejor aspecto.

Alternativa para el manejo de los mensajes de error. Resulta que mat-error debe ser hijo directo de mat-form-field para que se integre bien y visualmente se vea más cool. Además con esta alternativa podría utilizar varios mensajes según el error. Recordemos que en el ng-container no se renderiza si no lo que haya adentro (Ahora que lo pienso se parece al fragment de React 🤔)

<mat-form-field>
		<mat-label>Name</mat-label>
		<input type="text" matInput formControlName="name"/>
		<mat-icon matSuffix>sentiment_very_satisfied</mat-icon>
		<mat-error *ngIf="nameField.touched && nameField.invalid">
			<ng-container *ngIf="nameField.hasError('required')">El campo nombre es requerido</ng-container>
			<ng-container *ngIf="nameField.hasError('maxlength')">El campo nombre no puede tener más de 10 caracteres</ng-container>
		</mat-error>
</mat-form-field>

Así me va quedando

html

<<form [formGroup]="form" (ngSubmit)="send()">
  <div formGroupName="fullName">
    <mat-form-field>
      <mat-label>Name</mat-label>
      <input type="text" formControlName="name" matInput>
      <mat-icon matSuffix color="primary" *ngIf="isNameValid()">done</mat-icon>
      <mat-icon matSuffix color="warn" *ngIf="isNameInvalid()">close</mat-icon>
    </mat-form-field>
    <div class="messages" [class.active]="isNameInvalid()">
      <mat-error *ngIf="name().hasError('required') && name().touched">Este campo es requerido</mat-error>
      <mat-error *ngIf="name().hasError('maxlength')">El máximo son de 10 caracteres</mat-error>
      <mat-error *ngIf="name().hasError('pattern')">El nombre no debe tener caracteres</mat-error>
    </div>

    <mat-form-field>
      <mat-label>Last</mat-label>
      <input type="text" formControlName="last" matInput>
      <mat-icon matSuffix color="primary" *ngIf="isLastValid()">done</mat-icon>
      <mat-icon matSuffix color="warn" *ngIf="isLastInvalid()">close</mat-icon>
    </mat-form-field>
    <div class="messages" [class.active]="isLastInvalid()">
      <mat-error *ngIf="last().hasError('required') && last().touched">Este campo es requerido</mat-error>
      <mat-error *ngIf="last().hasError('maxlength')">El máximo son de 10 caracteres</mat-error>
      <mat-error *ngIf="last().hasError('pattern')">El nombre no debe tener caracteres</mat-error>
    </div>
  </div>

  <mat-form-field>
    <mat-label>Email</mat-label>
    <input type="email" formControlName="email" matInput>
    <mat-icon matSuffix color="primary" *ngIf="isEmailValid()">done</mat-icon>
    <mat-icon matSuffix color="warn" *ngIf="isEmailInvalid()">close</mat-icon>
  </mat-form-field>
  <div class="messages" [class.active]="isEmailInvalid()">
    <mat-error *ngIf="email().hasError('required') && email().touched">Este campo es requerido</mat-error>
    <mat-error *ngIf="email().hasError('email') && email().touched">Este no es un email válido</mat-error>
  </div>

  <mat-form-field>
    <mat-label>Phone</mat-label>
    <input type="tel" formControlName="phone" matInput>
    <mat-icon matSuffix color="primary" *ngIf="isPhoneValid()">done</mat-icon>
    <mat-icon matSuffix color="warn" *ngIf="isPhoneInvalid()">close</mat-icon>
  </mat-form-field>
  <div class="messages" [class.active]="isPhoneInvalid()">
    <mat-error *ngIf="phone().hasError('required') && phone().touched">Este campo es requerido</mat-error>
  </div>

  <mat-form-field>
    <mat-label>Color</mat-label>
    <input type="color" formControlName="color" matInput>
    <mat-icon matSuffix color="primary" *ngIf="isColorValid()">done</mat-icon>
    <mat-icon matSuffix color="warn" *ngIf="isColorInvalid()">close</mat-icon>
  </mat-form-field>
  <div class="messages" [class.active]="isColorInvalid()">
    <mat-error *ngIf="color().hasError('required') && color().touched">Este campo es requerido</mat-error>
  </div>

  <mat-form-field>
    <mat-label>Date</mat-label>
    <input matInput formControlName="date" [matDatepicker]="picker">
    <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
    <mat-datepicker #picker></mat-datepicker>
    <mat-icon matSuffix color="primary" *ngIf="isDateValid()">done</mat-icon>
    <mat-icon matSuffix color="warn" *ngIf="isDateInvalid()">close</mat-icon>
  </mat-form-field>
  <div class="messages" [class.active]="isDateInvalid()">
    <mat-error *ngIf="date().hasError('required') && date().touched">Este campo es requerido</mat-error>
  </div>

  <mat-form-field>
    <mat-label>Age</mat-label>
    <input type="number" formControlName="age" matInput>
    <mat-icon matSuffix color="primary" *ngIf="isAgeValid()">done</mat-icon>
    <mat-icon matSuffix color="warn" *ngIf="isAgeInvalid()">close</mat-icon>
  </mat-form-field>
  <div class="messages" [class.active]="isAgeInvalid()">
    <mat-error *ngIf="age().hasError('required') && age().touched">Este campo es requerido</mat-error>
    <mat-error *ngIf="age().hasError('min') && age().touched">Debe ser mayor mayot de edad</mat-error>
    <mat-error *ngIf="age().hasError('max') && age().touched">Debe estar vivo</mat-error>
  </div>

  <mat-form-field>
    <mat-label>Url</mat-label>
    <input type="url" formControlName="url" matInput>
    <mat-icon matSuffix color="primary" *ngIf="isUrlValid()">done</mat-icon>
    <mat-icon matSuffix color="warn" *ngIf="isUrlInvalid()">close</mat-icon>
  </mat-form-field>
  <div class="messages" [class.active]="isUrlInvalid()">
    <mat-error *ngIf="url().hasError('required') && url().touched">Este campo es requerido</mat-error>
  </div>

  <mat-form-field>
    <mat-label>Category</mat-label>
    <mat-select formControlName="category">
      <mat-option value="cat1-db 1">category-1 showed</mat-option>
      <mat-option value="cat2-db 2">category-2 showed</mat-option>
      <mat-option value="cat3-db 3">category-3 showed</mat-option>
      <mat-option value="cat4-db 4">category-4 showed</mat-option>
    </mat-select>
    <mat-icon matSuffix color="primary" *ngIf="isCategoryValid()">done</mat-icon>
    <mat-icon matSuffix color="warn" *ngIf="isCategoryInvalid()">close</mat-icon>
  </mat-form-field>
  <div class="messages" [class.active]="isCategoryInvalid()">
    <mat-error *ngIf="category().hasError('required') && category().touched">Este campo es requerido</mat-error>
  </div>

  <mat-form-field>
    <mat-label>Tag</mat-label>
    <mat-select formControlName="tag" multiple>
      <mat-option value="tag-db 1">tag-1 showed</mat-option>
      <mat-option value="tag-db 2">tag-2 showed</mat-option>
      <mat-option value="tag-db 3">tag-3 showed</mat-option>
      <mat-option value="tag-db 4">tag-4 showed</mat-option>
    </mat-select>
    <mat-icon matSuffix color="primary" *ngIf="isTagValid()">done</mat-icon>
    <mat-icon matSuffix color="warn" *ngIf="isTagInvalid()">close</mat-icon>
  </mat-form-field>

  <mat-checkbox id="agree" formControlName="agree">Agree</mat-checkbox>
  <div class="messages" [class.active]="isAgreeInvalid()">
    <mat-error *ngIf="agree().hasError('required') && agree().touched">debe aceptar los términos y condiciones
    </mat-error>
  </div>
  <mat-radio-group formControlName="gender">
    <mat-radio-button value="Masculino">Masculino</mat-radio-button>
    <mat-radio-button value="Femenino">Femenino</mat-radio-button>
    <mat-radio-button value="Otro">Otro</mat-radio-button>
  </mat-radio-group>
  <div class="messages" [class.active]="isGenderInvalid()">
    <strong *ngIf="gender().hasError('required') && gender().touched">Este campo es requerido</strong>
  </div>

  <mat-radio-group formControlName="zone">
    <mat-radio-button value="zona-1">zona-1</mat-radio-button>
    <mat-radio-button value="zona-2">zona-2</mat-radio-button>
    <mat-radio-button value="zona-3">zona-3</mat-radio-button>
    <mat-radio-button value="zona-4">zona-4</mat-radio-button>
  </mat-radio-group>
  <div class="messa ges" [class.active]="isZoneInvalid()">
    <strong *ngIf="zone().hasError('required') && zone().touched">Este campo es requerido</strong>
  </div>

  <button mat-raised-button type="submit" color="primary">Enviar</button>
</form>

> 

Typescript

<import {Component, OnInit} from '@angular/core';
import {FormBuilder, FormGroup, Validators} from '@angular/forms';

@Component({
  selector: 'app-builder-form',
  templateUrl: './builder-form.component.html',
  styleUrls: ['./builder-form.component.scss']
})
export class BuilderFormComponent implements OnInit {

  form: FormGroup;

  constructor(private formBuilder: FormBuilder) {
    this.buildForm();
  }

  ngOnInit(): void {
    this.name().valueChanges.subscribe(value => console.log(value)); // Observable dentro de angular
    this.form.valueChanges.subscribe(value => console.log(value));
  }

  buildForm(): void {
    this.form = this.formBuilder.group({
      fullName: this.formBuilder.group({
        name: ['', [Validators.required, Validators.maxLength(10), Validators.pattern(/^[a-zA-Z ]+$/)]],
        last: ['', [Validators.required, Validators.maxLength(10), Validators.pattern(/^[a-zA-Z ]+$/)]]
      }),
      email: ['', [Validators.required, Validators.email]],
      phone: ['', Validators.required],
      color: ['#FFFFFF', Validators.required],
      date: ['', Validators.required],
      age: ['', [Validators.required, Validators.min(18), Validators.max(100)]],
      url: ['', Validators.required],
      category: ['', Validators.required],
      tag: ['', Validators.required],
      agree: [false, [Validators.requiredTrue]],
      gender: ['', Validators.required],
      zone: ['', Validators.required]
    });
  }

  name = () => this.form.get('fullName.name');
  last = () => this.form.get('fullName.last');
  email = () => this.form.get('email');
  phone = () => this.form.get('phone');
  color = () => this.form.get('color');
  date = () => this.form.get('date');
  age = () => this.form.get('age');
  url = () => this.form.get('url');
  category = () => this.form.get('category');
  tag = () => this.form.get('tag');
  agree = () => this.form.get('agree');
  gender = () => this.form.get('gender');
  zone = () => this.form.get('zone');

  isNameValid = () => this.name().valid && this.name().touched;
  isNameInvalid = () => this.name().invalid && this.name().touched;

  isLastValid = () => this.last().valid && this.last().touched;
  isLastInvalid = () => this.last().invalid && this.last().touched;

  isEmailValid = () => this.email().valid && this.email().touched;
  isEmailInvalid = () => this.email().invalid && this.email().touched;

  isPhoneValid = () => this.phone().valid && this.phone().touched;
  isPhoneInvalid = () => this.phone().invalid && this.phone().touched;

  isColorValid = () => this.color().valid && this.color().touched;
  isColorInvalid = () => this.color().invalid && this.color().touched;

  isDateValid = () => this.date().valid && this.date().touched;
  isDateInvalid = () => this.date().invalid && this.date().touched;

  isAgeValid = () => this.age().valid && this.age().touched;
  isAgeInvalid = () => this.age().invalid && this.age().touched;

  isUrlValid = () => this.url().valid && this.url().touched;
  isUrlInvalid = () => this.url().invalid && this.url().touched;

  isCategoryValid = () => this.category().valid && this.category().touched;
  isCategoryInvalid = () => this.category().invalid && this.category().touched;

  isTagValid = () => this.tag().valid && this.tag().touched;
  isTagInvalid = () => this.tag().invalid && this.tag().touched;

  isAgreeValid = () => this.agree().valid && this.agree().touched;
  isAgreeInvalid = () => this.agree().invalid && this.agree().touched;

  isGenderValid = () => this.gender().valid && this.gender().touched;
  isGenderInvalid = () => this.gender().invalid && this.gender().touched;

  isZoneValid = () => this.zone().valid && this.zone().touched;
  isZoneInvalid = () => this.zone().invalid && this.zone().touched;

  send(): void {
    this.form.valid ? this.formValid() : this.form.markAllAsTouched();
  }

  formValid(): void {
    this.buildForm();
  }

}
> 

Así me quedó, utilicé mat-card me parecía un poco mas bonito:

Creo q me adelante preguntando en el otro video jj perdon