JQGrid + VRaptor - formatar retorno do result.use (JSON)

Pessoal, como posso fazer para formatar o retorno da chamada de algum metódo antes de serealizar?
O JQGrid (jquery) espera um retorno especifico de JSON

Exemplo:

{
“page”: 1,
“total”: 1,
“records”: 11,
“rows”: [
{“id”: 1, “cell”: [“1”, “Super Item”, “300”, 0, null, false, false]},
{“id”: 2, “cell”: [“2”, “Item 1”, “100”, 1, 1, false, false]},
{“id”: 3, “cell”: [“3”, “Sub Item 1”, “50”, 2, 2, true, true]},
{“id”: 4, “cell”: [“4”, “Sub Item 2”, “25”, 2, 2, false, false]},
{“id”: 5, “cell”: [“5”, “Sub-sub Item 1”, “25”, 3, 4, true, true]},
{“id”: 6, “cell”: [“6”, “Sub Item 3”, “25”, 2, 2, true, true]},
{“id”: 7, “cell”: [“7”, “Item 2”, “200”, 1, 1, false, false]},
{“id”: 8, “cell”: [“8”, “Sub Item 1”, “100”, 2, 7, false, false]},
{“id”: 9, “cell”: [“9”, “Sub-sub Item 1”, “50”, 3, 8, true, true]},
{“id”: 10, “cell”: [“10”, “Sub-sub Item 2”, “50”, 3, 8, true, true]},
{“id”: 11, “cell”: [“11”, “Sub Item 2”, “100”, 2, 7, true, true]}
]
}
Quando eu executo a minha chamada o mesmo retorna JSON puro:

@Get @Path("/produtos/gustavo")
	public void buscaJqGrid() {
		result.use(json())
		.from(dao.getLista())
		.serialize();
	}

Precisaria incluir dados antes de serealizar o JSON
"page": 1,
“total”: 1,
“records”: 11,
“rows”: [

Estou no caminho certo?

Meu código JQGrid:

		jQuery("#list2").jqGrid({
		   	url:'http://localhost:8080/vraptor1/produtos/gustavo',
		   	ajaxGridOptions: { contentType: 'application/json; charset=utf-8' },
			datatype: "json",
			mtype: "POST",
		   	colNames:['ID','Nome', 'Descrição', 'Preço'],
		   	colModel:[
		   		{name:'id',index:'id', width:25},
		   		{name:'nome',index:'nome', width:90},
		   		{name:'descricao',index:'descricao', width:200},
		   		{name:'preco',index:'preco', width:80, align:"right"}
		   	],
		   	rowNum:10,
		   	rowList:[10,20,30],
		   	pager: '#pager2',
		   	sortname: 'id',
		    viewrecords: true,
		    sortorder: "desc",
		    caption:"JSON Example"
		});
		jQuery("#list2").jqGrid('navGrid','#pager2',{edit:false,add:false,del:false});

crie uma classe

class JQGrid {
    private int page;
    private int total;
    private int records;
    private List<?> rows;
}

crie um objeto dessa classe com os parametros setados direitinho e faça:

result.use(json()).withoutRoot().from(jqgrid).include("rows").serialize();

Muito obrigado. Vou testar…

Me falaram que o apoio aqui era fantástico… To impressionado!!!

Lucas, aparentemente funcionou… Só que mesmo assim o JQGrid não mostra dados (undefined)
Eu to na dúvida com a anotação @Remotable, não achei nada na web a respeito, para que serve? Indica que é uma chamada Ajax? Preciso usar???
Qual package?

@Remotable era do vraptor 2, no 3 não existe isso

Vou ter que quebrar a cabeça com o jqgrid então. Porque vem correto o formato json porem nao renderiza. Utilizo outro componente jquery com json que vai legal.

Você conhece outro grid tão legal quanto jqgrid??

acho que não retornou no formato correto…

deveria ser, em cada linha:

 {"id": 1, "cell": ["1", "Super Item", "300", 0, null, false, false]}, 

e vc deve estar retornando:

 {"id": 1, nome: "Super Item", preco:"300"....]}, 

o que vc pode fazer é criar um converter pra essa classe jqGrid que converte pra esse formato… ou ainda descobrir uma option do jqGrid que te deixa tratar o retorno do método

[quote=gbmesso]Pessoal, como posso fazer para formatar o retorno da chamada de algum metódo antes de serealizar?
O JQGrid (jquery) espera um retorno especifico de JSON

Exemplo:

{
“page”: 1,
“total”: 1,
“records”: 11,
“rows”: [
{“id”: 1, “cell”: [“1”, “Super Item”, “300”, 0, null, false, false]},
{“id”: 2, “cell”: [“2”, “Item 1”, “100”, 1, 1, false, false]},
{“id”: 3, “cell”: [“3”, “Sub Item 1”, “50”, 2, 2, true, true]},
{“id”: 4, “cell”: [“4”, “Sub Item 2”, “25”, 2, 2, false, false]},
{“id”: 5, “cell”: [“5”, “Sub-sub Item 1”, “25”, 3, 4, true, true]},
{“id”: 6, “cell”: [“6”, “Sub Item 3”, “25”, 2, 2, true, true]},
{“id”: 7, “cell”: [“7”, “Item 2”, “200”, 1, 1, false, false]},
{“id”: 8, “cell”: [“8”, “Sub Item 1”, “100”, 2, 7, false, false]},
{“id”: 9, “cell”: [“9”, “Sub-sub Item 1”, “50”, 3, 8, true, true]},
{“id”: 10, “cell”: [“10”, “Sub-sub Item 2”, “50”, 3, 8, true, true]},
{“id”: 11, “cell”: [“11”, “Sub Item 2”, “100”, 2, 7, true, true]}
]
}
Quando eu executo a minha chamada o mesmo retorna JSON puro:

@Get @Path("/produtos/gustavo")
	public void buscaJqGrid() {
		result.use(json())
		.from(dao.getLista())
		.serialize();
	}

Precisaria incluir dados antes de serealizar o JSON
"page": 1,
“total”: 1,
“records”: 11,
“rows”: [

Estou no caminho certo?

Meu código JQGrid:

jQuery("#list2").jqGrid({ url:'http://localhost:8080/vraptor1/produtos/gustavo', ajaxGridOptions: { contentType: 'application/json; charset=utf-8' }, datatype: "json", mtype: "POST", colNames:['ID','Nome', 'Descrição', 'Preço'], colModel:[ {name:'id',index:'id', width:25}, {name:'nome',index:'nome', width:90}, {name:'descricao',index:'descricao', width:200}, {name:'preco',index:'preco', width:80, align:"right"} ], rowNum:10, rowList:[10,20,30], pager: '#pager2', sortname: 'id', viewrecords: true, sortorder: "desc", caption:"JSON Example" }); jQuery("#list2").jqGrid('navGrid','#pager2',{edit:false,add:false,del:false}); [/quote]

Você tem que colocar na criação do seu jqgrid, o seguinte codigo


				jsonReader: {  
					root: "rows", //array containing actual data  
				    page: "page", //current page  
				    total: "total", //total pages for the query  
				    records: "records", //total number of records  
				    repeatitems: false,
				    id: "codigo"
				 }

pode ser antes do RowNum.

Srs muito obrigado pela ajuda…

Lucas você deu uma baita luz…

Vou colocar aqui postado a solução completa (ainda falta melhorrar). Não sei se a mais adequada, porém funciona com boa perfomance. O desenvolvimento com VRAPTOR é muito esperto… (Lucas, vocês continuam investindo no framework. Queria ter mais informações, até para ajudar na venda da solução para nossos clientes)

Bom vamos lá:

1o) Classe responsável pelo container do JQGrid

package utils;

import java.util.List;

public class JQGrid {

	private int page;
    private int total;
    private int records;
    private List rows;
  
	public int getPage() {
		return page;
	}
	public void setPage(int page) {
		this.page = page;
	}
	public int getTotal() {
		return total;
	}
	public void setTotal(int total) {
		this.total = total;
	}
	public int getRecords() {
		return records;
	}
	public void setRecords(int records) {
		this.records = records;
	}
	
	public List getRows() {
		return rows;
	}
	
	public void setRows(List rows) {
		this.rows = rows;
	}
}
  1. Classe para trabalhar as celulas que compoe o JQGrid
package utils;

import java.util.List;

public class JQGridRow {
	
	private Long id;
	private List cell;
	
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public List getCell() {
		return cell;
	}
	public void setCell(List cell) {
		this.cell = cell;
	}
	
	

}
  1. Controller

[code]
@Get @Path("/produtos/gustavo")
public void buscaJqGrid() {

	JQGrid jqgrid = new JQGrid();
	
	List rows = new ArrayList();

	for (Produto c : dao.getLista()) {
		JQGridRow row = new JQGridRow();
		row.setId(c.getId());
		List cells = new ArrayList();
		cells.add(c.getId());
		cells.add(c.getNome());
		cells.add(c.getDescricao());
		cells.add(c.getPreco());
		row.setCell(cells);
		rows.add(row);
	}

	jqgrid.setRows(rows);
	jqgrid.setTotal(10);
	jqgrid.setPage(1);
	jqgrid.setRecords(10);

/*
jsonReader: {
root: “rows”, //array containing actual data
page: “page”, //current page
total: “total”, //total pages for the query
records: “records”, //total number of records
repeatitems: false,
id: “codigo”
}
*/

	result.use(json()).withoutRoot().from(jqgrid).include("rows").serialize();  
}
  1. JSP
	<table id="list2"></table>
	<div id="pager2"></div>


	<script type="text/javascript">
		// Carregar dados no Grid	
		jQuery("#list2").jqGrid({
		   	url:'/vraptor1/produtos/gustavo',
		   	ajaxGridOptions: { contentType: 'application/json; charset=utf-8' },
			datatype: "json",
//			mtype: "POST",
		   	colNames:['ID','Nome', 'Descrição', 'Preço'],
		   	colModel:[
		   		{name:'id',index:'id', width:25},
		   		{name:'nome',index:'nome', width:90},
		   		{name:'descricao',index:'descricao', width:200},
		   		{name:'preco',index:'preco', width:80, align:"right"}
		   	],
		   	rowNum:10,
		   	rowList:[10,20,30],
		   	pager: '#pager2',
		   	sortname: 'id',
		    viewrecords: true,
		    autowidth: true,
		    sortorder: "desc",
		    caption:"JSON Example",
		   	loadError: function(xhr,status,error) {alert(' error: ' + error);},

		    serializeGridData:function(postData){
		    	alert(' postData: ' + postData.rows);
			},
		    
		    loadComplete:function(data){
		    	alert('loadComplete - data: ' + data);

		    	var propertyName
		        for (propertyName in data) {
		        	alert(propertyName + ' ' + data[propertyName]);
		        }
		    }

		});
		jQuery("#list2").jqGrid('navGrid','#pager2',{edit:false,add:false,del:false});

	</script>

Não esquecer dos JSs:


Preciso ainda melhorar a captura da quantidade de registros, pagina, etc…

Mas o básico está ai. Espero poder contribuir…

continuamos investindo no vraptor sim =).

podemos tambem transformar esse código em um cookbook

Bom dia, muito obrigado pelas informações ajudou muito. No entanto ficamos com um duvida, como passar parâmetro para o meu controller?

só receber o parâmetro no controller, e passar um parâmetro na requisição com o mesmo nome.

Lucas, sei que o tópico é um pouco antigo, mas to seguindo a mesma idéia do amigo ‘gbmesso’ e tentando implementar essa JQGrid no meu projeto do curso FJ-28.

O que ocorre, é que quando eu mando abrir a página, sempre pede um download.

Eu vi um caso que vc ajudou, nesse post:

http://www.guj.com.br/java/145301-vraptor-3–json/3

Mas não entendi bem a idéia…

Se puder dar uma luz, agradeço… Vlw!

Só pra complementar, estou abrindo a página por um link do header:

header.jspf

[code]

  • ">Lista Produtos (teste)
  • [/code]

    ProdutosController.java

    [code]

    @Get @Path("/produtos/teste")
    public void buscaJqGrid() {

        JQGrid jqgrid = new JQGrid();  
          
        List rows = new ArrayList();  
    
        for (Produto c : dao.listaTudo()) {  
            JQGridRow row = new JQGridRow();  
            row.setId(c.getId());  
            List cells = new ArrayList();  
            cells.add(c.getId());  
            cells.add(c.getNome());  
            cells.add(c.getDescricao());  
            cells.add(c.getPreco());  
            row.setCell(cells);  
            rows.add(row);  
        }  
    
        jqgrid.setRows(rows);  
        jqgrid.setTotal(10);  
        jqgrid.setPage(1);  
        jqgrid.setRecords(10);  	
      
        result.use(Results.json()).withoutRoot().from(jqgrid).include("rows").serialize();    
    } [/code]
    

    teste.jsp

    [code]

    <script type="text/javascript">  
        // Carregar dados no Grid     
        jQuery("#list2").jqGrid({  
            url:'/vraptor-fj28/produtos/teste',  
            ajaxGridOptions: { contentType: 'application/json; charset=utf-8' },  
            datatype: "json",  
            //mtype: "POST",  
            colNames:['ID','Nome', 'Descrição', 'Preço'],  
            colModel:[  
                {name:'id',index:'id', width:25},  
                {name:'nome',index:'nome', width:90},  
                {name:'descricao',index:'descricao', width:200},  
                {name:'preco',index:'preco', width:80, align:"right"}  
            ],  
            rowNum:10,  
            rowList:[10,20,30],  
            pager: '#pager2',  
            sortname: 'id',  
            viewrecords: true,  
            autowidth: true,  
            sortorder: "desc",  
            caption:"JSON Example",  
            loadError: function(xhr,status,error) {alert(' error: ' + error);},  
    
            serializeGridData:function(postData){  
                alert(' postData: ' + postData.rows);  
            },  
              
            loadComplete:function(data){  
                alert('loadComplete - data: ' + data);  
    
                var propertyName  
                for (propertyName in data) {  
                    alert(propertyName + ' ' + data[propertyName]);  
                }  
            }  
    
        });  
        jQuery("#list2").jqGrid('navGrid','#pager2',{edit:false,add:false,del:false});  
    
    </script> [/code]
    

    as classes JQGrid e JQGridRow estão identicas ao que foi elaborado pelo usuário ‘gbmesso’…

    Obrigado à todos!

    vc testou isso no IE?

    Não, sempre uso o firefox como navegador default… Não estou com a aplicação no momento pra efetuar os testes no IE pra dar o retorno… acha necessário esse teste?

    vlw.

    não precisa fazer o teste no ie agora, é que esse erro acontece às vezes no IE…

    instala o firebug no firefox, e dá uma olhada se tá dando algum erro javascript…

    vc tá clicando em algum link que tem o caminho do controller que tá retornando o json?

    [quote=Lucas Cavalcanti]não precisa fazer o teste no ie agora, é que esse erro acontece às vezes no IE…

    instala o firebug no firefox, e dá uma olhada se tá dando algum erro javascript…

    vc tá clicando em algum link que tem o caminho do controller que tá retornando o json?[/quote]

    ate tenho o firebug instalado, mas realmente não verifiquei se deu alguma msg de erro por lá, vou ver melhor…

    quanto ao acesso ao controller, eu criei um link de acesso direto à página, mas digitando diretamente o endereço no navegador da página, acontece a mesma coisa.

    link no header.jspf:

    [code]

  • ">Lista Produtos (teste)
  • [/code]

    no ProdutosController, mesmo colocando o path no método:

    @Get @Path("/produtos/teste") public void buscaJqGrid() { ...

    ou

    @Get @Path("/produtos/teste.json") public void buscaJqGrid() { ...

    Tá dando o mesmo problema…

    Vlw!

    e a tela de download aparece qdo vc clica no link, certo?

    se sim, é assim mesmo… vc deveria chamar a url desse link via ajax, pra popular algo, por exemplo o jqGrid.

    [quote=Lucas Cavalcanti]e a tela de download aparece qdo vc clica no link, certo?

    se sim, é assim mesmo… vc deveria chamar a url desse link via ajax, pra popular algo, por exemplo o jqGrid.[/quote]

    Esse ponto justamente que não estou entendendo… estou seguindo a mesma idéia que postaram aqui, e em que momento chamo essa url no ajax? acho que na minha página jsp, já está fazendo a chamada na linha 10 do código:

    teste.jsp

    [code]
    <script type=“text/javascript” src="<c:url value="/jqgrid/js/i18n/grid.locale-pt-br.js"/>">
    <script type=“text/javascript” src="<c:url value="/jqgrid/js/jquery.jqGrid.min.js"/>">

    <table id="list2"></table>    
       <div id="pager2"></div>    
          
       <script type="text/javascript">    
           // Carregar dados no Grid       
           jQuery("#list2").jqGrid({    
               url:'/vraptor-fj28/produtos/teste',    //chamada url 
               ajaxGridOptions: { contentType: 'application/json; charset=utf-8' },    
               datatype: "json",    
               //mtype: "POST",    
               colNames:['ID','Nome', 'Descrição', 'Preço'],    
               colModel:[    
                   {name:'id',index:'id', width:25},    
                   {name:'nome',index:'nome', width:90},    
                   {name:'descricao',index:'descricao', width:200},    
                   {name:'preco',index:'preco', width:80, align:"right"}    
               ],    
               rowNum:10,    
               rowList:[10,20,30],    
               pager: '#pager2',    
               sortname: 'id',    
               viewrecords: true,    
               autowidth: true,    
               sortorder: "desc",    
               caption:"JSON Example",    
               loadError: function(xhr,status,error) {alert(' error: ' + error);},    
      
               serializeGridData:function(postData){    
                   alert(' postData: ' + postData.rows);    
               },    
                   
               loadComplete:function(data){    
                   alert('loadComplete - data: ' + data);    
      
                   var propertyName    
                   for (propertyName in data) {    
                       alert(propertyName + ' ' + data[propertyName]);    
                   }    
               }    
      
           });    
           jQuery("#list2").jqGrid('navGrid','#pager2',{edit:false,add:false,del:false});    
      
       </script>   [/code]