No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Crear un formulario

19/22
Recursos

Conociendo la directiva聽[(ngModel)]聽que nos facilita el intercambio de datos de forma bidireccional entre la vista y el componente, puedes crear tu primer formulario apoy谩ndote de esta directiva y de otras caracter铆sticas propias de Angular para el manejo y validaci贸n de formularios.

Paso 1

Crea un simple formulario de Login en el HTML y las variables en el componente para capturar los valores de los campos con聽ngModel:

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  form = {
    email: '',
    password = ''
  };
}

<form>
    <div>
        <label></label>
        <input name="email" type="email" [(ngModel)]="form.email" required />
    </div>
    <div>
        <label></label>
        <input name="password" type="password" [(ngModel)]="form.password" required />
    </div>
    <div>
        <button type="submit">Iniciar sesi贸n</button>
    </div>
</form>

Paso 2

Agregale al componente un m茅todo que responda al evento del env铆o del formulario llamado聽submitLogin(). Puedes enlazar este m茅todo al formulario con la directiva聽(ngSubmit)聽que va colocada en la etiqueta聽<form>聽junto con una variable de template para ponerle un nombre al formulario como por ejemplo聽#formLogin="ngForm". Tienes que igualar el nombre de tu variable a聽ngForm聽para que Angular reconozca que se trata de un formulario.

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  form = {
    email: '',
    password = ''
  };
  submitLogin() {
    // Login del usuario
  }
}

<form (ngSubmit)="submitLogin()" #formLogin="ngForm">
    <div>
        <label></label>
        <input name="email" type="email" [(ngModel)]="form.email" required />
    </div>
    <div>
        <label></label>
        <input name="password" type="password" [(ngModel)]="form.password" required />
    </div>
    <div>
        <button type="submit">Iniciar sesi贸n</button>
    </div>
</form>

Paso 3

Finalmente, gracias a esta conexi贸n de tu formulario con el componente, se activar谩 el m茅todo聽submitLogin()聽al hacer clic en el bot贸n. Para validar tu formulario, utiliza la variable de template para imprimir un mensaje de error en pantalla o deshabilitar el bot贸n de env铆o de la siguiente manera:

...
<div>
    <button [disabled]="formLogin.invalid" type="submit">Iniciar sesi贸n</button>
</div>
...

Aporte creado por: Kevin Fiorentino.

Aportes 60

Preguntas 7

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Angular siempre me pareci贸 dif铆cil, pero Nicol谩s lo explica de una manera digerible que se entiende todo super sencillo.

Hasta ahora genial el curso. Me agrada mucho como explica Nico.

Wow, terminando este modulo, me doy cuenta que Angular tiene super poderes, nos facilita mucho en cuanto a validaciones de entrada de texto, bloqueos de elementos en el dom, y todo esto con puros metodos/propiedades ya insertadas en Angular.

Me demor茅 30 minutos para compartir mi aporte 馃槄

<h1 class="form-title">Formulario</h1>
<form class="form" (ngSubmit)="onRegister()" #myForm="ngForm">
  <div></div>
  <div class="input-group">
    <label class="form-label" for="Nombre">Nombre</label>
    <input class="form-input" type="text" name="name" required id="name" #nameInput="ngModel" [(ngModel)]="register.name" placeholder="Cesar">
    <p class="message--error" [class.invalid]="nameInput.invalid">Campo requerido</p>
  </div>
  <div></div>
  <div></div>
  <div class="input-group">
    <label class="form-label" for="Email">Email</label>
    <input class="form-input" type="email" name="email" required id="email" #emailInput="ngModel" [(ngModel)]="register.email">
    <p class="message--error" [class.invalid]="emailInput.invalid">Campo requerido</p>
  </div>
  <div></div>
  <div></div>
  <div class="input-group">
    <label class="form-label" for="password">Password</label>
    <input class="form-input" type="password" name="password" required id="password" #passwordInput="ngModel" [(ngModel)]="register.password">
    <p  class="message--error" [class.invalid]="passwordInput.invalid">Campo requerido</p>
  </div>
  <div></div>
  <div></div>
  <div class="form-buttons">
    <button class="buttonSubmit" [disabled]="myForm.invalid" type="submit">Registrar</button>
    <button class="buttonAction" type="button">Accion</button>
  </div>
</form>
.form-title {
  display: flex;
  justify-content: center;
  color: darkgreen;
  font-size: 2.4rem;
  font-family: cursive;
  padding-bottom: 2rem;
}

.form {
  display: grid;
  grid-template-columns: 40px minmax(345px, 530px) 40px;
  grid-template-rows: repeat(5, auto);
}

.input-group {
  display: grid;
  justify-items: stretch;
  padding-bottom: 30px;

  .form-label {
    font-family: cursive;
    padding-bottom: 5px;
  }

  .form-input {
    width: 100%;
    padding: 12px 20px;
    margin: 8px 0;
    box-sizing: border-box;
    border: 1.3px solid darkgreen;
    border-radius: 10px;
  }
}

.form-buttons {
  display: flex;
  margin: 10px;
  padding-bottom: 30px;
  justify-content: space-evenly;

  .buttonSubmit {
  font-size:15px;
  font-family:Arial;
  width:140px;
  height:50px;
  border-width:1px;
  color:#fff;
  border-color:#599bb3;
  font-weight:bold;
  border-top-left-radius:8px;
  border-top-right-radius:8px;
  border-bottom-left-radius:8px;
  border-bottom-right-radius:8px;
  box-shadow: 0px 10px 14px -7px #276873;
  text-shadow: 0px 1px 0px #3d768a;
  background:linear-gradient(#599bb3, #408c99);
  }

  .buttonSubmit:disabled {
    background: linear-gradient(27deg, rgba(0,0,0,1) 0%, rgba(195,190,183,1) 100%);
    background-color:transparent;
  }

  .buttonSubmit:hover {
    background: linear-gradient(#408c99, #599bb3);
  }

  .buttonAction {
    font-size:15px;
  font-family:Arial;
  width:140px;
  height:50px;
  border-width:1px;
  color:rgba(255, 255, 255, 1);
  border-color:#599bb3;
  font-weight:bold;
  border-top-left-radius:8px;
  border-top-right-radius:8px;
  border-bottom-left-radius:8px;
  border-bottom-right-radius:8px;
  box-shadow: 0px 10px 14px -7px #276873;
  text-shadow: 0px 1px 0px #3d768a;
  background:linear-gradient(rgba(121, 214, 217, 1), rgba(52, 198, 187, 1));
  }

  .buttonAction:hover {
    background: linear-gradient(rgba(52, 198, 187, 1), rgba(121, 214, 217, 1));
  }
}
.message--error {
  background-color: red;
  color: white;
  opacity: 0;
  transition: all linear .2s;
  &.invalid {
    opacity: 1;
  }
}

@media screen and (min-width: 400px) {
  .form {
    justify-content: center;
  }
}


Y aqu铆 el c贸digo:
HTML

<div class="form-container">
  <h1>My Account</h1>
  <form (ngSubmit)="onRegister()" #myForm="ngForm">
    <div class="input-group">
      <label for="name">Name</label>
      <input
        type="text"
        id="name"
        required
        [(ngModel)]="register.name"
        name="name"
      />
      <p
        class="form-error-msg"
        [ngClass]="{
          valid: register.name !== '',
          invalid: register.name === ''
        }"
      >
        Invalid or no data entered
      </p>
      <label for="email">Email</label>
      <input
        type="email"
        id="email"
        required
        [(ngModel)]="register.email"
        name="email"
      />
      <p
        class="form-error-msg"
        [ngClass]="{
          valid: register.email !== '',
          invalid: register.email === ''
        }"
      >
        Invalid or no data entered
      </p>
      <label for="password">Password</label>
      <input
        type="password"
        id="password"
        required
        [(ngModel)]="register.password"
        name="password"
      />
      <p
        class="form-error-msg"
        [ngClass]="{
          valid: register.password !== '',
          invalid: register.password === ''
        }"
      >
        Invalid or no data entered
      </p>
    </div>
    <button
      type="submit"
      [disabled]="myForm.invalid"
      [class.invalid]="myForm.invalid"
    >
      Register
    </button>
  </form>
</div>

CSS

.form-container {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  width: 100vw;
  height: 100vh;
  background-color: white;
  display: grid;
  place-content: center;
  font-family: "Roboto", "Open Sans", "Helvetica Neue", sans-serif;
  font-size: 14px;
  & h1 {
    margin-bottom: 40px;
    font-size: 16px;
  }
}

form {
  width: 300px;
}
.input-group {
  display: flex;
  flex-direction: column;
  & label {
    margin-bottom: 4px;
    font-weight: 600;
  }
  & input {
    border: none;
    outline: none;
    height: 24px;
    border-radius: 10px;
    padding: 4px 8px;
    background-color: whitesmoke;
    caret-color: green;
    color: rgb(98, 97, 97);
  }
}
button[type="submit"] {
  background-color: rgb(75, 161, 108);
  padding: 16px 24px;
  width: 100%;
  border-radius: 10px;
  color: white;
  font-weight: 700;
  border: none;
  outline: none;
  cursor: pointer;
  &.invalid {
    background-color: rgb(170, 208, 185);
  }
}

.form-error-msg {
  font-size: 12px;
  color: red;
  &.valid {
    opacity: 0;
  }
  &.invalid {
    opacity: 1;
  }
}

Les comparto mi formulario
https://angular-ivy-w9gqgv.stackblitz.io

Si queremos validar los campos del formulario una vez se han enviado o se ha interactuado con ellos podemos hacer lo siguiente:

Primero agregamos una template variable a nuestro formulario

<form class="form" #registerForm="ngForm" (ngSubmit)="onSubmit(registerForm)">
</form>

Como se ha visto en clases agregamos una almohadilla o numeral y le asignamos un nombre luego le indicamos que ser谩 un ngForm.
Una vez tenemos esto podemos validar los campos del formulario de la siguiente manera:

  <div class="form-control">
    <input
      placeholder="Email"
      type="email"
      name="email"
      required
      [(ngModel)]="register.email"
    />
    <span
      class="helper-text"
      [class.visible]="
        (registerForm.submitted || registerForm.controls['email']?.touched) &&
        registerForm.controls['email'].invalid
      "
    >
      Error el campo email es requerido
    </span>
  </div>

Lo que hacemos aqu铆 es agregar una clase visible al span que contiene la clase helper-text basado en la condici贸n de que el usuario ha enviado el formulario o ya interactu贸 con el y adem谩s el campo es invalido.
Si quieren saber mas del funcionamiento de NgForm les recomiendo la documentaci贸n tambi茅n les dejo la documentaci贸n de los controles del formulario.

El formulario completo quedar铆a de la siguiente forma:

<form class="form" #registerForm="ngForm" (ngSubmit)="onSubmit(registerForm)">
  <div class="form-control">
    <input
      placeholder="Email"
      type="email"
      name="email"
      required
      [(ngModel)]="register.email"
    />
    <span
      class="helper-text"
      [class.visible]="
        (registerForm.submitted || registerForm.controls['email']?.touched) &&
        registerForm.controls['email'].invalid
      "
    >
      Error el campo email es requerido
    </span>
  </div>
  <div class="form-control">
    <input
      placeholder="Password"
      type="password"
      name="password"
      required
      [(ngModel)]="register.password"
    />
    <span
      class="helper-text"
      [class.visible]="
        (registerForm.submitted ||
          registerForm.controls['password']?.touched) &&
        registerForm.controls['password'].invalid
      "
    >
      Error el campo password es requerido
    </span>
  </div>
  <button type="submit">Register</button>
</form>

![](

Es poquito pero es trabajo honesto 馃槉
https://angular-ivy-dhnggy.stackblitz.io/


*

*
En StackBlitz no queda igual pero comparto el link
https://angular-9-material-starter-9imqxb.stackblitz.io

algo que no veo que mencionen es que los inputs tienen un validador para el email un poco mejor y es usando el atributo

pattern="^[^@][email protected][^@]+\.[a-zA-Z]{2,}$"

podriamos usar esa aexpresion regular para validar el formato de email. ya que como queda finalmente el formulario, puedes poner una letra y ya es valido, con esto obliga al usuario a poner un email de forma correcta

Si te sale el error Can't bind to 'ngModel' since it isn't a known property of 'input', agrega en el app.module.ts el Forms Module

import { FormsModule } from '@angular/forms';

[...]

@NgModule({
  imports: [
    [...]
    FormsModule
  ],
  [...]
})

Explicas muy bien, solo te falta orden. Es bueno borrar clases anteriores en el c贸digo, para no confundir.

Peque帽o aporte: Con todo lo aprendido ya podemos crear un formulario sencillo de registro y hacer algunas validaciones. Lo primero ser铆a crear el modelo de datos que se van a registrar en nuestro controlador

Lo segundo es crear el 鈥渇orm鈥 con los inputs dentro. Cada input va a estar manejado con [(ngModel)] y va corresponder a uno de las propiedades del objeto 鈥渞egister鈥.
Luego creamos el bot贸n para registrar esos datos. Algo muy importante a tener en cuenta es que siempre que estemos utilizando botones dentro de formularios debemos colocarle un type de alg煤n tipo. En el caso de que se trate del bot贸n que va a enviar la informaci贸n ser谩 de tipo submit 鈥渟ubmit鈥. Aqu铆 es donde podemos colocar una validaci贸n para el conjunto de los inputs del formulario haciendo que el bot贸n quede deshabilitado hasta tanto no se completen todos los campos. Esto lo hacemos usando property binding con el atributo disabled e igualandolo a la versi贸n 鈥渋nvalid鈥 de la variable template 鈥渇ormRegister鈥.

Por 煤ltimo solo resta especificar la acci贸n que se va ejecutar una vez que el formulario sea enviado. Para esto en la etiqueta form utilizamos (ngSubmit) y lo igualamos a una funci贸n, declarada en el controlador, que por el momento solo va a mostrar por consola los datos ingresados.

Etiqueta <button> dentro de los formularios

Por regla, la 煤ltima etiqueta <button> dentro de una etiqueta <form> ser谩 del tipo submit, asi que en si se pone al final un <button> y no se especifica el tipo entonces el browser lo entender谩 del tipo submit, aunque ya tengamos previamente otro <button> del tipo submit.

Me gusto mucho mi resultado, me guie de otros codigos pero al final lo personalice a lo que me gusta 馃榿

Estimados, en el examen hay una pregunta que dice:

驴Cu谩l paquete de Angular debemos importar en el App M贸dulo para trabajar con NgModel?

Pero no dice que es para trabajar con Forms, entonces esta mal formulada la pregunta.

Formulario de registro

Formulario de Login

Excelente curso 馃槂.

Me ha gustado mucho Angular, siento que rinde mucho m谩s el tiempo de desarrollo frente a React.

siempre vi angualr como una herramienta para seniors ya que me estoy familiarizando con ella la empiezo a entender y me encanta todo de ella

<h1>Formulario</h1>
<form (ngSubmit)="onRegister()" #myForm="ngForm">
  <div class="input-group">
    <label for="name">Nombre</label>
    <input
      required
      type="text"
      id="name"
      [(ngModel)]="register.name"
      name="name"
      placeholder="Your name here"
      #userName="ngModel"
      class="myForm"
      [ngClass]="{ 'invalid': userName.invalid }"
    >
    <p>Mensajes de error</p>
  </div>

  <div class="input-group">
    <label for="email">Email</label>
    <input
      required
      type="email"
      id="email"
      [(ngModel)]="register.email"
      name="email"
      placeholder="Your email here"
      #email="ngModel"
      class="myForm"
      [ngClass]="{ 'invalid': email.invalid }"
    >
    <p>Mensajes de error</p>
  </div>

  <div class="input-group">
    <label for="password">Password</label>
    <input
      required
      type="password"
      id="password"
      [(ngModel)]="register.password"
      name="password"
      #password="ngModel"
      class="myForm"
      [ngClass]="{ 'invalid': password.invalid }"
    >
    <p>Mensajes de error</p>
  </div>

  <button [disabled]="myForm.invalid" type="submit">Registrar</button>
</form>

Aqui les dejo mi aporte donde he aplicado parte de lo aprendido hasta ahora

https://angular-ivy-yrdeat.stackblitz.io/

Les comparto mi formulario:

Algo b谩sico pero se practic贸 lo aprendido 馃槂
https://angular-ivy-4ayp1d.stackblitz.io

Queridos compa帽eros, me gustar铆a compartirles como pude hacer mi practica de mi formulario, incluso, estuve adelantando un poco de lo que he estado aprendiendo de css.



Aunque si tengo que practicar sobre el binding porque yo segu铆a pensando que no pod铆a cambiando el nombre cuando pones [class] el XXX se cambiaba el nombre para el css, aun ando un poco confundido en esa parte.

me gusto mucho como este profesor explica la clase, de verdad es muy autentico. gracias! saludos

Yo jam谩s me animaba a aprender Angular porque se dec铆a que era dif铆cil, hasta que por el trabajo tuve que empezar a usarlo y gracias a este curso es que la estoy pasando sin problema alguno. Nicolas es un capo ense帽ando.

鉁屸湆鉁

Pense en no compartir el mio, ya que los de ustedes son waoo, pero estoy empezando y es trabajo honesto :p

Hola, les comparto mi avance hasta este punto de el curso usando lo que nos ha explicado el Nico y me tome el atrevimiento de usar mas sass y jugar mas con los estilos.

Hize tre panntallas:

  • Login
  • Registro
  • Recuperar contrase帽a

Como dato adicional, para los iconos use una libreria llamada font awesome. Lo unico que hize fue agregar el cdn al index.html y listo.
Link libreria iconos: https://fontawesome.com/

  • Pantalla de Login:
  • Panatalla de registro:
  • Pantalla de recuperar contrase帽a:
  • Panatlla listado de productos:

Mi Ejercicio de Formulario

Este es mi aporte, en vez de poner error en los input, hice que el bot贸n se deshabilitara cuando el input sea invalido.

Siento que angular es muy complicado, pero dando el primer paso es que se empieza aprender las cosas dificiles, gracias platzi por este maravilloso curso.

Te comparto mis ejemplo:

**Y el c贸digo:

HTML

<h1 class="form-title">My registration form</h1>
<form (ngSubmit)="onRegister()" #myForm="ngForm" id="myform">
  <div class="input-group">
    <label for="name">Name</label>
    <div>
      <input type="text" [class.input-error]="nameInput5.invalid" #nameInput5="ngModel" name="name" required id="name"
        [(ngModel)]="register.name">
      <p class="field-error" [class.invalid]="nameInput5.invalid">Name is required</p>
    </div>
  </div>
  <div class="input-group">
    <label for="email">Email</label>
    <div>
      <input type="email" [class.input-error]="emailInput.invalid" #emailInput="ngModel" name="email" required
        id="email" [(ngModel)]="register.email">
      <p class="field-error" [class.invalid]="emailInput.invalid">Email is required</p>
    </div>
  </div>
  <div class="input-group">
    <label for="pwd">Password</label>
    <div>
      <input type="password" [class.input-error]="pwdinput.invalid" #pwdinput="ngModel" name="password" required
        id="pwd" [(ngModel)]="register.password">
      <p class="field-error" [class.invalid]="pwdinput.invalid">Password is required</p>
    </div>
  </div>
  <div class="button-group">
    <button [disabled]="myForm.invalid" [class.btn-error]="myForm.invalid" type="submit">Register</button>
    <button type="button">Action</button>
  </div>
</form>
<hr />

SCSS

.form-title{
  text-align: center;
}

.field-error{
  margin-top: 2px;
  font-size: small;
  text-align: center;
  color: brown;
  opacity: 0;
  transition: all .5s;
  &.invalid{
    opacity: 1;
  }
}

.input-group{
  max-width: 60%;
  margin-left: auto;
  margin-right: auto;
}

#myform input{
  width: 100%;
  height: 2em;
  border-style: solid;
  border-radius: 10px;
  border-color: cadetblue;
  &.input-error{
    border-color: brown;
  }
}

#myform label{
  font-weight: bold;
}

#myform button{
  margin: 1%;
  width: 30em;
  height: 3em;
  border-radius: 10px;
  border-style: solid;
  background-color: cadetblue;
  color: blanchedalmond;
  &.btn-error{
    background-color: brown;
  }
}

.button-group{
  text-align: center;
}

My formulario

Despues de solucionar el problema del enrutamiento para poder mostrar ambos vistas (login y register) en el mismo proyecto, fui capaz de hacer el reto aplicando todo lo aprendido hasta ahora. Excelente curso @nicobytes!!!
Angular-register-login

Realmente lo que m谩s me gusto de este curso es que Nico no da vueltas a lo tema explica claro y no tan pausado a pesar de un curso basico. Y asume que hay cosas que ya sabemos y creo que ese es el plus de este curso que no vuelve sobre lo visto si no lo utiliza.

Este es mi formulario, cada campo tiene su validaci贸n y aparece y desaparece campo requerido de acuerdo a si el campo es valido o no.

Envi贸 mi primer registro de usuario en Angular: https://angular-ivy-cfkyjk.stackblitz.io

Hace tiempo he querido aprender este Framework, he oido que lo usa en entornos empresariales, y por aqui vamos dandole. Solo hay que tener bases de html y css

Muy buen dominio del tema, muchas gracias @NicolasMolina

Este fue mi reto

Deber铆an de dar clases de como solucionar problemas al actualizar sistemas y sobre problemas al ejecutar programas.

Excelente curso Nicolas 馃
猸愶笍猸愶笍猸愶笍猸愶笍猸愶笍