Solucionado (ver solução)
Solucionado
(ver solução)
7
respostas

Validação de formulário sem Helper

Olá a todos.

Estou com uma dificuldade: mostrar a mensagem de erro (erro ocorrido durante a validação do formulário) na view. Bem, não estou usando os helpers.

No meu validador tem o seguinte campo

[...]
public boolean temErros(EntityManager em, DynamicForm formulario){
    if ((instituicao.getInstituicaobyName(em, formulario.get("instituicao")) == null)){
                formulario.reject(new ValidationError("disciplina", "O campo de disciplina não pode ser vazio"));
    }
    return formulario.hasErrors();
}
[...]

No meu Controller

[...]
if(validador.temErros(jpa.em(), formulario)){
    flash("danger", "Há erros no formulário.");
    badRequest(docenciaForm.render(formulario)); 
}

Na minha view...

@(form: DynamicForm)
[...]
@main("ok"){
    <form id="form" method="post" action="/docencia/cadastro" class="form-horizontal" >
<div class="form-group relative">
            <label for="instituicao" class="control-label col-xs-2">Nome da Instituicao</label>
            <div class="col-xs-10">
                <input type="text" class="form-control autocomplete" id="instituicao" name="instituicao" placeholder="Informe o nome da instituicao">                
            </div>
            <a href="/tabelas/cadastro/instituicao" id="btnAddInstituicao" class="btn btn-inverse absolute" title="Adicionar uma instituicao ao Banco de Dados">
                <span class="glyphicon glyphicon-plus"></span>
            </a>
            <!-- AQUI -->
            @form.error("instituicao").map { error =>
                    error.message
            }
    </div>
}

É aqui na view que não sei que código Scala por para que o erro ocorrido e registrado em

//formulario.reject(new ValidationError("disciplina", "O campo de disciplina não pode ser vazio"));

seja apresentado abaixo de do input de Instituicao.

7 respostas

Olá Naun!

Os erros registrados com o .reject podem ser encontrados através dos campos do formulário. Você quase chegou na solução! Olhe só:

@{form("instituicao").error.map { error => error.message }}

Ao acessar form("instituicao") você adquire o campo instituicao do formulário e seus dados, incluindo os erros que pode acessar com .error. Aí, o mapeamento está certinho!

Teste e, se ainda der algo errado, me procure de novo aqui mesmo!

Bons estudos!

Olá, boa tarde. Primeiramente quero dizer que gostei muito do curso. Parabéns.

Sobre o problema: Testei conforme informado, mas nada foi apresentado.

Eu coloquei um sysout no validador para saber se estava sendo tratado corretamente e este está sendo impresso sem problemas no console.

Validador

if(strInstituicao.isEmpty()){
            formulario.reject(new ValidationError("instituicao", "O campo de instituicao não pode ser vazio")); 
            System.out.println("O campo de instituicao não pode ser vazio");
        }

Controller

[...]
        //Validando o formulário
        if(validadorDocencia.temErros(jpa.em(), formulario)){
            flash("danger", "Há erros no formulário. Dados não adicionados");            
            return badRequest(docenciaForm.render(formulario, atvDocente.getAtividadeDocentePorMagistrado(jpa.em()))); 
        }

View

@(form: DynamicForm)
<form id="form" method="post" action="/docencia/cadastro" class="form-horizontal" >
    <div class="form-group relative">
            <label for="instituicao" class="control-label col-xs-2">Nome da Instituicao</label>
            <div class="col-xs-10">
                <input type="text" class="form-control autocomplete" id="instituicao" name="instituicao" placeholder="Informe o nome da instituicao">                
            </div>
            <a href="/tabelas/cadastro/instituicao" id="btnAddInstituicao" class="btn btn-inverse absolute" title="Adicionar uma instituicao ao Banco de Dados">
                <span class="glyphicon glyphicon-plus"></span>
            </a>
            @{form("instituicao").error.map { error => error.message }}
        </div>
[...]
solução!

Naun, não consegui descobrir um jeito de fazer a validação por campos, em um formulário dinâmico, de modo aceitável. Descobri uma solução, mas é meio feia:

@for(error <- formulario.errors) {
    @if(error._1.equals("instituicao") && error._2.size() > 0) {
        @for(e <- error._2) {
            <p>@e.message</p>
        }
    }
}

Cada elemento do formulario.errors é uma tupla de String, ArrayList<ValidationError>. Sabendo disso, acessamos o primeiro valor da tupla com error._1 e comparamos com o nome do campo, instituicao.

Se existe uma tupla com esse valor, pegamos o segundo valor da tupla com error._2 que é uma lista dos erros deste campo.

Para cada um dos elementos, pegamos então a mensagem de erro, que será relacionada ao nome da tupla, e exibimos para o usuário.

Sei que a solução não é ideal nem otimizada, mas por hora funciona. Eu sugeriria, mesmo que você não utilize os helpers, que utilize (quando for fazer validações mais complexas) ao menos o formulário de modelo, para evitar esse tipo de problema.

Ps.: obrigado! Significa muito saber que consegui passar o conhecimento adiante.

E agradeço a você também, pois alunos como você que tentam fazer coisas diferentes são muito valiosos! Eu sabia que não havia erro de compilação, mas nunca tinha feito o teste da mensagem de erro com um formulário dinâmico (sempre prefiro ter uma modelagem para o formulário, por costume trazido de outras ferramentas).

Ao estudar para responder sua pergunta, aprendi um pouco mais sobre o assunto também!

É, realmente não é uma solução bonita hehe

Vou fazer algo mais simples então. Como usar * para marcar os campos obrigatórios, por exemplo, e etc. kk

Agradeço a atenção desprendida

O mais exequível que achei foi usar o Flash para isso. Ao invés de por success e danger, ponho o nome do campo e verifico a sua existência.

Exemplo:

No Validador

[...]
Instituicao instituicao = formulario.get();
if(instituicao.getNomeInstituicao().isEmpty()){
    formulario.reject(new ValidationError("instituicao", "O campo de instituição não pode ser vazio")); 
}

Na View

@if(flash.containsKey("instituicao")) {
    <div class="alert alert-danger">
        @flash.get("instituicao")
    </div>
}

Hahaha se funciona e não dá um trabalho absurdo.. é uma boa alternativa por hora! E ficamos esperando as melhorias no fonte do Play! =)