Está en la página 1de 7

Fechas y Listas desplegables

En este ejercicio abordaremos 2 temas: input de fechas y listas desplegables con filtrado y
ordenamiento.

Input de fechas en component de admin-usuarios.

1. Primero que todo debemos importar los módulos MdDatepickerModule y


MdNativeDateModule de Angular Material en el administrador.module para poder
usar el mdDataPicker y también dar soporte a los formatos de fechas. Además
también adicionaremos MdAutocompleteModule para la lista con función de
autocompletar.

import {
MdButtonModule,
MdCardModule,
MdDatepickerModule,
MdNativeDateModule,
MdInputModule,
MdAutocompleteModule } from '@angular/material';

Luego se deben agregar al decorador de imports.

2. Agregar el md-datapicker en el Template de admin-usuarios:


● (click)="pickerFecha.open()" Cuando se haga clic en el input abrirá el md-datapicker
● onkeydown="return false" Agregamos esta linea para que el usuario no pueda
introducir manualmente las fechas.
● [min]="fechaMinima" y [max]="fechaMaxima" establecen las fechas mínimas y
máximas que admitirá el md-datapicker.
● [mdDatepicker]="pickerFecha" Indicamos cuál será el md-datapicker asociado a
este input
● [mdDatepickerToggle]="pickerFecha" Le decimos a este botón que también pueda
abrir el md-datapicker cuando se dé click sobre él
● <md-datepicker #pickerFecha touchUi="true"></md-datepicker> Es el md-datapicker
que se abrirá y #pickerFecha indica su ID

<md-form-field class="third-width" dividerColor="{{(erroresFormulario.fechaCaducidad) ?


'warn' : 'primary'}}">
<input mdInput
formControlName="fechaCaducidad"
(click)="pickerFecha.open()"
onkeydown="return false"
[min]="fechaMinima"
[max]="fechaMaxima"
[mdDatepicker]="pickerFecha"
placeholder="Fecha de caducidad">
<md-datepicker-toggle mdSuffix [for]="pickerFecha"></md-datepicker-toggle>
<md-hint>
<span [hidden]="!(erroresFormulario.fechaCaducidad)">
{{erroresFormulario.fechaCaducidad}}</span>
</md-hint>
</md-form-field>
<md-datepicker #pickerFecha touchUi="true"></md-datepicker>

3. Modificamos el admin-usuarios-component

Agregamos la fecha mínima y máxima

fechaMaxima = new Date(2020, 1, 1);


fechaMinima = new Date();
..
constructor( … ){..}
..
En el método onSubmit agregamos lo siguiente para que el objeto tipo usuario que se
guardará tenga la fecha el en formato correcto.

// Obtenemos el valor de la fecha del control fechaCaducidad


let fechaCaducidad = this.formUsuarios.get('fechaCaducidad').value;
let fechaCaducidadString = fechaCaducidad.toISOString();
this.usuario.fechaCaducidad = fechaCaducidadString;

Listas desplegables con filtro y ordenamiento:

Dado que en Angular fue eliminado el pipe para ordenar listas (debido al mal uso que le
daban, el cual hacía la aplicación más lenta), tenemos que crear el nuestro. Lo ideal es
usarlo en las listas que de verdad lo requieran, es decir, en listas de muchos elementos.
El pipe lo usaremos en las listas de géneros de videos y en el tipo de video.
1. Primero creamos el pipe ordenarArreglo en la carpeta pipes/

import { Pipe, PipeTransform } from '@angular/core';


@Pipe({ name: 'ordenarArreglo' })
export class OrdenarArregloPipe implements PipeTransform {

/**
* Método para ordenar un arreglo de string
* @param arreglo
*/
transform(arreglo: string[]) {
if (arreglo.length >0) {
let arregloOrdenado: string[] = arreglo.sort((n1, n2) => {
if (n1 > n2) {
return 1;
}

if (n1 < n2) {


return -1;
}

return 0;
});

return arregloOrdenado;
}
}
}

/////// Identical except for the pure flag


@Pipe({
name: 'ordenarArregloImpure',
pure: false
})
export class OrdenarArregloPipeImpure extends OrdenarArregloPipe { }

2. Ahora se debe matricular el pipe en el administrador.module.


Se creó un pipe impuro como ejemplo en este ejercicio. la definición de pipes puros e
impuros está aquí
import { OrdenarArregloPipe, OrdenarArregloPipeImpure } from '../pipes/ordenar-
arreglo.pipe';
y se agrega en el decorador de providers.

3. Modificamos el Template de admin-usuarios:


● [mdAutocomplete]="autoTipo" Indicamos cuál será el md-autocomplete que usará
nuestro input
● #autoTipo="mdAutocomplete" Indicamos el ID para nuestro md-autocomplete
● *ngFor="let tipo of lista_tipo_usuario_filtrado | async" [value]="tipo.nombre iteramos
sobre la lista de tipos de usuario e indicamos que el valor será tipo.nombre

<md-form-field dividerColor="{{(erroresFormulario.tipoUsuario) ? 'warn' : 'primary'}}"


class="select-container">
<input mdInput formControlName="tipoUsuario" placeholder="Tipo de usuario"
type="text" [mdAutocomplete]="autoTipo">
<md-hint>
<span [hidden]="!(erroresFormulario.tipoUsuario)">
{{erroresFormulario.tipoUsuario}}</span>
</md-hint>
<md-autocomplete #autoTipo="mdAutocomplete">
<md-option *ngFor="let tipo of lista_tipo_usuario_filtrado | async"
[value]="tipo.nombre">
{{ tipo.nombre }}
</md-option>
</md-autocomplete>
</md-form-field>

4. Por último en el admin-usuarios.component

Agregamos una lista para filtrar sobre ella


lista_tipo_usuario_filtrado: any;
Agregamos 3 métodos
asignarFiltradoListasDesplegables() Método que asigna a cada lista desplegable de filtrado
un método para llevar a cabo el filtro
filtrarListaDesplegable() Método que filtra un valor en una lista general
validarListasDesplegables() Método para validar que lo que se escriba en los campos de
listas desplegables estén dentro de los elementos establecidos

/**
* Método que asigna a cada lista desplegable de filtrado un método para llevar a cabo el
filtro
*/
asignarFiltradoListasDesplegables() {
this.lista_tipo_usuario_filtrado = this.formUsuarios.get('tipoUsuario').valueChanges
.startWith(null)
.map(val => this.filtrarListaDesplegable(val, 'tipoUsuario'));
}
/**
* Método que filtra un valor en una lista general
* @param val : valor
* @param tipo : Identificador de la lista
*/
filtrarListaDesplegable(val: string, tipo: string) {
switch (tipo) {
case 'tipoUsuario':
return val ? this.lista_tipo_usuario.filter(s =>
s.nombre.toLowerCase().indexOf(val.toLowerCase()) === 0)
: this.lista_tipo_usuario;
default:
break;
}

/**
* Método para validar que lo que se escriba en los campos de listas desplegables
* estén dentro de los elementos establecidos
*/
validarListasDesplegables() {
let nombre = this.formUsuarios.get('tipoUsuario').value;
let nombre_corto = '';
switch (nombre) {
case this.lista_tipo_usuario[0].nombre:
nombre_corto = this.lista_tipo_usuario[0].nombre_corto;
this.usuario.tipoUsuario = nombre_corto;
break;
case this.lista_tipo_usuario[1].nombre:
nombre_corto = this.lista_tipo_usuario[0].nombre_corto;
this.usuario.tipoUsuario = nombre_corto;
break;

default:
// Si el valor ingresado no corresponde a ninguno de esos dos se genera un error
this.mensajesError.push('El campo Tipo de usuario contiene una opción que no
pertenece a la lista desplegable.');
this.formUsuarios.get('tipoUsuario').setErrors({
validacionLista: 'Solo puede elegir un elemento de la lista desplegable.'
});
this.erroresFormulario['tipoUsuario'] = 'Solo puede elegir un elemento de la lista
desplegable.';
break;
}

En el constructor llamamos a
this.asignarFiltradoListasDesplegables();

y en el onSubmit, después de this.usuario = this.formUsuarios.value;


agregamos lo siguiente para validar los valores ingresados en el input desplegable

this.validarListasDesplegables();

// Si hubo un error en las validaciones previas


if (this.mensajesError.length > 0) {
this.cargando = false;
return;
}

Recomendación: realizar commit con un mensaje de lo realizado.

Recursos extras:
● Pipes
● MdDataPicker
● MdAutocomplete

También podría gustarte