ASP .NET Core - Usando Caixas de Seleção em Cascata com Razor Pages


Neste artigo veremos como usar a tag helper select para exibir informações em cascata em mais de uma lista suspensa.

Hoje nosso objetivo será exibir listas suspensas em cascata, e isso quer dizer que as listas serão dependentes uma da outra, ou seja, ao selecionar um valor em uma lista vai determinar a seleção na outra caixa de seleção.

Na Asp .NET Core MVC a classe SelectList fornece essa funcionalidade. Ela herda de MultiSelectList implementando a interface IEnumerable<SelectListItem> e IEnumerable.

A forma mais simples de fazer isso é usar a Tag Helper Select como eu já mostrei em outro artigo.

Neste artigo eu vou usar duas listas suspensas que serão preenchidas com informações obtidas de um banco de dados relacional usando o EF Core.

A parte chata de usar essa abordagem é ter que fazer toda a configuração para usar o EF Core no projeto mas alguém tem que mostrar como fazer isso, não é mesmo !!!!

'Bora' pra prática...

Recursos Usados:

Criando o projeto ASP .NET Core MVC

Abra o VS 2017 Community e clique em New Project;

Selecione o template ASP .NET Core Web Application e informe o nome Listas_Cascata e clique em OK;

Escolha o template Web Application (Model-View-Controller) para criar uma aplicação ASP .NET Core MVC. Estou usando a versão 2.2 da ASP .NET Core.

Definindo o modelo de domínio e o contexto

Nesta etapa vamos definir  a classe de contexto AppDbContext para realizar o mapeamento com o banco de dados usando o EF Core e a configuração no arquivo appsettings.json:

O arquivo de contexto AppDbContext:

using Microsoft.EntityFrameworkCore;
namespace Lista_Cascata.Models
{
    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options ) : base(options)
        {}
     }
}

O arquivo appsettings.json :

{
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=.\\MACORATTI;Initial Catalog=Cadastro;Integrated Security=True"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*"
}

Definindo a View

Agora altere o código da View Index.cshtml conforme abaixo:

@model Estado
<h1>Usando a tag Helper Select</h1>
<hr />
<h2>Apenas definindo select asp-for</h2>
<select asp-for="EstadoSigla"></select>
<br />
<h2>Estados definidos usando 'option value'</h2>
<select asp-for="EstadoSigla">
    <option value="MG">Minas Gerais</option>
    <option value="RS">Rio Grande do Sul</option>
    <option value="PR">Paraná</option>
    <option value="SP">São Paulo</option>
    <option value="RJ">Rio de Janeiro</option>
    <option value="--">Outros Estados</option>
</select>

 

No primeiro código estamos definindo o model Estado e usando a tag helper asp-for para indicar que propriedade EstadoSigla esta vinculada com o elemento select de forma gerar a lista suspensa.

Esta abordagem apenas gera uma lista suspensa vazia.

No segundo código estamos definindo as opções usando option value de forma manual o que pode até ser feito se você tiver poucas opções.

Agora podemos ver a lista suspensa com as opções exibidas.

Nesse caso, as opções definidas na marcação serão incluídas no HTML gerado. A opção selecionada será determinada automaticamente com base no valor da propriedade do modelo.

Por exemplo, se a propriedade EstadoSigla estiver definida como 'SP' no modelo, o seguinte HTML será gerado:

<select id="EstadoSigla" name="EstadoSigla">
    <option value="MG">Minas Gerais</option>
    <option value="RS">Rio Grande do Sul</option>
    <option value="PR">Paraná</option>
    <option selected="selected" value="SP">São Paulo</option>
    <option value="RJ">Rio de Janeiro</option>
    <option value="--">Outros Estados</option>
</select>

Carregando uma lista de opções de uma fonte de dados

Podemos carregar uma lista de opções de forma dinâmica de uma fonte de dados como um banco de dados, arquivo XML, arquivo JSON, etc.

Para fazer isso podemos usar o atributo asp-items definindo-o para um IEnumerable.

Para não complicar muito eu vou criar um serviço parar fornecer uma lista de estados com siglas e nomes.

Altere o código da classe Estado incluindo a propriedade EstadoNome :

    public class Estado
    {
        public string EstadoNome { get; set; }
        public string EstadoSigla { get; set; }
    }

Agora crie uma pasta Services no projeto e a seguir inclua uma classe chamada EstadosService com o seguinte código:

using AspnCore_Select.Models;
using System.Collections.Generic;
namespace AspnCore_Select.Services
{
    public class EstadosService
    {
        public static List<Estado> GetEstados()
        {
            var listaEstados = new List<Estado>()
            {
                new Estado(){ EstadoSigla="AL", EstadoNome="Alagoas"},
                new Estado(){ EstadoSigla="BA", EstadoNome="Bahia"},
                new Estado(){ EstadoSigla="CE", EstadoNome="Ceará"},
                new Estado(){ EstadoSigla="DF", EstadoNome="Distrito Federal"},
                new Estado(){ EstadoSigla="ES", EstadoNome="Espirito Santo"},
                new Estado(){ EstadoSigla="GO", EstadoNome="Goiás"},
                new Estado(){ EstadoSigla="MG", EstadoNome="Minas Gerais"},
                new Estado(){ EstadoSigla="PR", EstadoNome="Paraná"},
                new Estado(){ EstadoSigla="RS", EstadoNome="Rio Grande do Sul"},
                new Estado(){ EstadoSigla="SP", EstadoNome="São Paulo"},
                new Estado(){ EstadoSigla="TO", EstadoNome="Tocantins"}
            };
            return listaEstados;
        }
    }
}

Agora no controlador HomeController vamos definir uma lista de estados em uma ViewBag (ou ViewData) para exibir na view Index.

Inclua o código abaixo no controlador HomeController:

using AspnCore_Select.Models;
using AspnCore_Select.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Diagnostics;
using System.Linq;
namespace AspnCore_Select.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            ViewBag.Estados = EstadosService.GetEstados().Select(c => new SelectListItem()
                                                   { Text= c.EstadoNome, Value=c.EstadoSigla}).ToList();
            return View();
        }
        ...
}

Outra sintaxe que podemos usar seria:

 ViewBag.Estados = new SelectList(EstadosService.GetEstados(), "EstadoNome", "EstadoSigla");

Agora altere o código da view Index.cshtml conforme a seguir:

@model Estado
<h1>Usando a tag Helper Select</h1>
<hr />
<br />
<h3>Apenas definindo select asp-for</h3>
<select asp-for="EstadoSigla"></select>
<br />
<h3>Estados definidos usando 'option value'</h3>
<select asp-for="EstadoSigla">
    <option value="MG">Minas Gerais</option>
    <option value="RS">Rio Grande do Sul</option>
    <option value="PR">Paraná</option>
    <option value="SP">São Paulo</option>
    <option value="RJ">Rio de Janeiro</option>
    <option value="--">Outros Estados</option>
</select>
<br />
<h3>Obtendo a lista de uma fonte de dados usando asp-items</h3>
<select asp-for="EstadoSigla"
        asp-items="@ViewBag.Estados"></select>

 

Executando o projeto teremos o seguinte resultado:

Pegue o projeto completo aqui: AspnCore_Select.zip

(disse Jesus) "Eu sou o pão vivo que desceu do céu; se alguém comer deste pão, viverá para sempre; e o pão que eu der é a minha carne, que eu darei pela vida do mundo. "
João 6:51

Referências:


José Carlos Macoratti