[Resolvido] Ajuda - vRaptor - Editar checkbox

6 respostas
Wendell_Albino

Bom dia!

Ainda estou desenvolvendo um controle de manutenção de usuários de um sistema e, depois que foi resolvido a parte de cadastro com os checkboxs http://www.guj.com.br/java/279230-resolvido-ajuda---iniciante-vraptor---adicao-list-checkbox

agora estou com um problema de lógica para alterar o perfil do usuário.

Na página JSP coloquei da seguinte forma:

<c:forEach items="${regras}" var="regra" varStatus="s"> <input type="checkbox" name="usuario.regras[${s.index}].codRegra" value="${regra.codRegra}" <c:if test="${usuario.regras[s.index].codRegra eq regra.codRegra}"> checked="checked" </c:if> /> ${regra.perfil} </c:forEach>

onde deveriam aparecem selecionados os checkboxs com os perfis correspondentes do usuário a ser editado.
Porém está acontecendo que não seleciona corretamente os perfis do usuário selecionado. Por exemplo, tenho 3 perfis diferente no sistema. Cadastro um novo usuário com 2 perfis. Mas quando vou edita-lo aparece apenas 1 checkbox selecionado. No banco de dados está salvando normalmente.

Alguém sabe o problema desta lógica?

6 Respostas

Rafael_Guerreiro

Eu faria essa seleção depois com javascript. Do jeito que está, o código fica meio poluído.

Você pode alterar o toString de uma regra para que você consiga converter ela em um array na JSP e manipulá-la no javascript:

public class Regra {
   private long id;
   private String name;

   public String toString(){
       return "{id: '"+ this.getId() + "', name:'" + this.getName() + "'}"; // repara que o valor do ID e o valor do name estão com aspas simples (') para transformá-los em String no javascript.
   }

// getters e setters
}

Assim, vamos supor que você tem uma lista com 3 regras:

// esboço da ideia dos valores.
regra 1:
   id = 1
   name = "xpto"
regra 2:
   id = 2
   name = "abcde"
regra 3:
   id = 3
   name = "1 2 3 de Oliveira 4"

Com isso, será gerado a seguinte saída no .toString() da lista de regras:

Dessa forma, você tem um array de objetos no javascript.

&lt;c:forEach items="${regras}" var="regra" varStatus="s"&gt;  
   &lt;input type="checkbox" name="usuario.regras[${s.index}].codRegra"  
      value="${regra.codRegra}" /&gt; ${regra.perfil}        
&lt;/c:forEach&gt;
&lt;script&gt;
   var selecteds = ${usuario.regras};
// se vc estiver usando jQuery, aqui fica mais limpo ainda...
   $(selecteds).each(function(){
      $('input[type=checkbox][value=' + this.id + ']').attr('checked', true);
   });
&lt;/script&gt;

Isso deve funcionar…

Wendell_Albino

Rafael Guerreiro,

interessante desta forma usando o javascript. Funcionou perfeitamente!
Mas será que o VRaptor consegue fazer isso não?

Lucas_Cavalcanti

dá uma olhada no teste que vc fez:

<c:if test="${usuario.regras[s.index].codRegra eq regra.codRegra}">

ou seja, vc tá testando que se a regra do usuário do índice X é igual à regra atual… vc deveria ver se a regra atual está dentro da lista de regras do usuário…

se vc usar a taglib fn dá pra tentar fazer:

<c:if test="${fn:contains(usuario.regras, regra)}">

ou algo do tipo.

Rafael_Guerreiro

Checar os checks para você baseado em uma lista? Não. Ele consegue é gerar um JSON para que a gente possa usar no JavaScript. É bem legal, mas não atende muito bem à esse seu caso…

O ideal é você deixar o javascript em um arquivo JS separado:

&lt;script&gt;
   var selecteds = ${usuario.regras};
&lt;/script&gt;
&lt;script src="&lt;c:url value="/js/algumNomeQueVoceIdentifique.js" /&gt;"&gt;&lt;/script&gt;

// E dentro do algumNomeQueVoceIdentifique.js você coloca isso.
   $(selecteds).each(function(){
      $('input[type=checkbox][value=' + this.id + ']').attr('checked', true);
   });

É ainda melhor se você colocá-los dentro de um bloco de função do jQuery:

// Assim o jQuery guarda essas instruções para serem executadas somente quando a página carrega, ou seja, não haverão JS atrasando o carregamento da página. Dando a impressão de que ela é mais rápida.
$(document).ready(function(){
   $(selecteds).each(function(){
      $('input[type=checkbox][value=' + this.id + ']').attr('checked', true);
   });
});
Wendell_Albino

Lucas Cavalcanti:
dá uma olhada no teste que vc fez:

<c:if test="${usuario.regras[s.index].codRegra eq regra.codRegra}">

ou seja, vc tá testando que se a regra do usuário do índice X é igual à regra atual… vc deveria ver se a regra atual está dentro da lista de regras do usuário…

se vc usar a taglib fn dá pra tentar fazer:

<c:if test="${fn:contains(usuario.regras, regra)}">

ou algo do tipo.

Cara, não conhecia esta função da taglib! Muito bom! Desta forma funcionou sim!

Wendell_Albino

Rafael Guerreiro:
Checar os checks para você baseado em uma lista? Não. Ele consegue é gerar um JSON para que a gente possa usar no JavaScript. É bem legal, mas não atende muito bem à esse seu caso…

O ideal é você deixar o javascript em um arquivo JS separado:

&lt;script&gt;
   var selecteds = ${usuario.regras};
&lt;/script&gt;
&lt;script src="&lt;c:url value="/js/algumNomeQueVoceIdentifique.js" /&gt;"&gt;&lt;/script&gt;

// E dentro do algumNomeQueVoceIdentifique.js você coloca isso.
   $(selecteds).each(function(){
      $('input[type=checkbox][value=' + this.id + ']').attr('checked', true);
   });

É ainda melhor se você colocá-los dentro de um bloco de função do jQuery:

// Assim o jQuery guarda essas instruções para serem executadas somente quando a página carrega, ou seja, não haverão JS atrasando o carregamento da página. Dando a impressão de que ela é mais rápida. $(document).ready(function(){ $(selecteds).each(function(){ $('input[type=checkbox][value=' + this.id + ']').attr('checked', true); }); });

Obrigado pela explicação! O melhor é deixar o código bem organizado mesmo.

Criado 3 de agosto de 2012
Ultima resposta 3 de ago. de 2012
Respostas 6
Participantes 3