VRaptor3 + Flexigrid + JSON

36 respostas
Cherubini

Olá pessoal,

blz?

estou testando um grid chamado flexigrid com o vraptor3 porem eu não estou conseguindo carregar os dados nele, o componente chama em modo debug meu metodo com passando o arquivo json e tals, porem não aparece nada !!!

A unica coisa que comecou a dar erro foi agora o jquery, que antes estava funcionando perfeito

Erro Jquery:

object is undefined
[Break on this error] length = object.length,

Controller:

@Path("/user.json")
	public void listUsers(){
		User user = userDao.getUserDao().listAll().get(0); 
		result.use(json()).from(user).serialize();
	}

View:

$("#flex1").flexigrid({
		url: '/JPM/user.json',
		dataType: 'json',
		colModel : [
			{display: 'ID', name : 'id', width : 40, sortable : true, align: 'center'},
			{display: 'Email', name : 'email', width : 250, sortable : true, align: 'left'},
			{display: 'Password', name : 'password', width : 40, sortable : true, align: 'left'},
			{display: 'Name', name : 'name', width : 250, sortable : true, align: 'left'},
			{display: 'Rule', name : 'rule', width : 150, sortable : true, align: 'left'}			
		],
		buttons : [
			{name: 'Add', bclass: 'add', onpress : onClick},
			{name: 'Delete', bclass: 'delete', onpress : onClick},
			{separator: true}
		],
		searchitems : [
			{display: 'Email', name : 'email'},
			{display: 'Rule', name : 'Rule'},
			{display: 'Name', name : 'name', isdefault: true}
		],
		sortname: "id",
		sortorder: "asc",
		usepager: true,
		singleSelect: true,
		title: 'Users',
		useRp: true,
		rp: 15,
		showTableToggleBtn: true,
		width: 950,
		height: 200
	});

Se alguem tiver alguma dica, ficarei grato!

Obrigado.

OBS:

Coloquei a versão min do jquery 1.4.2 e agora o erro mudou para:

a is undefined
[Break on this error] a))();else c.error("Invalid JSON: "+a)...(d)if(i)for(f in a){if(b.apply(a[f],

36 Respostas

Lucas_Cavalcanti

faça uma requisição direto para o /user.json e poste aqui o json que ele está retornando plz

Cherubini

Lucas,

segue o json:

{"user": {
  "id": 1,
  "email": "[email removido]",
  "password": "123456",
  "name": "t",
  "rule": "ADMINISTRATOR"
}}

Obrigado.

Lucas_Cavalcanti

vc quer mesmo mostrar a senha dos usuários?

enfim, mude a geração do json para:

result.use(json()).withoutRoot().from(user).serialize();
Cherubini

Não, lucas isso é só um teste ! É logico que não !! Quero fazer funcionar primeiro, depois vou ajustando !

Ajustei do jeito que você falou e mesmoa ssim não funcionou!!!

Segue json:

{
  "id": 1,
  "email": "[email removido]",
  "password": "123456",
  "name": "t",
  "rule": "ADMINISTRATOR"
}
Cherubini

Esse erro ainda no firebug esta ocorrendo:

a is undefined
[Break on this error] a))();else c.error("Invalid JSON: "+a)...(d)if(i)for(f in a){if(b.apply(a[f],
Lucas_Cavalcanti

então… na documentação do flexgrid qual é o formato de json que ele espera?

Cherubini

Lucas,

pelo o qe vi na net, o povo usando com PHP ele, usa uma estrutura de cel, segue exemplo:

"{id: '" . $pais['Country']['iso'] . "', 
    cell: ['"  . $pais['Country']['iso'] . "', '"
               . $pais['Country']['name'] . "', '" 
               . $pais['Country']['printable_name'] . "', '" 
               . $pais['Country']['iso3'] . "', '" 
               . $pais['Country']['numcode'] . 
        "']
}";
Lucas_Cavalcanti

bom, se vc precisa que seja assim, vc precisa criar um converter pra gerar o json desse jeito…

ou talvez tenha no flexgrid um método que trate o json antes de qqer coisa, daí vc pode converter o json padrão do vraptor

Cherubini

achei esse é o formato que o flexigrid verifica:

{
  "page": 1,
  "total": 2,
  "rows":[
    {"id": "ALFKI", "cell": ["ALFKI","Alfreds Futterkiste",
                             "Maria Anders", ... ,"030-0076545"]},
    {"id": "ANATR", "cell": ["ANATR","Ana Trujillo Emparedados y helados",
                             "Ana Trujillo","Owner", ... ,"(5) 555-3745"]}
  ]
}

Bem diferente do formato do vraptor !!!

Não teria algum grid que melhor se adequa ao Vraptor?

G

Eu olhei no site e conforme a documentação esse é o JSON esperado para a listagem.

Creio que nesse caso você precise criar um POJO aí para conter os dados da listagem, e a partir dele o Vraptor serializa o JSON.

pubic class Grid { private Integer page; private Integer total; private List<User> rows; }

E no controller:

@Path("/user.json") public void listUsers(){ List<User> users = userDao.getUserDao().listAll(); Grig grid = // monta a grid com os dados para o flexigrid result.use(json()).withoutRoot().from(grid).include(users).serialize(); }

Cherubini:
achei esse é o formato que o flexigrid verifica:

{
  "page": 1,
  "total": 2,
  "rows":[
    {"id": "ALFKI", "cell": ["ALFKI","Alfreds Futterkiste",
                             "Maria Anders", ... ,"030-0076545"]},
    {"id": "ANATR", "cell": ["ANATR","Ana Trujillo Emparedados y helados",
                             "Ana Trujillo","Owner", ... ,"(5) 555-3745"]}
  ]
}

Bem diferente do formato do vraptor !!!

Não teria algum grid que melhor se adequa ao Vraptor?

Cherubini

Garcia,

na verdade da documentacao do flexgrid segue esse pojo:

public class FlexigridRow {

	public String id;
	public List<String> cell;

}


public class FlexiGridJson {

	private Integer page;
	private Integer total;
	private List<FlexigridRow> rows;
}

Porem nao estou conseguindo mandar o atributo cell para o json, ele esta ignorando os valores, e dando o seguinte erro:

row.cell is undefined
[Break on this error] td.innerHTML = row.cell[idx];

com razao, pois meu pojo esta vindo sem ele!

Segue codigo

@Path("/user.json")
	public void listUsers(){
		List<User> users = userDao.getUserDao().listAll();
		List<FlexigridRow> rows = new ArrayList<FlexigridRow>();
		
			FlexigridRow row = new FlexigridRow();
			row.setId(users.get(0).getId()+"");
			row.setCell(users);
			rows.add(row);
		
		FlexiGridJson grid = new FlexiGridJson(1, users.size(), rows);
		result.use(json()).withoutRoot().from(grid).include("rows").serialize();  
	}

e o json gerado

{
  "page": 1,
  "total": 1,
  "rows": [
    {
      "id": "1"
    }
  ]
}

Alguem tem alguma dica ?

Cherubini

tentei dar um include no “cell” porem nada feito.

segue code:

@Path("/user.json")
	public void listUsers(){
		List<User> users = userDao.getUserDao().listAll();
		List<FlexigridRow> rows = new ArrayList<FlexigridRow>();
		
			FlexigridRow row = new FlexigridRow();
			row.setId(users.get(0).getId()+"");
			row.setCell(users);
			rows.add(row);
		
		FlexiGridJson grid = new FlexiGridJson(1, users.size(), rows);
		result.use(json()).withoutRoot().from(grid).include("rows").include("cell").serialize();  
	}
G

O Lucas pode dizer se estou certo, mas se não me engano no include deve ser o caminho completo da propriedade:

Cherubini

Garcia funciou !!!

Porem flexigrid é um lixo ! Tive que transformar meu json nesse formato

O Flexigrid aceita o segundo json nao o primeiro

{
  "page": 1,
  "total": 1,
  "rows": [
    {
      "id": "1",
      "cell": [
        {
          "id": 1,
          "email": "[email removido]",
          "password": "123456",
          "name": "t",
          "rule": "ADMINISTRATOR"
        }
      ]
    }
  ]
}

//ACEITO PELO FLEXIGRID

{
  "page": 1,
  "total": 1,
  "rows": [
    {
      "id": "1",
      "cell": [
        "1",
        "[email removido]",
        "123456",
        "t",
        "ADMINISTRATOR"
      ]
    }
  ]
}

ai tive que fazer uma gambi para aceitar

@Path("/user.json")
	public void listUsers(){
		List<User> users = userDao.getUserDao().listAll();
		List<FlexigridRow> rows = new ArrayList<FlexigridRow>();
			
			List<String> cell = new ArrayList<String>();
			FlexigridRow row = new FlexigridRow();
			row.setId(users.get(0).getId()+"");
			
			String id = users.get(0).getId()+"";
			String email = users.get(0).getEmail()+"";
			String password = users.get(0).getPassword()+"";
			String name = users.get(0).getName()+"";
			String rule = users.get(0).getRule()+"";
			cell.add(id);
			cell.add(email);
			cell.add(password);
			cell.add(name);
			cell.add(rule);
			
			row.setCell(cell);
			rows.add(row);
		
		FlexiGridJson grid = new FlexiGridJson(1, users.size(), rows);
		result.use(json()).withoutRoot().from(grid).include("rows").include("rows.cell").serialize();   
	}

Vocês não uma maneira mais bonita ?rs

Vlws

G

Duas dicas: é bom você evitar fazer várias chamadas de get em um List. Ao invés associe a uma variavel e busque dela os valores:

// disso
users.get(0).getId()

// para isso
User user = users.get(0);

user.getId();
user.getName();

Além disso evite criar StringBuilder/StringBuffers desnecessários:

//disso
user.getId()+"";

//para isso
String.valueOf(user.getId());
Lucas_Cavalcanti

ao invés dos includes, vc pode usar um recursive()…

dá pra criar um conversor do XStream que já gera o formato do flexgrid…

dá pra ver se o flexgrid pode ser customizado tb

ou dá pra tentar outra biblioteca de grids

J

Lucas Cavalcanti:
ao invés dos includes, vc pode usar um recursive()…

dá pra criar um conversor do XStream que já gera o formato do flexgrid…

dá pra ver se o flexgrid pode ser customizado tb

ou dá pra tentar outra biblioteca de grids

Aproveitando seu comentario vejo que na web e muito pobre a parte de grids editaveis hoje eu uso JqGrid mas ainda acho q tem muito q melhorar vc tem outras opcoes de Grids ?

Leandro-SP

Também estou a procura de uma biblioteca para grid… vou tentar integrar o meu projeto que usa vraptor3 com o Flexigrid mesmo… será que existem outras opções mais fáceis de integrar com o vraptor?

Aguardo resposta.
Obrigado.
Att,
Leandro.

Lucas_Cavalcanti

o ExtJS tem um grid, e existe um jQuery Grid plugin tb…

não tenho certeza se é mais fácil, mas são outras opções

Leandro-SP

ae Cherubini e pessoal!!!
Consegui serializar os dados para inserir no Flexigrid… porém como que eu jogo isso na View?
Dentro do jsp como fica o javascript? quais os imports que preciso?
aguardo resposta.
obrigado.
Leandro.

Leandro-SP

Ninguém?

Lucas_Cavalcanti

jsp, e imports?

vc não vai colocar código java no jsp!

vc só precisa chamar a url da lógica que gera o json via ajax

Leandro-SP

Lucas Cavalcanti:
jsp, e imports?

vc não vai colocar código java no jsp!

vc só precisa chamar a url da lógica que gera o json via ajax

Lucas Cavalcanti,

Você tem um exemplo de como chamar a url da logica do json via ajax de dentro do jsp?

Estou tentando com um

mas não está mostrando o Flexigrid…

Aguardo resposta.

Obrigado.

Leandro.

Lucas_Cavalcanti

se vc tem o div:

<div id="banana"></div>

e quer mostrar o flexgrid dentro dessa div, vc tem que colocar esse código de javascript no final da sua jsp, antes do

<script type="text/javascript">
   $("#banana").flexgrid({
        url: '/url/da/logica/que/gera/o/json',
        //outras configurações do flexgrid
   });
</script>
Leandro-SP
Lucas Cavalcanti:
se vc tem o div:
<div id="banana"></div>

e quer mostrar o flexgrid dentro dessa div, vc tem que colocar esse código de javascript no final da sua jsp, antes do

<script type="text/javascript">
   $("#banana").flexgrid({
        url: '/url/da/logica/que/gera/o/json',
        //outras configurações do flexgrid
   });
</script>

Engraçado! ainda nao to conseguindo renderizar o flexigrid.. to fazendo tudo direitinho... incluí o codigo:

<script type="text/javascript" src="<c:url value="/javascripts/flexigrid.js"/>"></script>

No header.jspf

E estou chamando no lista.jsp

<div id="flex1"></div>
		
         <script type="text/javascript">
						$("#flex1").flexigrid({
							url: '/usuario/lista.json',
							dataType: 'json',
							colModel : [
								{display: 'ID', name : 'id', width : 40, sortable : true, align: 'center'},
								{display: 'Email', name : 'email', width : 250, sortable : true, align: 'left'},
								{display: 'Senha', name : 'senha', width : 40, sortable : true, align: 'left'},
								{display: 'Nome', name : 'nome', width : 250, sortable : true, align: 'left'},
								{display: 'Roles', name : 'roles', width : 150, sortable : true, align: 'left'}			
							],
							buttons : [
								{name: 'Add', bclass: 'add', onpress : onClick},
								{name: 'Delete', bclass: 'delete', onpress : onClick},
								{separator: true}
							],
							searchitems : [
								{display: 'Email', name : 'email'},
								{display: 'Roles', name : 'roles'},
								{display: 'Nome', name : 'nome', isdefault: true}
							],
							sortname: "id",
							sortorder: "asc",
							usepager: true,
							singleSelect: true,
							title: 'Users',
							useRp: true,
							rp: 15,
							showTableToggleBtn: true,
							width: 950,
							height: 200
						});   
						</script>

quando eu chamo diretamente a url /usuario/lista.json vem o arquivo direitinho com os dados.

O que posso estar fazendo errado?

Lucas_Cavalcanti

o problema é que

url: '/usuario/lista.json',

desconsidera o context path…

então vc teria que fazer algo do tipo:

url: '<c:url value="/usuario/lista.json"/>',

ou colocar o nome do contexto hard_coded:

url: '/contexto/usuario/lista.json',
Leandro-SP

Já tentei desta maneira aí... nem sinal do flexigrid...

<div id="flex1"></div>
			
				<script type="text/javascript">
						$("#flex1").flexigrid({
							url: '<c:url value="/usuario/lista.json"/>',
							dataType: 'json',
							colModel : [
								{display: 'ID', name : 'id', width : 40, sortable : true, align: 'center'},
								{display: 'Email', name : 'email', width : 250, sortable : true, align: 'left'},
								{display: 'Senha', name : 'senha', width : 40, sortable : true, align: 'left'},
								{display: 'Nome', name : 'nome', width : 250, sortable : true, align: 'left'},
								{display: 'Roles', name : 'roles', width : 150, sortable : true, align: 'left'}			
							],
							buttons : [
								{name: 'Add', bclass: 'add', onpress : onClick},
								{name: 'Delete', bclass: 'delete', onpress : onClick},
								{separator: true}
							],
							searchitems : [
								{display: 'Email', name : 'email'},
								{display: 'Roles', name : 'roles'},
								{display: 'Nome', name : 'nome', isdefault: true}
							],
							sortname: "id",
							sortorder: "asc",
							usepager: true,
							singleSelect: true,
							title: 'Users',
							useRp: true,
							rp: 15,
							showTableToggleBtn: true,
							width: 950,
							height: 200
						});   
						</script>

Empaquei... :(

Lucas_Cavalcanti

dá uma olhada no firebug pra ver se ele está fazendo a requisição pro lugar certo…

(vc vai precisar de um Firefox, com o plugin firebug instalado, e olhar pra aba console)

Leandro-SP

Lucas Cavalcanti:
dá uma olhada no firebug pra ver se ele está fazendo a requisição pro lugar certo…

(vc vai precisar de um Firefox, com o plugin firebug instalado, e olhar pra aba console)

Consegui um progresso mas acho que ta faltando a implementação do onClick:

Apareceu no firebug…

Não tenho noção de como implementar os 2 onClick.

Lucas_Cavalcanti
buttons : [  
           {name: 'Add', bclass: 'add', onpress : onClick},  
           {name: 'Delete', bclass: 'delete', onpress : onClick},  
           {separator: true}  
],

o problema está aqui…

o que vc quiz dizer com esse onClick?

acho que o que vc precisa fazer é criar uma função pro botão add e uma pro botão delete, e fazer a ação necessária pra cada…

Leandro-SP

Lucas Cavalcanti:
buttons : [ {name: 'Add', bclass: 'add', onpress : onClick}, {name: 'Delete', bclass: 'delete', onpress : onClick}, {separator: true} ],

o problema está aqui…

o que vc quiz dizer com esse onClick?

acho que o que vc precisa fazer é criar uma função pro botão add e uma pro botão delete, e fazer a ação necessária pra cada…

Ae consegui! Funcionou a parte de mostrar os dados no flexigrid… está ok agora.
Agora só falta fazer a parte de Adicionar e Remover dentro do flexigrid…
Alguém tem alguma ideia de como fazer isso ao clicar no botao Adicionar ou Remover?

Lucas_Cavalcanti

no remover vc precisa fazer algo parecido com pegar o id do usuário (algum dos parametros da function deve ser isso) e mandar uma requisição ajax para /usuarios/remove (a url do método remove do seu UsuariosController, ou algo parecido), passando esse id

o adicionar, vc precisa fazer algo como criar uma linha nova no grid com inputs, e o submit criaria um outro cara via ajax…

Leandro-SP

Lucas Cavalcanti:
no remover vc precisa fazer algo parecido com pegar o id do usuário (algum dos parametros da function deve ser isso) e mandar uma requisição ajax para /usuarios/remove (a url do método remove do seu UsuariosController, ou algo parecido), passando esse id

o adicionar, vc precisa fazer algo como criar uma linha nova no grid com inputs, e o submit criaria um outro cara via ajax…

Consegui fazer!

Unico porém:

No firefox está funcionando que é uma beleza… mas no IE8, o Flexigrid não popula. Ele popula somente quando eu clico em alguma coluna ou em algum dos controles de paginação do flexigrid… ja viu isso Lucas Cavalcanti?

Lucas_Cavalcanti

não funcionar no IE8? sempre :wink:

dá uma olhada no site do flexgrid se tem alguma coisa falando sobre isso

Leandro-SP

Funcionou! Tinha um errinho no javascript!!! Obrigado!!!

joander.vieira

Cherubini:
Garcia funciou !!!

Porem flexigrid é um lixo ! Tive que transformar meu json nesse formato

O Flexigrid aceita o segundo json nao o primeiro

{
  "page": 1,
  "total": 1,
  "rows": [
    {
      "id": "1",
      "cell": [
        {
          "id": 1,
          "email": "[email removido]",
          "password": "123456",
          "name": "t",
          "rule": "ADMINISTRATOR"
        }
      ]
    }
  ]
}

//ACEITO PELO FLEXIGRID

{
  "page": 1,
  "total": 1,
  "rows": [
    {
      "id": "1",
      "cell": [
        "1",
        "[email removido]",
        "123456",
        "t",
        "ADMINISTRATOR"
      ]
    }
  ]
}

ai tive que fazer uma gambi para aceitar

@Path("/user.json")
	public void listUsers(){
		List<User> users = userDao.getUserDao().listAll();
		List<FlexigridRow> rows = new ArrayList<FlexigridRow>();
			
			List<String> cell = new ArrayList<String>();
			FlexigridRow row = new FlexigridRow();
			row.setId(users.get(0).getId()+"");
			
			String id = users.get(0).getId()+"";
			String email = users.get(0).getEmail()+"";
			String password = users.get(0).getPassword()+"";
			String name = users.get(0).getName()+"";
			String rule = users.get(0).getRule()+"";
			cell.add(id);
			cell.add(email);
			cell.add(password);
			cell.add(name);
			cell.add(rule);
			
			row.setCell(cell);
			rows.add(row);
		
		FlexiGridJson grid = new FlexiGridJson(1, users.size(), rows);
		result.use(json()).withoutRoot().from(grid).include("rows").include("rows.cell").serialize();   
	}

Vocês não uma maneira mais bonita ?rs

Vlws

Cherubini, como você esta chamando o seu controller ( @Path("/user.json") public void listUsers(){ ) no flexigrid.

O meu não aparece os dados.

Por favor poste ai o seu flexigrid o jsp e o controller.

Criado 15 de julho de 2010
Ultima resposta 24 de set. de 2011
Respostas 36
Participantes 6