Aitor Sánchez - Blog - Oct. 26, 2023, 7:32 p.m.
¿Necesitas que tu usuario seleccione un valor de una lista y has pensado en ion-select? O, tal vez, ya sabes cómo se hace pero te falta algún detalle para sacarle todo el partido ¿verdad?
Mi nombre es Aitor Sánchez, soy desarrollador de apps desde 2014, y en este artículo te enseñaré a usar Ion Select en tus apps. Con sus entresijos y cosas interesantes sobre este componente.
Pero antes de continuar, esta es la Flutter Mafia. Es mi newsletter donde aprenderás desarrollo de apps móviles, aso y monetización junto con otros genietes que ya están dentro. Y si te suscribes te regalo mi ebook "Duplica los ingreso de tus apps en 5 minutos" No es broma, quizás te interese.
Pues bien, aquí no quiero explayarme mucho porque la mayoría sabréis lo que es. Si no, no estarías aquí.
Se trata de un desplegable sobre el que tu usuario podrá escoger entre varias opciones.
Veamos un ejemplo, lo entenderás mejor :)
Tranquilo, este componente no requiere de ninguna instalación. Simplemente lo puedes usar llamando a las etiquetas de turno que lo invocan.
Ahora lo verás en los ejemplos de uso. No te impacientes.
Tampoco, no es necesaria ninguna configuración para usarlo. Solo hay que usarlo y chinpún.
Genial, ahora sí. Hemos llegado al punto que estabas esperando.
Antes de nada, un ejemplo de código sencillito para que vayas entrando en el juego:
Primero el código TS:
import { Component } from '@angular/core';
@Component({
selector: 'my-page',
templateUrl: 'my-page.html'
})
export class MyPage {
superheroes: string[] = [
'Superman',
'Ironman',
'Spiderman',
'Aquaman',
'Flash',
'Thor',
'D. Strange',
'Hulk',
'Hawk Eye',
'Star Lord'
];
selectedHero: string;
constructor() {
this.selectedHero = '';
}
onHeroChange() {
console.log("Superhéroe seleccionado:", this.selectedHero);
}
}
Ahora el HTML:
<ion-item>
<ion-label>Superhéroe</ion-label>
<ion-select placeholder="Selecciona uno" [(ngModel)]="selectedHero" (ionChange)="onHeroChange()">
<ion-select-option *ngFor="let heroe of superheroes" [value]="heroe">{{ heroe }}</ion-select-option>
</ion-select>
</ion-item>
Todos los componentes visuales que tengan un input del usuario tienes que envolverlos en un ion-item. Si no lo haces, Ionic no capturará los eventos de entrada correctamente.
Lo más importante de este ejemplo es la etiqueta ion-select.
En primer lugar, le asignarás un ngModel que será la variable que se sincronizará con el “value” de la ion-option que esté seleccionada en ese momento.
En segundo lugar, tienes que rellenar tu select con sus respectivas options como lo haría un programador web.
Para ello basta con meter todas las “ion-option” que quieras dentro del “ion-select”.
Pero recuerda, el valor que le asignes a estas “ion-option” será el que se guarde en la variable que has bindeado en el ngModel del “ion-select”.
Para asignar un valor por defecto, basta con que inicialices la variable que está bindeada a tu “ion-select” con el valor que quieras que tenga al iniciarse (siempre y cuando esté dentro del array, o en su defecto valores, que esté en las “ion-option”s de tu select y sea igual que su etiqueta “value”).
Ejemplo:
<ion-item>
<ion-label>Gender</ion-label>
<ion-select [(ngModel)]="gender">
<ion-option value="f">Female</ion-option>
<ion-option value="m">Male</ion-option>
</ion-select>
</ion-item>
En el caso de que gender fuese "f" el select tomaría como seleccionado a "Female". En caso contrario y que gender fuese"m", male seria el seleccionado.
Esto es más de lo mismo que has visto antes, pero agregándole un detalle. Tienes que asignar la propiedad “multiple=’true’” en el html de la siguiente manera:
<ion-item>
<ion-label>Toppings</ion-label>
<ion-select [(ngModel)]="toppings" multiple="true">
<ion-option>Bacon</ion-option>
<ion-option>Black Olives</ion-option>
<ion-option>Extra Cheese</ion-option>
<ion-option>Mushrooms</ion-option>
<ion-option>Pepperoni</ion-option>
<ion-option>Sausage</ion-option>
</ion-select>
</ion-item>
Aitor, ¿entonces el valor de la variable bindeada ahora que contiene?
Contendrá un array de strings con los datos de los objetos seleccionados ordenados del primero al último en el orden de aparición dentro del selector.
Como imaginarás, tienes el botón de confirmación y el de cancelación.
Estos eventos los controlarás desde código más adelante, pero de momento quiero que sepas que puedes cambiar el texto que tienen con las propiedades “okText” y “cancelText” de la siguiente manera:
<ion-select okText="Okay" cancelText="Dismiss">
...
</ion-select>
Vale, para esto tienes varias maneras de hacerlo.
<ion-item>
<ion-label>Employee</ion-label>
<ion-select [(ngModel)]="employee" [compareWith]="compareFn">
<ion-option *ngFor="let employee of employees" [value]="employee"></ion-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label>Employee</ion-label>
<ion-select [(ngModel)]="employee" [compareWith]="compareFn" ionOptions="nuestras-options">
</ion-select>
</ion-item>
Ambas opciones son igual de buenas. Pero me quedaría con la segunda, de hecho, es la que recomienda el api.
El código es más limpio y no tendrás que escribir más sobre el html, que ya sabes lo molesto que es.
Al tratarse de un componente simple, tienes dos funciones principales para él.
Veamos el código TS para utilizarlos:
import { Component, ViewChild } from '@angular/core';
import { IonSelect } from '@ionic/angular';
@Component({
selector: 'my-page',
templateUrl: 'my-page.html'
})
export class MyPage {
@ViewChild('mySelect') selectRef: IonSelect;
constructor() {}
openSelect() {
this.selectRef.open();
}
closeSelect() {
this.selectRef.close();
}
}
Por otro lado, tienes 3 campos que te tengo que mencionar:
Ahora, un ejemplo que utilice todo esto:
Primero el HTML donde vas a utilizar todo:
<ion-item>
<ion-label>Superhéroes</ion-label>
<ion-select [compareWith]="compareFn" interface="popover" multiple="true" cancelText="Cancelar"
okText="Confirmar" placeholder="Selecciona superhéroes" [selectOptions]="selectOpts" selectedText="Tus Héroes">
</ion-select>
</ion-item>
Ahora el TS que tiene la lógica:
import { Component } from '@angular/core';
@Component({
selector: 'my-page',
templateUrl: 'my-page.html'
})
export class MyPage {
superheroes: any[] = [
{ id: 1, name: 'Superhéroe 1' },
{ id: 2, name: 'Superhéroe 2' },
// ... más superhéroes ...
];
selectOpts: any = {
header: 'Elige tus superhéroes',
subHeader: 'Selecciona uno o varios superhéroes'
};
constructor() {}
compareFn(o1: any, o2: any): boolean {
return o1 && o2 ? o1.id === o2.id : o1 === o2;
}
}
Y ahora, un ejemplo terminado basado en el array de héroes que te he mostrado al principio:
<ion-item>
<ion-label>Superhéroes</ion-label>
<ion-select [compareWith]="compareFn" interface="popover" multiple="true" cancelText="Cancelar"
okText="Confirmar" placeholder="Selecciona superhéroes" [selectOptions]="selectOpts" selectedText="Tus Héroes">
<ion-select-option *ngFor="let heroe of superheroes" [value]="heroe">{{ heroe.name }}</ion-select-option>
</ion-select>
</ion-item>
Llegados a este punto, ya tienes que saber perfectamente cómo usar y configurar un ion-select. Ahora vas a ver un detalle más, los eventos que emite este componente.
En este caso tienes 4 y son los siguientes:
Primero el código TS del ejemplo:
import { Component } from '@angular/core';
@Component({
selector: 'my-page',
templateUrl: 'my-page.html'
})
export class MyPage {
superheroes: any[] = [
{ id: 1, name: 'Superhéroe 1' },
{ id: 2, name: 'Superhéroe 2' },
// ... más superhéroes ...
];
selectOpts: any = {
header: 'Elige tus superhéroes',
subHeader: 'Selecciona uno o varios superhéroes'
};
constructor() {}
compareFn(o1: any, o2: any): boolean {
return o1 && o2 ? o1.id === o2.id : o1 === o2;
}
onCancel() {
console.log('Selección cancelada');
}
onBlur() {
console.log('Select perdió el foco');
}
onChange(event: any) {
console.log('Valor cambiado:', event.detail.value);
}
onFocus() {
console.log('Select tiene el foco');
}
}
Y ahora le HTML al que hace referencia:
<ion-item>
<ion-label>Superhéroes</ion-label>
<ion-select [compareWith]="compareFn" interface="popover" multiple="true" cancelText="Cancelar"
okText="Confirmar" placeholder="Selecciona superhéroes" [selectOptions]="selectOpts" selectedText="Tus Héroes"
(ionCancel)="onCancel()"
(ionBlur)="onBlur()"
(ionChange)="onChange($event)"
(ionFocus)="onFocus()">
<ion-select-option *ngFor="let heroe of superheroes" [value]="heroe">{{ heroe.name }}</ion-select-option>
</ion-select>
</ion-item>
Si te preguntas cómo se controla el cambio de valor de un select, en el punto anterior has visto los posibles eventos que se disparan de este componente y cuando se emiten.
Pero para poner las cosas un poco más fáciles, ahora verás un ejemplo en código que siempre es mucho mejor.
Aquí va:
<ion-select #C (ionChange)="onChange(C.value)">
<!-- Aquí van nuestros ion-option -->
</ion-select>
Si te fijas en la parte donde se construye el select, "#C" hace referencia al mismo objeto para poder acceder a sus propiedades.
Así podrás acceder a estas desde la misma etiqueta ¿entiendes? Por eso, y sin necesidad de gastar recursos con un ngModel, llamas al método "onChange" pasándole el valor que nos llega desde el objeto "#C" cada vez que el valor del select cambia.
¿A qué es la leche?
Con las últimas versiones del Framework (creo que desde la versión de Ionic 5) se ha ido agregando nuevas funcionalidades a este.
Incluso los selectores, que es lo que estamos viendo en este tutorial, también han sufrido dicha actualización. Ahora tienes disponible una nueva etiqueta para las opciones de tu select que se llama ion-select-option.
El código de implementación de esta nueva etiqueta sería el siguiente:
<ion-item>
<ion-label>Select</ion-label>
<ion-select>
<ion-select-option value="brown">Brown</ion-select-option>
<ion-select-option value="blonde">Blonde</ion-select-option>
<ion-select-option value="black">Black</ion-select-option>
<ion-select-option value="red">Red</ion-select-option>
</ion-select>
</ion-item>
Cómo puedes ver, cambia los "ion-option" que has visto en el tutorial por "ion-select-option". Aparentemente no hay nada diferente a nivel de diseño e implementación, pero, por si acaso, aquí te dejo las propiedades de este nuevo componente:
Mira, en el momento que tu mejoras el logo de una app que tengas publicada en Google Play, las descargas y los ingresos que esta aplicación genera aumentan. Esto es así. Mejor logo es igual a más dinero.
Basándonos en esto, hemos creado esta herramienta que te permite evaluar, optimizar y mejorar los logos de tus apps para que reciban más descargas. No te quiero espoilear, dentro hay un video explicativo. Entra en el enlace.
Ahora si geniete, me despido ya. Espero haberte ayudado y nos vemos en el siguiente artículo. Hasta ese entonces ¡que te vaya bien!