Primeros pasos
Qué es Angular: ventajas y cómo aprenderlo
Instalación de Angular CLI
Comandos de Angular para correr tu proyecto
Estructura de un proyecto en Angular
Conceptos básicos de TypeScript para usar Angular
Comunicación de datos
String interpolation
Property Binding
Introducción al Event Binding de Angular
Otros eventos que puedes escuchar
Data binding con ngModel
Estructuras de control
Uso de *ngIf
Uso de *ngFor
*ngFor para arrays
Uso de *ngSwitch
Angular Devtools
Estilos
Estilos a la lista de productos
Class and style
NgClass y NgStyle
Crear un formulario
Deploy
Despliegue con Firebase Hosting
Despedida
Continúa con el Curso de Angular: Componentes y Servicios
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Nicolas Molina
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.
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>
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>
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 68
Preguntas 9
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;
}
}
Les comparto mi formulario
https://angular-ivy-w9gqgv.stackblitz.io
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;
}
}
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/
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="^[^@]+@[^@]+\.[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
Explicas muy bien, solo te falta orden. Es bueno borrar clases anteriores en el código, para no confundir.
![](
*
*
En StackBlitz no queda igual pero comparto el link
https://angular-9-material-starter-9imqxb.stackblitz.io
No agregue tanto diseño como algunos compañeros pero es mi esfuerzo de aprendizaje básico. 😉
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 “form” con los inputs dentro. Cada input va a estar manejado con [(ngModel)] y va corresponder a uno de las propiedades del objeto “register”.
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 “submit”. 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 “invalid” de la variable template “formRegister”.
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.
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
],
[...]
})
Dejo aqui mi aporte a la causa ;D
URL: https://angular-2i3hng.stackblitz.io
✌✌✌
<button>
dentro de los formulariosPor 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.
✅
Este sería mi resultado
Me quedaron varias dudas y mi formulario le faltaron agregar varios detalles que estoy seguro que podre aclarar en el curso de Angular Forms
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
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:
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/
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 🤖
⭐️⭐️⭐️⭐️⭐️
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?