VRaptor pegar valor dos checkbox checados

Bom galera, como faço pra pegar o valor dos checkbox checados no VRaptor?

Tenho uma relação Post NxM Category, e quando vou classificar os posts já quero selecionar quantas categorias for possivel.
Aproveitando a deixa, usando o hibernate(Criteria) nesse caso, como faço para listar as categorias que ainda não tem post e vice-versa?

Sobre os checkboxes você pode usar algo como:

<input type="checkbox" name="categories[0].id" value="1" /> categoria-1 <input type="checkbox" name="categories[1].id" value="2" /> categoria-2 <input type="checkbox" name="categories[2].id" value="3" /> categoria-3

E no controller

public void foo(List<Category> categories) { ... }

Você pode fazer isso, que é um pouco feio, mas é o mais simples:

List<Category> categories = post.getCategories();
List<Long> categoriesIds = //transforma a lista para ids

session.createCriteria(Category.class)
    .add(Restrictions.in("id", categoriesIds)).list();

jeito complicado, é algo do tipo:

session.createCriteria(Category.class)
      .add(Subqueries.notIn("id",
             DetachedCriteria.createCriteria(Post.class, "p")
                 .createAlias("p.categories", "category")
                 .setProjection(Projections.property("category")
                    .add(Restrictions.eq("p.id", post.getId()))
         )).list();

deve ter vários parêntesis errados, e nomes de métodos, mas é algo assim estranho :stuck_out_tongue:

No caso dos checkbox eles estão dentro de uma tabela, e isso é dinâmico, eu não saberei os indices para setar em name e nem mesmo em value.

Eu ainda não testei a solução que vc me passou, vou testar ao chegar da faculdade, mais acho que assim da certo:

<table> <c:forEach var="category" items="${categories}"> <tr> <td><input type="checkbox" name="${category.id}" value="${category.id}" /> ${category.description}</td> </tr> </c:forEach> </table>

Como eu disse eu ainda não testei, mais baseado na solução que vc me passou eu presumo que da forma acima de certo. Ou eu estou errado?

Quanto a solução do hibernate eu prefiro a solução mais facil. Vou testar.
Uma pergunta, temos alguma diferença de performance quando utilizado Criteria ou HQL?

Olá, tenta fazer assim:

<table>
     <c:forEach var="category" items="${categories}" varStatus="s">
        <tr>
          <td><input type="checkbox" name="categories[${s.index}].id" value="${category.id}" /> ${category.description}</td>
        </tr>
    </c:forEach>
</table>

e receber um
(List categories)
no seu método

quanto à diferença de performance, depende da complexidade das queries que você criar…
para queries pequenas é irrelevante… para queries grandes, com vários subselects e joins,
talvez tenha alguma diferença sim, só não sei te dizer qual vai ser melhor… mas sem dúvida
hql é mais legível para queries grandes…

Poderia dar um exemplo de como ficaria em HQL o que você passou em Criteria.

session.createQuery("from Category c where c not in (:categories)").setParameterList("categories", post.getCategories()).list()

ou se vc não quiser chamar o getCategories do post:

session.createQuery("from Category c where c not in (select p.categories from Post p where p = :post)").setParameterList("post", post).list()

nas duas situações, tanto HQL quanto criteria, as minhas coleções estando Lazy elas estarão null.

Dai como fica nessa situação?

quanto ao hql deu certo, optei por ele por achar mais simular ao já conhecido sql e por ser mais facil de entender.

Agora quanto ao checkbox, fiz da forma que vc me falou e minha coleção que recebo como parâmetro vem sempre null.

<table> <c:forEach var="service" items="${services}" varStatus="s"> <tr> <td><input type="checkbox" name="{services[${s.index}].id}" value="${service.id}" /> ${service.description}</td> </tr> </c:forEach> </table>

public void create(ServiceProvider serviceProvider, List<Service> services){ this.dao.create(serviceProvider, services); }

Não funcionou.

tira as chaves do nome dos checkboxes:

<td><input type="checkbox" name="services[${s.index}].id" value="${service.id}" /> ${service.description}</td>

o name dos inputs deve ser sempre uma string mesmo, não uma variável…

[]'s

Funcionou, huhu…

obrigadoooo.

Pra inserir tudo certo, e para eu atualizar como ficaria para os checkboxs virem checados?

E se não for pedir muito poderias responder pra mim um outro pergunta que eu abri aqui no forum:

http://www.guj.com.br/posts/list/144981.java

Desde já agradeço a atenção.

isso é um pouco difícil…

mas vai ser algo do tipo:

<%@ taglib prefix="fn" uri="...../functions" %>
<%@ taglib prefix="c" uri="...../core" %>
...

<input type="checkbox" ....
        <c:if test="${fn:contains(service, cara.services)}">
               checked="checked"
        </c:if>
    /><!-- fechando a tag do checkbox -->

eu provavelmente estou errando alguma ordem, mas acho que isso funciona…

[]'s

opa show de bola até aqui tudo certo.

Agora como faço pra pegar o valor de um só checkbox, no caso tenho um que diz que situação ativo/inativo?

<input type="checkbox" 
        ....
        <c:if test="${ativo}">  
                checked="checked"  
      </c:if>  
 /><!-- fechando a tag do checkbox -->  

Pelo que eu entendi dessa forma eu chegaria o checkbox na hora de editar, mais a minha pergunta seria no momento do insert, pois mesmo o checkbox estando checado o valor sempre esta como false.

se vc tem a classe:

public class Usuario {
    private boolean ativo;
    //getters e setters
}

e no método do controller:

public void adiciona(Usuario usuario){...}

é só colocar no checkbox:

<input type="checkbox" name="usuario.ativo" />

que deve funcionar… se não funcionar, coloca value=“true” também