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

[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]

    o que vc quer fazer?

    ao clicar no link vc quer recarregar o grid?

    [quote=Lucas Cavalcanti]o que vc quer fazer?

    ao clicar no link vc quer recarregar o grid?[/quote]

    Não consigo nem visualizar o grid… Fica uma tela em branco, que abre o download… o problema é esse…

    Isso ocorre toda vez que tenta visualizar, seja por link, seja por acesso direto da página digitando o endereço no navegador…

    vlw!

    mas qual página vc está acessando? a /produtos/teste?

    não é pra acessar essa página diretamente, pois isso só mostra o json mesmo.
    O html que vc postou aqui tem que estar em outra página, digamos /produtos/lista.

    crie o método no controller:

    public void lista() {
    }

    e no lista.jsp vc coloca o html que vc tinha posto aqui.

    [quote=Lucas Cavalcanti]mas qual página vc está acessando? a /produtos/teste?

    não é pra acessar essa página diretamente, pois isso só mostra o json mesmo.
    O html que vc postou aqui tem que estar em outra página, digamos /produtos/lista.

    crie o método no controller:

    public void lista() {
    }

    e no lista.jsp vc coloca o html que vc tinha posto aqui.[/quote]

    huummm acho que entendi a idéia… mas meu código está em outra máquina… na segunda feira (23/04) posto o resultado e se deu certo…

    Vlw!

    [quote=Lucas Cavalcanti]mas qual página vc está acessando? a /produtos/teste?

    não é pra acessar essa página diretamente, pois isso só mostra o json mesmo.
    O html que vc postou aqui tem que estar em outra página, digamos /produtos/lista.

    crie o método no controller:

    public void lista() {
    }

    e no lista.jsp vc coloca o html que vc tinha posto aqui.[/quote]

    Oi Lucas,

    Realmente o procedimento agora está encaminhando… rsrsrs. Criando o metodo no ProdutoController só ‘chamando’ a página resolveu mesmo, brigadão.

    Agora a minha nova ‘bobeira’ é que minha ‘grid’ ainda não aparece perfeita… pelo firebug, recebo msg que não está carregando as ‘js’. Mas minhas outras ‘js’ tão no mesmo caminho que usei para a ‘header.jspf’ e nada…

    teste.jsp

    	 <script type="text/javascript" src="<c:url value="/jqgrid/js/jquery.jqGrid.js"/>"></script>
    	 <script type="text/javascript" src="<c:url value="/jqgrid/js/jquery-1.7.2.min.js"/>"></script>
    	 <script type="text/javascript" src="<c:url value="/jqgrid/js/i18n/grid.locale-en.js"/>"></script>		 
    	 <script type="text/javascript" src="<c:url value="/jqgrid/js/grid.base.js"/>"></script>
    	 <script type="text/javascript" src="<c:url value="/jqgrid/js/grid.formedit.js"/>"></script>
    	 <script type="text/javascript" src="<c:url value="/jqgrid/js/grid.common.js"/>"></script>
    	 <script type="text/javascript" src="<c:url value="/jqgrid/js/grid.celledit.js"/>"></script>
    	 <script type="text/javascript" src="<c:url value="/jqgrid/js/grid.grouping.js"/>"></script>
    	 <script type="text/javascript" src="<c:url value="/jqgrid/js/grid.tbltogrid.js"/>"></script>
    	 <script type="text/javascript" src="<c:url value="/jqgrid/js/grid.subgrid.js"/>"></script>
    	 <script type="text/javascript" src="<c:url value="/jqgrid/js/grid.import.js"/>"></script>
    	 <script type="text/javascript" src="<c:url value="/jqgrid/js/jquery.fmatter.js"/>"></script>
    	 <script type="text/javascript" src="<c:url value="/jqgrid/js/grid.treegrid.js"/>"></script>
    	 <script type="text/javascript" src="<c:url value="/jqgrid/js/grid.custom.js"/>"></script>
    	 <script type="text/javascript" src="<c:url value="/jqgrid/js/grid.inlinedit.js"/>"></script>
    	 <script type="text/javascript" src="<c:url value="/jqgrid/js/grid.jqueryui.js"/>"></script>
    	 <script type="text/javascript" src="<c:url value="/jqgrid/js/grid.filter.js"/>"></script>
    	 <script type="text/javascript" src="<c:url value="/jqgrid/js/JsonXml.js"/>"></script>
    	 		 
    	 <link href="<c:url value="/jqgrid/css/ui.jqgrid.css"/>" rel="stylesheet" type="text/css" media="screen" />

    Minha estrutura de arquivos está em anexo e tbem minha visão da tela até o momento com o erro do firebug…

    Aproveitando, para colocar os links ‘editar’ e ‘excluir’ nessa grid, como faria?

    Obrigado e no aguardo.




    não conheço mto do jqgrid… abre um tópico só pra isso, daí outras pessoas ajudam