Blazor - Criando um Componente Calendário

Hoje veremos como criar um componente para Calendário no Blazor.

Se você esta chegando agora e não sabe o que é o Blazor leia o artigo ASP .NET Core - Iniciando com o Blazor - Macoratti; se você já conhece e quer saber mais pode fazer o curso de Blazor Essencial.  

Blazor : Componentes

o Blazor é um Framework baseado em componentes, e, isso significa que praticamente todos os elementos que compõe uma aplicação Blazor, são Componentes.

Um componente nada mais é do que uma “parte” de uma interface de usuário, e, pode ser toda uma página, um pequeno fragmento da página, uma janela de diálogo ou um formulário. Assim, qualquer elemento que no final for renderizado como uma interface de usuário é um componente da sua aplicação Blazor.

No Blazor  um componente é escrito em HTML e C# e criado em um arquivo com a extensão .razor.

O Blazor já vem com alguns componentes prontos para usar como o EditForm mas permite que você crie os seus próprios componentes.

E é isso que veremos neste artigo:  a criação de um componente bem simples para usar como calendário no Blazor.

Recursos usados:

Blazor : Criando um Componente Calendário

Abra o VS 2019 Community (versão mínima 16.5) e selecione a opção Create a New Project;

A seguir selecione a opção Blazor app e clique em next;

Informe o nome do projeto :  Blazor_Calendario, a localização e clique em Create;

Selecione a opção - Blazor Server App. Não vamos usar autenticação e vamos habilitar o https.

Clique no botão Create para criar o projeto.

Com o projeto criado vamos limpar o projeto excluindo os arquivos abaixo e suas referências:

Dentro da pasta Shared crie uma pasta Componentes e a seguir inclua um componente Razor chamado Calendario.razor.

Neste arquivo inclua o código definido abaixo:

<div class="row">
    <div class="col-md6">
        <table>
            <tr>
                <td>
                    <select class="form-control" @bind="Dia">
                        @for (int i=1;i <= 31;i++)
                        {
                            <option>@i</option>
                        }
                    </select>
                </td>
                <td>
                    <select class="form-control" @bind="Mes">
                        @for (int i = 1; i <= 12; i++)
                        {
                            <option value="@i">@Meses[i-1]</option>
                        }
                    </select>
                </td>
                <td>
                    <select class="form-control" @bind="Ano">
                        @for (int i = DateTime.Now.Year-100; i <= DateTime.Now.Year+50;i++ )
                        {
                            <option>@i</option>
                        }
                    </select>
                </td>
                <td>
                    <button type="button" class="btn btn-info">Selecione a data</button>
                </td>
            </tr>
        </table>
    </div>
</div>
@code {
    public int Dia { get; set; }
    public int Mes { get; set; }
    public int Ano { get; set; }
    public string[] Meses { get; set; } =
    {
        "Janeiro", "Fevereiro", "Março",
        "Abril", "Maio", "Junho", "Julho",
        "Agosto","Setembro","Outubro",
        "Novembro","Dezembro"
    };
    [Parameter]
    public DateTime DataInicial { get; set; }
   protected override void OnInitialized()
    {
        Dia = DataInicial.Day;
        Mes = DataInicial.Month;
        Ano = DataInicial.Year;
    }
}

Neste código criamos o componente definindo o seguinte:

1- No markup HTML

- Criamos uma tabela com 3 colunas : uma para exibir o dia, outra para o mês e a outra para o ano;
- Usamos um select/option para exibir os dias do mês, os meses do ano e um intervalo de anos;

2- No código C# criamos :

- As propriedades Dia, Mes e Ano;
- O array de string Meses contendo os nomes dos meses;
- Definimos o parâmetro DataInicial;
- No método OnInitialized do componente atribuímos os valores iniciais ao dia, mês e ano;

A seguir no componente Index.razor da pasta Pages altere o código conforme abaixo:

@page "/"
<h2>Usando o Componente Calendario</h2>
<Calendario DataInicial="Data"></Calendario>
@code{
    public DateTime Data { get; set; }

    protected override void OnInitialized()
    {
        Data = new DateTime(2020, 10, 11);
    }
}

Aqui usamos a tag <Calendario></Calendario> para usar o componente criado.

Executando o projeto iremos obter o resultado abaixo:

Vamos incrementar o componente permitindo selecionar a data.

Definindo a seleção da data

Um cenário comum com componentes aninhados é o desejo de executar o método de um componente pai quando ocorre um evento de componente filho.

Um evento onclick que ocorre no componente filho é um caso de uso comum. Para expor eventos em componentes, usamos um EventCallback. Um componente pai pode atribuir um método de retorno de chamada ao EventCallback de um componente filho.

Para poder obter a data selecionada vamos usar um EventCallBack que permite fazer a comunicação a partir de um componente filho com o componente pai.

Quando a data for selecionada no componente filho , que é o componente Calendario, o componente pai que é o componente Index, deverá ser notificado, e, para isso o componente filho Calendario deve expor um evento.

O componente pai atribui um método callback (retorno de chamada) ao evento do componente filho. No Blazor, para expor um evento, usamos EventCallback.

Assim no componente filho Calendario.razor vamos definir:

No arquivo Calendario.razor inclua o código destacado em azul abaixo:

<div class="row">
    <div class="col-md6">
        <table>
            <tr>
                <td>
                    <select class="form-control" @bind="Dia">
                        @for (int i=1;i <= 31;i++)
                        {
                            <option>@i</option>
                        }
                    </select>
                </td>
                <td>
                    <select class="form-control" @bind="Mes">
                        @for (int i = 1; i <= 12; i++)
                        {
                            <option value="@i">@Meses[i-1]</option>
                        }
                    </select>
                </td>
                <td>
                    <select class="form-control" @bind="Ano">
                        @for (int i = DateTime.Now.Year-100; i <= DateTime.Now.Year+50;i++ )
                        {
                            <option>@i</option>
                        }
                    </select>
                </td>
                <td>
                    <button type="button" class="btn btn-info" @onclick="OnSelectClick">Selecione a data</button>
                </td>
            </tr>
        </table>
    </div>
</div>
@code {
    public int Dia { get; set; }
    public int Mes { get; set; }
    public int Ano { get; set; }
    public string[] Meses { get; set; } =
    {
        "Janeiro", "Fevereiro", "Março",
        "Abril", "Maio", "Junho", "Julho",
        "Agosto","Setembro","Outubro",
        "Novembro","Dezembro"
    };
    [Parameter]
    public DateTime DataInicial { get; set; }
    [Parameter]
    public EventCallback<DateTime> DataSelecionada { get; set; }
   protected override void OnInitialized()
    {
        Dia = DataInicial.Day;
        Mes = DataInicial.Month;
        Ano = DataInicial.Year;
    }

   public Task OnSelectClick()
   {
      DateTime dt = new DateTime(Ano, Mes, Dia);
       return DataSelecionada.InvokeAsync(dt);
    }
}

Agora no componente Index.razor inclua o código conforme mostrado a seguir:

@page "/"
<h2>Usando o Componente Calendario</h2>
<Calendario DataInicial="Data" DataSelecionada="OnDateSelected"></Calendario>
@code{
    public DateTime Data { get; set; }
    public DateTime DataSelecionada { get; set; }

    protected override void OnInitialized()
    {
        Data = new DateTime(2020, 10, 11);
        DataSelecionada = Data;
    }
    public void OnDateSelected(DateTime dt)
    {
       DataSelecionada = dt;
    }
}

Executando o projeto agora teremos:

Pegue o código do projeto aqui: Blazor_Calendario.zip

"E a paz de Deus, que excede todo o entendimento, guardará os vossos corações e os vossos pensamentos em Cristo Jesus."
Filipenses 4:7

 


Referências:


José Carlos Macoratti