Vraptor 3 + validator + erro ao remontar select/combobox

Olá pessoal,

após muita pesquisa e nenhuma resposta resolvi criar este tópico…

1a dúvida:

Seguindo a documentação do vraptor3 fiz um crud com a validação de campos do vraptor (validação no modo ‘estilo clássico’).

Quando dá erro é re-exibida a tela do formulário com os dados informados + uma mensagem de alerta ao usuário, relativa ao erro.

Para campos input text não há problemas, os campos vêm com os valores informados.

Mas nos comboboxes/selects não aparecem as opções (obs.: as opções dos selects são montadas com dados do banco de dados)

Usei a opção “exibir código fonte” e na parte dos selects as opções não aparecem no html.

O que devo fazer ??

O esperado era vir as opções disponíveis e a opção selecionada.

2a dúvida:

Na tela deste formulário há partes dínâmicas, montadas via javascript e uso show/hide nos divs para mostrar/esconder eles.

Após a validação quando há erro os divs que haviam recebido ‘show’ vem ‘hide’, quando dou show manualmente (clico num botão) aparem normalmente os divs e seus os campos estão com os valores informados.

Como manter o estado de exibição das divs após haver um erro de validação no vraptor3 ??

abçs

Pode postar o código JSP e do Controller?

[]´s

Daniel

[quote=asdias]Olá pessoal,

após muita pesquisa e nenhuma resposta resolvi criar este tópico…

1a dúvida:

Seguindo a documentação do vraptor3 fiz um crud com a validação de campos do vraptor (validação no modo ‘estilo clássico’).

Quando dá erro é re-exibida a tela do formulário com os dados informados + uma mensagem de alerta ao usuário, relativa ao erro.

Para campos input text não há problemas, os campos vêm com os valores informados.

Mas nos comboboxes/selects não aparecem as opções (obs.: as opções dos selects são montadas com dados do banco de dados)

Usei a opção “exibir código fonte” e na parte dos selects as opções não aparecem no html.

O que devo fazer ??

O esperado era vir as opções disponíveis e a opção selecionada.
[/quote]

vc tá usando validator.onErrorUse(page()).of(…) ? se sim, troque pra validator.onErrorUse(logic()).forward();

o page.of não executa a lógica, só vai direto pra view, já o forward executa a lógica, logo os comboboxes vão vir populados

se quiser fazer isso do jeito fácil, faça validação do lado do cliente (usando plugins javascript, por exemplo o JQuery Validator)… senão vc vai precisar mandar pro vraptor os estados dos divs… não tem um jeito mais fácil que isso, pq vc vai para outra requisição… fazer validações com javascript talvez seja a melhor opção

Oi Lucas,

sobre a dúvida 1:

este é o trecho do código-fonte que trata das validações, que não haviamos posto na mensagem anterior:

		[code]this.validator.onErrorUse(Results.page()).of(ClienteController.class).form("adicionar", cliente.getIdGFornec, 0L);[/code]

o que acontecia neste: quando dava erro a tela com o form de cadastro era re-exibida, os campos input text e checkbox continham os dados informados, porém os selects vinham sem opções.

seguindo tua orientação troquei para:

		[code]this.validator.onErrorUse(Results.logic()).forwardTo(ClienteController.class).form("adicionar", cliente.getIdFornec, 0L);[/code]

o que acontece agora: quando dá erro a tela com o form de cadastro é re-exibida, os campos input text e checkbox vêm em branco (perde-se tudo que o usuário informou) e os selects vem com opções (porém sem as opções selecionadas pelo usuário).

Obs.: este form é usado para cadastro/alteração e estou usando no modo cadastro. neste modo não tem como recuperar os dados do banco de dados para exibir na tela quando ocorre erro.

… li de novo a documentação do Vraptor3 e tentei esta combinação

                    [code]this.validator.onErrorUse(Results.logic()).redirectTo(TarifaController.class).form("adicionar", cliente.getIdGFornec, 0L);[/code]

mas tambem veio todo o form em branco, com os selects com opções.

tambem tentei usando estes, o 1o veio em branco o form e o segundo deu erro.

this.validator.onErrorUse(Results.page()).redirect("/cliente/form/adicionar/12/0"); this.validator.onErrorUse(Results.page()).forward("WEB-INF/jsp/cliente/form.jsp");

Onde estou errando ??

abçs

informação adicional: acabo de baixar um aplicativo exemplo do site do Vrapto3 (vraptor-mydvds).

Na tela de cadastro de dvds quando não preencho um campo, por exemplo ‘Título do DVD’, é exibida a tela de form com a mensagem de erro definida na validação. Os campos imput text vêm corretamente preenchidos, mas o select ‘Tipo’ vem sem as opções. (igual ocorre na minha aplicação)

Acho que deve ser algum problema no Vraptor3, e não na minha programação.

Na programação deste exemplo é usada esta forma de redirecionamento:

Abçs

os seus inputs estão assim?:

<input type="text" name="xyz" value="${xyz}"/>

se sim, algum dos parâmetros do método form tem o mesmo nome do objeto dos seus inputs?

Por exemplo:

public void form(Cliente cliente, ...) {}
<input type="text" name="cliente.nome"/>
...

Oi Lucas

resposta 1a questão:

meus inputs estão assim: <<nome_objeto_recebido_controller>>.<<nome_atributo>>

exemplo:

[code]Comissão: <input type="text" name="cliente.comissao" value="${cliente.comissao}">[/code]

Além disso tenho 4 selects: num deles pode se escolher ‘n’ opções.
Neste tive que passar uma variável auxiliar na assinatura do método, pois o vRaptor3 não aceita selects com mais de uma opção escolhida (segui suas orientações no passado).

Só relembrando: com os input text e checkbox não dava problemas (seguindo a 1a lógica que fiz, que depois você falou para mudar) O problema eram com os selects.
Nos inputs radio não testei.

Também tenho objetos dentro de objetos: para estes os inputs são assim por exemplo:

resposta 2a questão: sim

O problema está acontecendo também no exemplo my-dvds da página de Vraptor3. Você pode ver o código dele para simular aí o problema.

Abçs

então… isso não é um problema… é o comportamento esperado:

page()).of(Controller.class).metodo() é pra fazer um forward para a página de uma lógica, sem executar a lógica… ou seja, não vai preencher o select pq o método form não foi invocado

logic()).forward(Controller.class).metodo() é pra fazer um forward para a lógica, ou seja, ela será executada…

vc pode postar um pedaço do seu código pra eu ter uma idéia melhor sobre o que está acontecendo?

o que eu preciso: da lógica form, e todas as linhas que tenham result.include dentro dela

@asdias

quanto aos dados do select, eles vem de outra entidade?

Não seria o caso de vc adicioná-los novamente na view?

Tipo:

if (validator.hasErrors()) {
	result.include("departmentList", departmentDao.findAll());
}
validator.onErrorUse(Results.page()).of(UserController.class).form();

Nesse caso, um formulário de usuários com um select para informar o departamento…

Oi Lucas,

vi a mensagem do lscosta: talvez o que ele falou funcione, mas na aplicação exemplo dada na página do Vraptor3 (vraptor-mydvds) não se usa isso: colocar incluides dentro do parte do validator.

em http://www.blumar.com.br/downloads/geral/erro.zip segue o código-fonte da controller, o jsp e figuras das telas da aplicação exemplo vraptor-mydvds (contendo a simulação do erro).

Meu código-fonte é grande e complexo, por isso, recomendo que você veja o código do vraptor-mydvds, que apresenta o mesmo erro e é mais simples.

figuras no anexo:
fig1 form de cadastro de dvd, repare que tem opções no select
fig 2 preencho o form deixando um campo em branco, com isso vai dar erro na validação
fig3 form após redirecionamento, repare que o select vem em branco, sem opções

Abçs

eu modifiquei o código do mydvds de page()).of( pra logic()).forwardTo e o select veio preenchido sem problemas… o problema é na sua aplicação… vou dar uma olhada no seu source pra ver se vejo algo que possa dar problemas…

uma dica: esse seu TarifaController está fazendo coisas demais, classes com mta responsabilidade são difíceis de manter…

mas enfim, o problema mto provavelmente está na lógica do seu método form + o redirecionamento do vraptor…

tenta fazer o seguinte:
-suba o seu servidor em modo de debug
-coloque um breakpoint na primeira linha do método form
-no método adicionar use o:

this.validator.onErrorUse(Results.logic()).forwardTo(TarifaController.class).form("adicionar", tarifa.getHotel().getMneu_for(), 0L);

-execute uma requisição que dá erro de validação

-teoricamente vai parar no breakpoint que vc pôs no método form…
-vê se os parâmetros foram passados direito
-vai passando linha por linha (F6 no eclipse) e vê se ele tá entrando nas condições certas, e se ele está chegando nos result.include dos selects…

provavelmente isso vai te fazer ver qual é o problema que tá acontecendo…

Fiz a modificação que você me orientou no vraptor-mydvds: com isto o select, após a validação, passou a vir preenchido.

Porém a opção do select que havia sido escolhida não veio selecionada. Mostra sempre o select, com a 1a opção disponível selecionada.

Aguardo então sua análise do código que enviei.

Obrigado,
Abçs

Acabei de ver tua resposta, vou fazer o teste via debug.

Fiz ontem o debug pelo Eclipse, mas no meio do processo o Eclipse exibie uma mensagem de erro falando para mim setar a opção ‘java compiller >> add line number atributes to generated class files (used by the debugger)’.

Mas esta opção já está marcada.

Testei com ela marcada e desmarcada e a mensagem sempre vem.

Como você viu minha controller é complexa, estou perdendo bastante tempo tirado cada pedaço dela para achar onde esta erro.

Você lembra da minha dúvida 2: saber como manter após o redirect do vRaptor3 as variávias javaScript ??!! Vi que mesmo que eu faça funcionar a validação vou perder o estado das minhas variáveis javaScript.

É possivel fazer via ajax+vRaptor3 a validação do form ??
presquisei na documentação do vRaptor3 sobre ajax, mas eles focaram na parte de montagem via ajax da view. E na web não achei nenhum exemplo disso.

abçs

vc pode fazer as validações via javascript direto (usando JQuery validator por exemplo), pode submeter o form via ajax e retornar um json caso dê erro de validação, etc