Blazor Server - CRUD com EFCore com Modal Dialog - IV
Neste artigo vamos criar uma aplicação Blazor Server e realizar um CRUD usando o EF Core e os recursos do jQuery e Bootstrap. |
Continuando a terceira parte do artigo vamos agora incluir a validação, salvar os dados e usar o JavaScript Interop para gerenciar as janelas modais.
Incluindo a validação
Para validar a entrada dos dados no formulário modal primeiro teremos que usar o recurso Data Annotations no modelo de domínio. Isso já foi feito na definição do modelo como vemos a seguir:
using System;
using System.ComponentModel.DataAnnotations;
namespace Blazor_Tarefas.Data
{
public class Tarefa
{
[Key]
public int Id { get; set; }
[Required(ErrorMessage = "Informe o nome da tarefa")]
[StringLength(30, ErrorMessage = "Nome é muito longo.")]
public string Nome { get; set; }
[Required(ErrorMessage = "O status é obrigatório")]
[MaxLenght(30)]
public string Status { get; set; }
[Required(ErrorMessage = "A data de conclusão tem que ser informada")]
public DateTime DataConclusao { get; set; }
}
}
|
Também precisamos adicionar o componente DataAnnotationsValidator que anexa suporte de validação usando anotações de dados.
Para exibir as mensagens de validação, vamos usar o componente ValidationSummary. Ambos os componentes são adicionados no componente TarefaDetalhe.razor dentro do componente EditForm.
...
<EditForm Model="@TarefaObject" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<div class="form-group">
<label for="nome">Tarefa</label>
<input type="hidden" @bind-value="@TarefaObject.Id" />
<InputText id="name" class="form-control" @bind-Value="@TarefaObject.Nome" />
</div>
<div class="form-group">
<label for="status">Status</label>
<InputSelect id="Summary" class="form-control" @bind-Value="TarefaObject.Status">
<option value="">Selecione</option>
@foreach (var status in TarefaStatusLista)
{
<option value="@status">@status</option>
}
</InputSelect>
</div>
<div class="form-group">
<label for="dataConclusao">Conclusão em</label>
<input type="date" id="addition" name="math" @bind-value="@TarefaObject.DataConclusao" />
</div>
<button type="submit" class="btn btn-primary">Enviar</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancelar</button>
</EditForm>
...
|
Após essas implementações ao rodar a aplicação e tentar submeter o formulário com dados inválidos veremos as mensagens de erro conforme a figura a seguir:
Podemos ver os erros de validação na seção ValidationSummary. Se você quiser mostrar a mensagem de validação ao lado de cada controle em vez de um resumo, remova o componente ValidationSummary e inclua o seguinte padrão de código próximo a cada elemento input :
<ValidationMessage For="@(() => TarefaObject.Nome)" />
O resultado obtido é o mostrado na figura abaixo:
Salvando os dados e usando o JS
Interop
Após realizar a validação dos dados podemos implementar a funcionalidade para
salvar os dados no banco de dados.
Isso é feito no método HandleValidSubmit que é acionado quando o formulário é enviado com êxito após passar na validação. Assim temos que adicionar a lógica “salvar” neste método.
...
private async void HandleValidSubmit() |
Com isso os dados já serão salvos no banco de dados mas você vai notar que a janela de diálogo modal continua aberta.
Precisamos chamar um código JavaScript a partir do código .NET para fechar a caixa de diálogo. Para chamar a função JavaScript a partir do C#, usamos o recurso IJSRuntime. E vamos ter que injetar esse serviço no componente:
@inject IJSRuntime jsRuntime
Assim vamos criar o método CloseTarefaModal que será invocado no método HandleValidSubmit() logo após os dados serem salvos:
...
private async void HandleValidSubmit() |
A seguir vamos definir o método CloseTarefaModal:
@inject ITarefasService service
@inject IJSRuntime jsRuntime
... @code { [Parameter] public Tarefa TarefaObject { get; set; } List<string> TarefaStatusLista = new List<string>() { "Nova", "Em Progresso", "Concluída" };
private async Task CloseTarefaModal()
{
await jsRuntime.InvokeAsync<object>("CloseModal", "tarefaModal");
}
private async void HandleValidSubmit()
{
await service.Add(TarefaObject);
await CloseTarefaModal();
}
}
|
O método InvokeAsync<T> usa um identificador para a função JavaScript que você deseja invocar junto com qualquer número de argumentos serializáveis JSON.
Aqui chamamos a
função JavaScript 'CloseModal' para a janela ''tarefaModal'.
A seguir vamos definir o método JavaScript para fechar a janela e para abrir a
janela no arquivo _Host.cshtml.
...
<script src="_framework/blazor.server.js"></script>
<script>
function ShowModal(modalId) {
$('#' + modalId).modal('show');
}
function CloseModal(modalId) {
$('#' + modalId).modal('hide');
}
</script>
</body>
</html>
|
Neste código a função ShowModal() vai abrir a janela e CloseModal() vai fechar a janela modal.
A comunicação entre os componentes
Agora os dados estão sendo salvos e a janela modal está sendo fechada, mas não consiguimos ver o item recém-adicionado na lista de tarefas.
Para ver os dados temos que atualizar o navegador.
Isso ocorre porque temos que informar ao componente pai para se atualizar para exibir o novo conjunto de dados que foram incluídos a partir do componente filho.
Os componentes podem oferecer retornos de chamada (CallBacks) que os componentes pais podem usar para reagir a eventos gerados por seus componentes filhos.
Vamos implementar isso.
No componente filho TarefaDetalhe vamos declarar um parâmetro Action e definir a Action com o nome DadosAlterados e a invocar no método HandleValidSubmit():
[Parameter] public Action DadosAlterados { get; set; }
private async void HandleValidSubmit() |
A seguir podemos fazer com que o componente Pai - ListaTarefa.razor - trata o evento DadosAlterados da seguinte forma:
<TarefaDetalhe TarefaObject=tarefaObject DadosAlterados="@DadosAlterados"></TarefaDetalhe> @page "/listatarefas"
...
private async void DadosAlterados() { listaTarefas = await service.Get(); StateHasChanged(); } } |
Note que declaramos no componente Pai a Action @DadosAlterados definida no componente Filho.
O método StateHasChanged notifica o componente de que seu estado foi alterado. Quando aplicável, chamar StateHasChanged faz com que o componente seja renderizado novamente. Este método é chamado automaticamente para métodos EventCallBack.
Agora podemos adicionar um novo registro após a validação, fechar a caixa de diálogo e ao salvar vamos atualizar o componente pai.
Neste momento ao executar o projeto teremos o seguinte resultado :
Na próxima parte do artigo vamos continuar implementando as demais funcionalidades do CRUD.
"Quanto lhe for
possível, não deixe de fazer o bem a quem dele precisa"
Provérbios 3:27
Referências:
ASP .NET Core - Implementando a segurança com
ASP.NET Core MVC - Criando um Dashboard .
C# - Gerando QRCode - Macoratti
ASP .NET - Gerando QRCode com a API do Google
ASP .NET Core 2.1 - Como customizar o Identity
Usando o ASP .NET Core Identity - Macoratti
ASP .NET Core - Apresentando o IdentityServer4
ASP .NET Core 3.1 - Usando Identity de cabo a rabo