JQuery + Vraptor3 + tag select (RESOLVIDO)

77 respostas
ViniciusNaka

Boa tarde pessoal.

Estou tentando fazer uma ordenação de lista, onde é carregada inicialmente uma lista de funcionários e caso eu selecione um departamento no select ele exibe só os funcionários daquele depto.

A minha ideia é a seguinte, tenho dois <c:foreach>…

esse chama tds os funcionarios…

c:forEach var="funcionario" items="${funcionarioList}">
											<tr id="func">
												<td id="id_func" style="display: none;">${funcionario.idFuncionario}</td>
												<td id="nome_func">${funcionario.nome}</td>
												<td id="email_func">${funcionario.email}</td>
												<c:choose>
													<c:when test="${funcionario.tipoFuncionario == true}">
														<td id="descricao" align="center">Sim</td>
													</c:when>
													<c:otherwise>
														<td id="descricao" align="center">Não</td>
													</c:otherwise>
												</c:choose>
												<td id="depto_func">${funcionario.depto}</td>
												<td><a
													href="<c:url value="/funcionarios/${funcionario.idFuncionario}" />">
														Editar </a></td>
												<td>
													<form
														action="<c:url value="/funcionarios/${funcionario.idFuncionario}"/>"
														method="post"">
														<button class="link" name="_method" value="DELETE">Excluir</button>
													</form></td>
											</tr>
									</c:forEach>

Esse chama só os funcionários do departamento…

<c:forEach var="funcionario" items="${funcionariosDepto}"> // nao sei se no items esta chamando corretamente o metodo do controller
											<tr id="func">
												<td id="id_func" style="display: none;">${funcionario.idFuncionario}</td>
												<td id="nome_func">${funcionario.nome}</td>
												<td id="email_func">${funcionario.email}</td>
												<c:choose>
													<c:when test="${funcionario.tipoFuncionario == true}">
														<td id="descricao" align="center">Sim</td>
													</c:when>
													<c:otherwise>
														<td id="descricao" align="center">Não</td>
													</c:otherwise>
												</c:choose>
												<td id="depto_func">${funcionario.depto}</td>
												<td><a
													href="<c:url value="/funcionarios/${funcionario.idFuncionario}" />">
														Editar </a></td>
												<td>
													<form
														action="<c:url value="/funcionarios/${funcionario.idFuncionario}"/>"
														method="post"">
														<button class="link" name="_method" value="DELETE">Excluir</button>
													</form></td>
											</tr>
									</c:forEach>

esse do depto esta display: none, pois quero que apareça somente quando selecionarem um depto, ai eu exibiria ele e esconderia o outro…

meu método do controller…

// METODO QUE LISTA TODOS OS FUNCIONARIOS POR DEPARTAMENTO
	@Get
	@Path("/funcionarios/depto/{depto}")
	public List<Funcionario> getFuncionariosDepto(String depto){
		List<Funcionario> funcionarios = dao.listarFuncDeptos(depto);		
		return funcionarios;
	}

o jquery que estou usando…

// Exibe a lista de funcionários por departamento
	$(function(){			
	 ("#sel_depto").change(function(){
	 	exibirListaDepto();}).change();		
	});
	
	function exibirListaDepto(){
		var depto = $("#sel_depto").val();
		if (depto != null) {
			$.get('/funcionarios/depto/', depto);
			$("#tr_list_all").hide();
			$("#tr_list_depto").show();
		}
		else {
			$("#tr_list_all").show();
			$("#tr_list_depto").hide();
		}
	}

Como que eu faço para chamar meu FuncionarioController pelo jQuery?

Bom, tentei ser o mais claro possível hehe… me desculpem pela minha inexperiência hehe

Obrigado pela ajuda desde já.

Abs

77 Respostas

P

Veja no final do post http://www.guj.com.br/java/236884-resolvido-receber-json-no-vraptor-3

Lucas_Cavalcanti

leia a apostila do FJ-28 como o pbnf falou, mas resumindo vc usaria algo do tipo:

$.getJSON('/funcionarios/depto/', depto, function(json) {
   //trata o retorno
});

e no controller retornar a lista de funcionarios em json.

ViniciusNaka

é pela apostila FJ-28 mesmo que estou estudando :smiley:

então, quando seleciono um depto no select ele nao ta chamando certo meu jQuery… :frowning:

<select id="sel_depto">
	<option> Selecione... </option>
	<option value="GAS"> GAS </option>													
</select>
// Exibe a lista de funcionários por departamento
	$(function(){			
	 ("#sel_depto").change(function(){
	 	window.alert("esta chamando");
	 	exibirListaDepto();}).change();		
	});
	
	function exibirListaDepto(){
		var depto = $("#sel_depto").val();
		if (depto != null) {
			$.get('/funcionarios/depto/', depto, function(json){				
				$("#tr_list_all").hide();
				$("#tr_list_depto").show();	
			});			
		}
		else {
			$("#tr_list_all").show();
			$("#tr_list_depto").hide();
		}
	}
Lucas_Cavalcanti

faltando um $ na segunda linha:

$("#sel_depto").change(function(){
ViniciusNaka

mesmo assim, nem chega no alert…

$(function(){					
	 $("#sel_depto").change(function(){
	 	window.alert("esta chamando");
	 	exibirListaDepto();}).change();		
	});

não seria algo errado no meu select?

abs

Lucas_Cavalcanti

acho que chamar o .change() do final não vai funcionar…

vc pode extrair a função:

$(function(){
    exibirListaDepto();
    $("#sel_depto").change(exibirListaDepto);
});
ViniciusNaka

opa… voltei a mexer com isso só hj hehe…

então, eu dei uma lida nesse tópico… http://www.guj.com.br/java/213443-resolvido-checkbox-dinamico-com-javascript-e-vraptor-3/4

daí mudei meu jquery, chamando ele pelo onchange no meu select…

function popularFuncDeptos(){
		var sigla = $("#sel_depto").val();
		window.alert(sigla); // coloquei so para ver se esta pegando certo o valor do select
		$.get('/ReconhecimentoNew/funcionario/depto/', 
			{'departamento.sigla' : sigla},
			function(data){
			$("#tr_list_all").hide();
			$("#tr_list_depto").show();
		});		
	}

mas qndo chega no meu controller, esta null…

@Get
	@Path("/funcionario/depto/{departamento.sigla}")
	public void listFuncionariosDepto(String sigla){
		if(sigla == null){
			result.redirectTo(this).listar();
		} else {
			Integer idDepto = departamentoDAO.listarFuncDeptos(sigla);
			result.include("funcDeptos", dao.listarFuncDeptos(idDepto));
		}		
	}

alguém sabe o que estou fazendo de errado?

Lucas_Cavalcanti

bom, vc quer que a sigla fique na url, como está configurado no controller?

se sim, o nome do parâmetro no @Path tem que ser sigla (a menos que vc receba um Departamento ao invés da String)

@Path("/funcionario/depto/{sigla}")

e no javascript vc tem que passar o parâmetro na url:

$.get('/ReconhecimentoNew/funcionario/depto/' + sigla,  
        function(data){
ViniciusNaka

bom dia Lucas…

obrigado, agora funcionou. Estou recebendo a string no meu método, mas pelo jeito o restante da function não executa, pois não some a linha e tb não aparece a outra :frowning:

function popularFuncDeptos(){
		var sigla = $("#sel_depto").val();
		window.alert(sigla);
		$.get('/ReconhecimentoNew/funcionario/depto/' + sigla,			
			function(data){
			$("#tr_list_all").hide();
			$("#tr_list_depto").show();
		});		
	}
Lucas_Cavalcanti

pôe um alert(‘passei aqui’) dentro da function e vê se ele aparece.

dá uma olhada no firebug (uma ext do firefox) pra ver se dá algum erro no javascript

ViniciusNaka

Coloquei 2 alerts…

function popularFuncDeptos(){
		var sigla = $("#sel_depto").val();
		window.alert(sigla);
		$.get('/ReconhecimentoNew/funcionario/depto/' + sigla,			
			function(data){
			window.alert("inicio");
			$("#tr_list_all").hide();
			$("#tr_list_depto").show();
			window.alert("fim");
		});		
	}

os alerts funcionam, porém, não funciona o hide nem o show :frowning:

vou colocar meus métodos abaixo para ver se é algo errado neles…

controller…

@Get
	@AccessLevel(maximumAccessLevel=1, minimumAccessLevel = 0)
	@OnAccessDenial
	@Path("/funcionario/depto/{sigla}")
	public void listFuncionariosDepto(String sigla){
		if(sigla == null){
			result.redirectTo(this).listar();
		} else {
			this.idDepto = departamentoDAO.listarFuncDeptos(sigla);
			result.redirectTo(this).listar();		
		}		
	}

método listar… o idDepto é uma variavel que criei no controller…

@Get
	@AccessLevel(maximumAccessLevel=1, minimumAccessLevel = 0)
	@Path("/funcionario/listar")
	@OnAccessDenial
	public void listar(){
		if(this.idDepto == null){
			result.include("departamentoList", departamentoDAO.listar());
			result.include("listarFuncionarios", dao.listar());
		} else {			
			result.include("listarFuncDepto", dao.listarFuncDeptos(this.idDepto));
		}		
	}

ah, eu debuguei pelo firebug e nada de erro de script :frowning:

Lucas_Cavalcanti

se os alerts estão funcionando o problema é no javascript…

existe algum elemento com o id tr_list_all e tr_list_depto?

ViniciusNaka

seguem as tr’s…

<tr id="tr_list_all">
									<td colspan="5">									
									<c:forEach var="funcionario" items="${listarFuncionarios}">
											<tr id="func">
												<td id="id_func" style="display: none;">${funcionario.idFuncionario}</td>
												<td id="nome_func">${funcionario.nome}</td>
												<td id="email_func">${funcionario.email}</td>
												<c:choose>
													<c:when test="${funcionario.tipoFuncionario == true}">
														<td id="descricao" align="center">Sim</td>
													</c:when>
													<c:otherwise>
														<td id="descricao" align="center">Não</td>
													</c:otherwise>
												</c:choose>
												<td id="depto_func">${funcionario.depto.sigla}</td>
												<td><a
													href="<c:url value="/funcionarios/editar/${funcionario.idFuncionario}" />">
														Editar </a></td>
												<td>
													<form
														action="<c:url value="/funcionarios/excluir/${funcionario.idFuncionario}"/>"
														method="post"">
														<button class="link" name="_method" value="DELETE">Excluir</button>
													</form></td>
											</tr>
									</c:forEach>
									</td>
								</tr>
								<tr id="tr_list_depto" style="display: none;">
									<td colspan="5">
									<c:forEach var="funcionario" items="${listarFuncDepto}">
											<tr id="func">
												<td id="id_func" style="display: none;">${funcionario.idFuncionario}</td>
												<td id="nome_func">${funcionario.nome}</td>
												<td id="email_func">${funcionario.email}</td>
												<c:choose>
													<c:when test="${funcionario.tipoFuncionario == true}">
														<td id="descricao" align="center">Sim</td>
													</c:when>
													<c:otherwise>
														<td id="descricao" align="center">Não</td>
													</c:otherwise>
												</c:choose>
												<td id="depto_func">${funcionario.depto}</td>
												<td><a
													href="<c:url value="/funcionarios/editar/${funcionario.idFuncionario}" />">
														Editar </a></td>
												<td>
													<form
														action="<c:url value="/funcionarios/excluir/${funcionario.idFuncionario}"/>"
														method="post"">
														<button class="link" name="_method" value="DELETE">Excluir</button>
													</form></td>
											</tr>
									</c:forEach>									 
									</td>
								</tr>
Lucas_Cavalcanti

se vc executar as linhas no console do firebug acontece algo?

$("#tr_list_all").hide();  
            $("#tr_list_depto").show();
ViniciusNaka

Bom dia Lucas, ao executar esses scripts, aparece isso no console…

ViniciusNaka

criei uma div de teste e coloquei para escondê-la… daí funcionou…
deve ser algo nas minhas tr’s :frowning: que não esta deixando escondê-la…

Lucas_Cavalcanti

sim, o problema é com os trs mesmo, mas deveria funcionar o show e o hide…

tenta no console do firebug digitar só $(’#tr_list_all’) e ver se ele seleciona algum elemento

ViniciusNaka

bom, mudei meu html e deixei duas tabelas ao invés de trs…agora esta escondendo e aparecendo a outra, porém, ela aparece vazia…

tentei usando 2 métodos no controller…

esse recebe a sigla do depto…

@Get
	@AccessLevel(maximumAccessLevel=1, minimumAccessLevel = 0)
	@OnAccessDenial
	@Path("/funcionario/depto/{sigla}")
	public void listFuncionariosDepto(String sigla){
		int idDepto = 0;
		if(sigla == null){
			result.redirectTo(this).listar(idDepto);
		} else {
			idDepto = departamentoDAO.listarFuncDeptos(sigla);
			result.redirectTo(this).listar(idDepto);		
		}		
	}

e redireciona para esse…

@Get
	@AccessLevel(maximumAccessLevel=1, minimumAccessLevel = 0)
	@Path("/funcionario/listar")
	@OnAccessDenial
	public void listar(int idDepto){
		result.include("departamentoList", departamentoDAO.listar());
		if(idDepto == 0){
			result.include("listarFuncionarios", dao.listar());
		} else {			
			result.include("listarFuncDepto", dao.listarFuncDeptos(idDepto));
		}		
	}

mas aparece a tabela fazia :frowning:

tentei deixar só este método…

// METODO QUE LISTA TODOS OS FUNCIONARIOS POR DEPARTAMENTO
	@Get
	@AccessLevel(maximumAccessLevel=1, minimumAccessLevel = 0)
	@OnAccessDenial
	@Path("/funcionario/depto/{sigla}")
	public void listFuncionariosDepto(String sigla){
		if(sigla == null){
			result.redirectTo(this).listar(idDepto);
		} else {
			int idDepto = departamentoDAO.listarFuncDeptos(sigla);			
			result.include("listarFuncDepto", dao.listarFuncDeptos(idDepto));		
		}		
	}

mas nao chega nem executar a linha do script hide()

Lucas_Cavalcanti

o problema não é no java, é no html+javascript

ViniciusNaka

é, verifiquei no console a resposta e aparece certinho a lista com os funcionarios do depto que eu seleciono no select, mas na tela nada… :frowning:

Lucas_Cavalcanti

tenta dar uma olhada no jQuery, aprender melhor como ele funciona…

o problema está nele

ViniciusNaka

to estudando sobre jQuery…

comecei a mexer com minha function agora pouco…

até o momento esta assim…

function popularFuncDeptos(){
		var sigla = $("#sel_depto").val();
		alert(sigla);
		$.get('/ReconhecimentoNew/funcionario/depto/' + sigla,			
			function(funcDeptos){
			var teste = $(funcDeptos).find("#table_list_depto").html();
			alert(teste);
			$("#table_list_all").hide();
			$("#mostra_tabela").show(teste);						
		});		
	}

eu pego o retorno, daí seleciono só a parte da table com os dados que esta escondida (teste) mas ao mandar exibir não aparece :frowning:
ja tentei criando uma div e usando o .show(teste), .load(teste), .html(teste) e nada de aparecer :frowning:

ViniciusNaka

funcionou, mas somente no chrome e firefox, no ie não aparece a tabela :frowning:

a function ficou assim…

function popularFuncDeptos(){
		var sigla = $("#sel_depto").val();
		alert(sigla);
		$.get('/ReconhecimentoNew/funcionario/depto/' + sigla,			
			function(funcDeptos){
			var teste = $(funcDeptos).find("#table_list_depto").html();
			alert(teste);
			$("#table_list_all").hide();
			$("#mostra_tabela").html(teste);						
		});		
	}
Lucas_Cavalcanti

bom, uma dica pra facilitar sua vida: pare de usar tabelas…

use div’s e li’s sempre que possível. Use tabelas só pra coisas que são tabelas de verdade.

cada browser trata tabelas de um jeito, por isso que dá pau

ViniciusNaka

Valeu Lucas… mas eu evito tb usar tabelas, só nesse caso de listagem que acho que fica mais alinhado.
Fiz um teste e tirei as tabelas, mas mesmo com div, p e label acontece a mesma coisa no ie :frowning:

Lucas_Cavalcanti

o hide() e o show() do jQuery funcionam normalmente no IE…

tenta isolar esse hide e show num contexto menor e ver se estão funcionando (por exemplo no click de um botão ou um link). O problema pode estar em outra parte do javascript (se dá algum erro o browser para de executar o JS)

ViniciusNaka

pelo que testei o .hide() e o .show() funcionam, pois eu coloquei uma borda de cor diferente para destacar as tabelas, mas o que esta acontecendo é o seguinte…

no chrome e ff qndo chega no alert do teste ele exibe os dados da tabela, mas no ie só exibe o comentário…

<table id="table_list_depto" style="display: none; border-style: solid; border-color: green; width: 100%;">
								<!-- Loop FOR para exibir os funcionarios --> //  exibe essa linha
								<c:forEach var="funcionario" items="${listarFuncDepto}">
									<tr>
										<td id="id_func" style="display: none;">${funcionario.idFuncionario}</td>
										<td id="nome_func">${funcionario.nome}</td>
										<td id="email_func">${funcionario.email}</td>
										<c:choose>
											<c:when test="${funcionario.tipoFuncionario == true}">
												<td id="descricao" align="center">Sim</td>
											</c:when>
											<c:otherwise>
												<td id="descricao" align="center">Não</td>
											</c:otherwise>
										</c:choose>
										<td id="depto_func">${funcionario.depto.sigla}</td>
										<td><a
											href="<c:url value="/funcionario/editar/${funcionario.idFuncionario}" />">
												Editar </a>
										</td>
										<td>
											<form
												action="<c:url value="/funcionario/excluir/${funcionario.idFuncionario}"/>"
												method="post"">
												<button class="link" name="_method" value="DELETE">Excluir</button>
											</form>
										</td>
									</tr>
								</c:forEach>
							</table>

pelo jeito ele não pega o retorno

Lucas_Cavalcanti

em que lugar tá dando esse erro?

ViniciusNaka

minha function atualmente… ele nao da erro somente a observacao que coloquei no alert

function popularFuncDeptos(){
		var sigla = $("#sel_depto").val();
		//alert(sigla);
		if(sigla != "all"){ // esse if eu fiz para exibir tds
			$.get('/ReconhecimentoNew/funcionario/depto/' + sigla,			
				function(funcDeptos){
				var teste = $(funcDeptos).find("#table_list_depto").html();
				alert(teste); // aqui exibe somente aquele comentario no ie e depois aparece a tabela vazia, no chrome e ff exibe os dados corretamente
				$("#table_list_all").hide();
				$("#table_list_depto").show().html(teste);
			});						
		} else {
			$("#table_list_depto").hide();
			$("#table_list_all").show();				
		}				
	}
Lucas_Cavalcanti

dê um alert(funcDeptos)

ViniciusNaka

hmm desculpe lucas, falei errado no outro post, ele deve estar pegando errado o trecho “teste” do retorno…

function popularFuncDeptos(){  
    var sigla = $("#sel_depto").val();  
    //alert(sigla);  
    if(sigla != "all"){ // esse if eu fiz para exibir tds  
        $.get('/ReconhecimentoNew/funcionario/depto/' + sigla,            
            function(funcDeptos){  
            var teste = $(funcDeptos).find("#table_list_depto").html();  // aqui eu acredito que devo tratar diferente para o ie
            alert(teste); 
            $("#table_list_all").hide();  
            $("#table_list_depto").show().html(teste);  
        });                       
    } else {  
        $("#table_list_depto").hide();  
        $("#table_list_all").show();                  
    }                 
}
Lucas_Cavalcanti

pedi pra fazer o alert pra ver se o html tá vindo completo no ie

ViniciusNaka

o html vem certinho lucas.

Lucas_Cavalcanti

o problema deve ser vc estar usando ids… qdo vc cria o $(html) ele cria o html no DOM, e se vc tem ids repetidos ferra o seletor do jquery (em alguns casos)…

mas vc pode, contudo, fazer isso:

$("#table_list_depto").load('/ReconhecimentoNew/funcionario/depto/' + sigla + ' #table_list_depto', //note o espaço             
            function(){    
            
            $("#table_list_all").hide();    
            $(this).show()
        });

mais docs em: http://api.jquery.com/load/ Load page fragments

ViniciusNaka

bom dia Lucas…

tentei da forma que vc sugeriu, tentei de outras formas tb e nada de funcionar no ie :frowning:

Lucas_Cavalcanti

deveria funcionar sim, pelo menos se o id do elemento que vc passou foi uma div…

vc usou o load mesmo?

ViniciusNaka

sim usei o load mesmo

function popularFuncDeptos(){
		var sigla = $("#sel_depto").val();
		if(sigla != "all"){		
		$("#list_depto").load('/ReconhecimentoNew/funcionario/depto/' +sigla+ ' #list_depto',
				function(){
			alert("Load: "+$(this).html());
			$("#list_all").hide();
			$("#list_depto").show();				
		});
		} else {
			$("#list_depto").hide();
			$("#list_all").show();				
		}	
	
	}

ah, eu tirei ate as tabelas e deixei em div’s hehe

Lucas_Cavalcanti

no FF e no chrome isso funciona?

faça o seguinte:

if (sigla != "all") { alert("!!!!");}

o alert aparece?

dá uma olhada no developer tools do IE (F12) e veja se a requisição foi feita

ViniciusNaka

dessa forma nao funciona em nenhum browser…

o alert “Load” depois do function já aparece com o html certinho, mas exibe somente a div fazia.

function popularFuncDeptos(){  
    var sigla = $("#sel_depto").val();  
    if(sigla != "all"){       
    $("#list_depto").load('/ReconhecimentoNew/funcionario/depto/' +sigla+ ' #list_depto',  
            function(){  
        alert("Load: "+$(this).html());  
        $("#list_all").hide();  
        $("#list_depto").show();                  
    });  
    } else {  
        $("#list_depto").hide();  
        $("#list_all").show();                
    }     
  
}

para ver se a requisição foi feita é no console igual ao ff? se for não aparece nada

Lucas_Cavalcanti

ah… tem que ver se o $(this) é a div mesmo…

de qqer forma, vc consegue ver a resposta que o servidor mandou no developer tools do IE? (F12)

ViniciusNaka

o $(this) é a div mesmo, aparece um bom pedaço do html no alert…

entao, eu acesso o developer tools, coloco um breakpoint, debugo ele executa td e nao aparece nada no console

Lucas_Cavalcanti

tenta dar um inspect nessa div, depois que o load foi feito, e ver se na árvore de objetos os dados estão lá

ViniciusNaka

o que estava acontecendo… ele incluia a div id=“list_depto” dentro dela mesma, duplicando-a, depois da function ela exibia somente a de dentro e a de fora ficava display none… inclui outra div dentro dela “list_depto2” como teste e mudei a function…

$("#list_depto").load('/ReconhecimentoNew/funcionario/depto/' +sigla+ ' #list_depto2',

mesmo assim, dei um inspect e os dados não são carregados no ie, mas agora aparecem nos outros dois browsers…

Lucas_Cavalcanti

mas os dados ficam na árvore de componentes no ie, pelo menos?

ViniciusNaka

não… consta assim…

<div id="list_depto" style="border-bottom-style: solid; border-bottom-color: green; border-right-style: solid; border-top-color: green; width: 100%; border-top-style: solid; border-right-color: green; border-left-style: solid; border-left-color: green;">
<div id="list_depto2"/> // aqui deveria carregar os dados
Lucas_Cavalcanti

a resposta da requisição tem uma div id=#list_depto2 ? dentro dessa div tem o conteúdo que vc quer?

ViniciusNaka

a resposta tem a div fechada sem os dados…

<div id="list_depto" style="border-bottom-style: solid; border-bottom-color: green; border-right-style: solid; border-top-color: green; width: 100%; border-top-style: solid; border-right-color: green; border-left-style: solid; border-left-color: green;">  
<div id="list_depto2"/> // aqui deveria carregar os dados

no ff e chrome os dados são carregados

Lucas_Cavalcanti

então o código do load tá errado…

o código certo é:

$('#id_da_div_onde_os_dados_serao_colocados').load('/url/marota #id_da_div_que_contem_os_dados_na_resposta');
ViniciusNaka

alterei meu html e a function…

function popularFuncDeptos(){
		var sigla = $("#sel_depto").val();
		if(sigla != "all"){		
		        $("#listas").load('/ReconhecimentoNew/funcionario/depto/' +sigla+ ' #list_depto',
				function(){			
			$("#list_all").hide();
			$("#list_depto").show();
		});
		} else {	
			$("#listas").load('/ReconhecimentoNew/funcionario/depto/' +sigla+ ' #list_all',
					function(){			
			$("#list_depto").hide();
			$("#list_all").show();
			});
		}

mas ainda nada de aparecer no ie os dados :cry:

Lucas_Cavalcanti

a div #listas fica vazia no ie, mas a resposta do load contém a div #list_depto ?

ViniciusNaka

fica assim…

<div id="listas" style="width: 650px; height: 600px;">
      <div id="list_depto" style="border-bottom-style: solid; border-bottom-color: green; border-right-style: solid; border-top-color: green; width: 100%; border-top-style:          solid; border-right-color: green; border-left-style: solid; border-left-color: green;"/> //repare que a tag aparece fechada e sem nenhum dado
</div>
Lucas_Cavalcanti

e no corpo da resposta tem algum dado na div list_depto?

ViniciusNaka

Opa, voltei a mexer com isso de novo hehe…
eu dei uma lida nisso…

http://www.wbotelhos.com.br/2010/01/20/manipulando-dados-json-via-ajax-com-vraptor-3/

não conhecia JSON, daí dei uma estudadinha hehe… até ja usei para uma outra atividade aqui, mas nessa listagem ele vem o retorno bonitinho dos objetos, mas qndo dou um alert, no console do firebug aparece que “is undefined”.

meu controller…

@Get
	@AccessLevel(maximumAccessLevel=1, minimumAccessLevel = 0)
	@Path("/funcionario/listar")
	@OnAccessDenial
	public void listar(int idDepto){
		result.include("departamentoList", departamentoDAO.listar());
		if(idDepto == 0){
			result.include("listarFuncionarios", funcionarioDAO.listar());
		} else {						
			List<Funcionario> funcionarios = funcionarioDAO.listarFuncDeptos(idDepto);
			result.use(json()).from(funcionarios).include("depto").include("usuario").serialize();
		}		
	}

meu método JSON…

function popularFuncDeptos(){
		var sigla = $("#sel_depto").val();
		if(sigla != "all"){
			$.getJSON('/Reconhecimento/funcionario/depto/' + sigla,
				function(json){
				alert("Ver o json no console");
				$(json).each(function(){
					alert(json.funcionario.nome); //coloquei somente para exibir um dado para ver como pega-lo e joga-lo no meu html
					alert(json.funcionario.email);					
				});
			});		
	        }	
	}

já tentei de várias formas, mas nada :frowning:
para ajudar o retorno vem assim…

Object { idFuncionario=82, nome="Vinicius Nakayama", more...}
	
depto
	Object { idDepto=1, nome="Gerência de Apoio ao Suporte", sigla="GAS"}
	
idDepto
	1
	
nome
	"Gerência de Apoio ao Suporte"
	
sigla
	"GAS"
	
email
	"[email removido]"
	
idFuncionario
	82
	
nome
	"Vinicius Nakayama"
	
tipoFuncionario
	true
	
usuario
	Object { @class="usuario_$$_javassist_4", @resolves-to="usuario", more...}
	
@class
	"usuario_$$_javassist_4"
	
@resolves-to
	"usuario"
	
idUsuario
	3
	
login
	"vinicius"
	
nome
	"Vinicius Nakayama"
	
perfil
	"0"
	
senha
	"yFUIvUnS7oueFcTuU74n0Q=="
Lucas_Cavalcanti

a url que vc está usando no $.getJSON é diferente da que vc tá usando no @Path, é isso mesmo?

ViniciusNaka

me desculpe Lucas, é que antes ele chama esse método…

@Get
	@AccessLevel(maximumAccessLevel=1, minimumAccessLevel = 0)
	@OnAccessDenial
	@Path("/funcionario/depto/{sigla}")
	public void listFuncionariosDepto(String sigla){
		int idDepto = 0;
		if(sigla.equals("all") || sigla.equals(null)){
			result.redirectTo(this).listar(idDepto);
		} else {
			idDepto = departamentoDAO.getIdDepto(sigla);
			result.redirectTo(this).listar(idDepto);		
		}		
	}
Lucas_Cavalcanti

tente fazer sem passar por um redirect e ver se funciona

ViniciusNaka

tentei sem o redirect…

@Get
	@AccessLevel(maximumAccessLevel=1, minimumAccessLevel = 0)
	@OnAccessDenial
	@Path("/funcionario/depto/{sigla}")
	public void listFuncionariosDepto(String sigla){
		int idDepto = 0;
		result.include("departamentoList", departamentoDAO.listar());		
		if(sigla.equals("all") || sigla.equals(null)){
			result.include("listarFuncionarios", funcionarioDAO.listar());
		} else {
			idDepto = departamentoDAO.getIdDepto(sigla);
			List<Funcionario> funcionarios = funcionarioDAO.listarFuncDeptos(idDepto);
			result.use(json()).from(funcionarios).include("depto").include("usuario").serialize();
		}				
	}

e mesma coisa :frowning:

um print da tela…

Lucas_Cavalcanti

ah tah, vc tá serializando uma lista de funcionarios

faça o seguinte:

mude o controller para:

result.use(json()).withoutRoot().from(funcionarios)....

assim o json já fica direto com a lista de funcionarios

e o javascript para:

$.getJSON('/Reconhecimento/funcionario/depto/' + sigla,  
            function(funcionarios){  
            
            $(funcionarios).each(function(){  
               //aqui o this é um funcionario
                this.nome
                this.idFuncionario
                //...                    
            });  
        });

isso deve funcionar, até com o redirect

não tinha funcionado antes pq o json q o vraptor gera (sem o withoutRoot)

{'list':[
  {'idFuncionario': 123, 'nome': "joao".....},
  {'idFuncionario': 123, 'nome': "joao".....},
   ....
]}

então pra acessar seria json.list

ViniciusNaka

fiz do jeito que vc disse, ate ai blz, mas na hora de exibir no html estou tentando assim…

function popularFuncDeptos(){
	var sigla = $("#sel_depto").val();
	if(sigla != "all"){
	$.getJSON('/Reconhecimento/funcionario/depto/' + sigla,
		function(funcionarios){
			$(funcionarios).each(function(){
				$("#list_all").hide();				
				$('<p>');
					$('<label>').val(this.idFuncionario).hide();
					$('</label>');
					$('<label>').val(this.nome);
					$('</label>');
					$('<label>').val(this.email);
					$('</label>');
					if(this.tipoFuncionario==true){
						$('<label>Sim</label>');						 
					} else {
						$('<label>Não</label>'); 
					}
					$('<label>').val(this.depto.sigla);
					$('</label>');				
				$('</p>');
			}).appendTo('#list_depto');
			$("#list_depto").show();
		});		
		}	
	}

teria uma outra maneira de mostrar no html ?
ja tentei deixar o $("#list_depto").show(); antes do each ou o $("#list_all").hide(); depois do each, mas nada :frowning:

abaixo um print do erro…

Lucas_Cavalcanti

vc não precisa fazer as tags de fechamento…

um dos jeitos de gerar o html é assim:

$('<p>')
   .append($('<label>').html(this.idFuncionario).hide())  
   .append($('<label>').html(this.nome))  
   .append($('<label>').html(this.email))  
   .append($('<label>').html(this.tipoFuncionario==true ? 'Sim' : 'Não'))   
   .append($('<label>').html(this.depto.sigla))  
   .appendTo($('algum elemento aqui'));

ou seja, o $(’’) já cria a tag com abre e fecha, o append coloca elementos lá dentro e o html muda todo o conteúdo de dentro da tag (ou pega ele se vc não passar nenhum argumento). E vc precisa do appendTo pra colocar esse p que vc criou em algum lugar (uma div por exemplo).

o val só serve pra formulário (inputs, selects e textareas)

[]'s

ViniciusNaka

obrigado lucas!! funcionou!! :slight_smile:

function popularFuncDeptos(){
	var sigla = $("#sel_depto").val();
	if(sigla != "all"){
	$.getJSON('/Reconhecimento/funcionario/depto/' + sigla,
		function(funcionarios){
			$("#list_all").hide();
			$("#list_depto").hide();
			$("#list_depto").empty();
			$(funcionarios).each(function(){							
				$('<p>')
					.append($('<label>').html(this.idFuncionario).hide())
					.append($('<label>').html(this.nome))
					.append($('<label>').html(this.email))
					.append($('<label>').html(this.tipoFuncionario==true ? 'Sim' : 'Não'))
					.append($('<label>').html(this.depto.sigla))					
					.append($('<a href="<c:url value="/funcionario/editar/${funcionario.idFuncionario}" />">Editar </a> </label>'))
					.appendTo('#list_depto');
			});					
			$("#list_depto").show();
		});		
	} else {
		$("#list_depto").hide();
		$("#list_all").show();
	}	
}

só mais uma dúvida hehe… eu tenho a classe usuarioLogado…

@Component
@SessionScoped
public class UsuarioLogado {

	private Usuario usuarioLogado;
	
	public Usuario getUsuarioLogado() {
		return usuarioLogado;
	}	
	public void setUsuarioLogado(Usuario usuarioLogado) {
		this.usuarioLogado = usuarioLogado;
	}
	public Perfil getPerfil(){
		Perfil perfil = new Perfil();
		if(this.usuarioLogado != null){
			perfil.setLoggedIn(true); //como o usuário corrente não é nulo, significa que ele está logado
			if(this.usuarioLogado.getPerfil() == '1'){ //verifica se é gestor e setta true no nivel de acesso
				perfil.setAccessLevel(1);
			} 			
		}
		return perfil;
	}
	
	public void login(Usuario usuario) {
		this.usuarioLogado = usuario;
	}

	public String getNome(){
		return usuarioLogado.getNome();
	}
	
	public char getPerfilLogin(){
		return this.usuarioLogado.getPerfil();
	}
	
	public boolean isLogado(){
		return usuarioLogado != null;
	}
	
	public void logout(){
		this.usuarioLogado = null;
	}
}

Gostaria de validar uma coisa… se o tipo de usuario logado(usuarioLogado.perfilLogin == ‘0’) for = 0 eu exibo o botao excluir, se nao somente o editar. No html eu consegui fazer mas aqui na function não :frowning:
eu chamei o UsuarioLogado no meu controller, e dou um result para serializar o objeto, igualzinho como faço para os funcionarios mas sem o withoutRoot(), porém, nao esta funcionando na hora de exibir ele

Lucas_Cavalcanti

por padrão ele serializa os attributos, ele não usa os getters…

se vc só quer saber se o usuário tá logado ou não, vc pode responder só “logado” ou “deslogado”, ou algo do tipo…

pra isso vc pode usar o result.use(http()).body(“logado”)

ViniciusNaka

hmmm…
Lucas, voltando um pouco sobre a listagem hehe… no meu jQuery quero add no final de cada linha o “” para edição do mesmo…

function popularFuncDeptos(){  
    var sigla = $("#sel_depto").val();  
    if(sigla != "all"){  
    $.getJSON('/Reconhecimento/funcionario/depto/' + sigla,  
        function(funcionarios){  
            $("#list_all").hide();  
            $("#list_depto").hide();  
            $("#list_depto").empty();  
            $(funcionarios).each(function(){                              
                $('<p>')  
                    .append($('<label>').html(this.idFuncionario).hide())  
                    .append($('<label>').html(this.nome))  
                    .append($('<label>').html(this.email))  
                    .append($('<label>').html(this.tipoFuncionario==true ? 'Sim' : 'Não'))  
                    .append($('<label>').html(this.depto.sigla))                    
                    .append($('<a href="<c:url value="/funcionario/editar/${funcionario.idFuncionario}" />">Editar </a> </label>'))  //isso aqui nao funciona, aparece somente />
                    .appendTo('#list_depto');  
            });                   
            $("#list_depto").show();  
        });       
    } else {  
        $("#list_depto").hide();  
        $("#list_all").show();  
    }     
}

vc sabe se tem como eu fazer isso pelo jQuery?

Lucas_Cavalcanti

se essa function estiver dentro de um .js não vai funcionar o <c:url…

tem vários jeitos de resolver isso:

  • colocar essa função direto no jsp (não mto legal)
  • criar uma variável javascript no head do seu template que vai passar em todas as telas:
<html>
   <head>
       ...
      <script type="text/javascript">
          var context = '<c:url value="/" />';
      </script>
   </head>

e usar essa variável nos js

<a id="editarFuncionario" href="<c:url value="/funcionario/editar/"/>">Editar</a>

e no js

var a = $('#editarFuncionario').clone();
a.attr('href', a.attr('href') + idFuncionario).

...append(a)

enfim, e mais mtos outros jeitos

ViniciusNaka

Muito Obrigado Lucas pelas dicas!!

ficou dessa forma minha function…

function popularFuncDeptos(){    
    var sigla = $("#sel_depto").val();    
    if(sigla != "all"){    
    $.getJSON('/Reconhecimento/funcionario/depto/' + sigla,    
        function(funcionarios){    
            $("#list_all").hide();    
            $("#list_depto").hide();    
            $("#list_depto").empty();    
            $(funcionarios).each(function(){
            var a = $('#editarFuncionario').clone();
	    var href = a.attr('href');
	    var hrefNumber = href.lastIndexOf("/");
	    var hrefNew = href.substring(0, hrefNumber);  // usei lastIndexOf e substring (nao pesquisei se em jQuery da pra fazer de uma forma mais simples)                 
                $('<p>')    
                    .append($('<label>').html(this.idFuncionario).hide())    
                    .append($('<label>').html(this.nome))    
                    .append($('<label>').html(this.email))    
                    .append($('<label>').html(this.tipoFuncionario==true ? 'Sim' : 'Não'))    
                    .append($('<label>').html(this.depto.sigla))
                    .append($('<label>'))  
                    .append(a.attr('href', hrefNew.concat('/'+this.idFuncionario)))                    
                    .appendTo('#list_depto');    
            });                     
            $("#list_depto").show();    
        });         
    } else {    
        $("#list_depto").hide();    
        $("#list_all").show();    
    }       
}
ViniciusNaka

Voltando a esse tópico hehe… reparei somente hoje que a parte do clone() não funciona no IE. Na hora que carrega a lista o que foi clonado não aparece :frowning:
Pesquisei na net e tentei usar o cloneNode(true), mas daí teria q mudar quase toda a estrutura da minha function porque se não da erro nos append e na hora de colocar o id corretamente… resumindo essa parte eu teria q refazer…

$(funcionarios).each(function(){  
            var a = $('#editarFuncionario').clone();  
        var href = a.attr('href');  
        var hrefNumber = href.lastIndexOf("/");  
        var hrefNew = href.substring(0, hrefNumber);  // usei lastIndexOf e substring (nao pesquisei se em jQuery da pra fazer de uma forma mais simples)                   
                $('<p>')      
                    .append($('<label>').html(this.idFuncionario).hide())      
                    .append($('<label>').html(this.nome))      
                    .append($('<label>').html(this.email))      
                    .append($('<label>').html(this.tipoFuncionario==true ? 'Sim' : 'Não'))      
                    .append($('<label>').html(this.depto.sigla))  
                    .append($('<label>'))    
                    .append(a.attr('href', hrefNew.concat('/'+this.idFuncionario)))                      
                    .appendTo('#list_depto');      
            });                       
            $("#list_depto").show();      
        });

alguém sabe se o clone() não funciona mesmo no IE ou teria outra forma de usá-lo?

abs

Lucas_Cavalcanti

vc tentou o clone com a última versão do jquery?

ViniciusNaka

eu estou usando a 1.5.1…

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>

bom, pelo que vi, já saiu a 1.6.1… vou testar com ela.
vlw!

ViniciusNaka

É, infelizmente não funcionou :(. Continua aparecendo sem os clones.

Lucas_Cavalcanti

Internet Explorer - facilitando a vida dos desenvolvedores web desde 1995

:wink:

uma outra alternativa seria, ao inves de clonar, criar um novo na mão:

$(funcionarios).each(function(){    
           var a = $('#editarFuncionario');    
       var href = a.attr('href');    
       var hrefNumber = href.lastIndexOf("/");    
       var hrefNew = href.substring(0, hrefNumber);  // usei lastIndexOf e substring (nao pesquisei se em jQuery da pra fazer de uma forma mais simples)                     
               $('<p>')        
                   .append($('<label>').html(this.idFuncionario).hide())        
                   .append($('<label>').html(this.nome))        
                   .append($('<label>').html(this.email))        
                   .append($('<label>').html(this.tipoFuncionario==true ? 'Sim' : 'Não'))        
                   .append($('<label>').html(this.depto.sigla))    
                   .append($('<label>'))      
                   .append($('<a>Editar</a>').attr('href', hrefNew.concat('/'+this.idFuncionario))) ///!!!                       
                   .appendTo('#list_depto');        
           });                         
           $("#list_depto").show();        
       });
ViniciusNaka

Olá Lucas…

fiz o que você sugeriu, mas a imagem do botão não aparece :frowning:

<a id="editarFuncionario" href="<c:url value="/funcionario/editar/${funcionario.idFuncionario}" />">
    <img class="img_lista" id="img_editar" alt="Editar" src="/Reconhecimento/images/editar.gif" />
</a>

tentei criar um img (da mesma forma que crio o ) e add no , mas aparece na página somente [Object]

Lucas_Cavalcanti

se vc colocou no css como #editarFuncionario, não vai funcionar mesmo…

tome cuidado com usar id e ficar clonado objetos… teoricamente vc não pode ter mais de um objeto com o mesmo id, e talvez seja por isso que vc está tendo esses problemas…

quando o id pode se repetir, vc tem que trocar por uma class, daí o browser vai fazer tudo direitinho

ViniciusNaka

se vc colocou no css como #editarFuncionario, não vai funcionar mesmo…

eu nao coloquei nada no css para esse id

desculpe Lucas, não entendi o que vc disse :S

quando o id pode se repetir, vc tem que trocar por uma class, daí o browser vai fazer tudo direitinho

Lucas_Cavalcanti

vc tem vários elementos com o mesmo id no seu html. Isso não é o comportamento esperado, o id deveria ser único. Várias coisas do browser e do jquery vão parar de funcionar se tiver mais de um elemento com o mesmo id.

por exemplo, ao invés de usar:

<img id="banana" ...>

....

<img id="banana" ...>

faça

<img class="banana">

<img class="banana">
ViniciusNaka

certo, mas para clonar/copiar o elemento eu faço como?
pq dessa forma ele da erro…

$('#exemplo');

‘undefined’ is null or not an object

Lucas_Cavalcanti

se vc trocou de id pra class, é só trocar o # por .:

$('.exemplo')
ViniciusNaka

Muito obrigado pelo ajuda Lucas!!

Eu alterei minha function e funcionou dessa forma…

function popularFuncDeptos(){
	var sigla = $("#sel_depto").val();
	if(sigla != "all"){
	$.getJSON('/Reconhecimento/funcionario/depto/' + sigla,
		function(funcionarios){
			$("#list_all").hide();
			$("#list_depto").hide();
			$("#list_depto").empty();			
			$(funcionarios).each(function(){		
			// editar
				var editar = $('#editarFuncionario').clone();
			//excluir
				var excluir = $('#excluirFuncionario').clone();
				$('<table>')					
					.append($('<tr>'))
					.append($('<td>').html(this.idFuncionario).hide())
					.append($('<td>').css('width', '280px').html(this.nome))
					.append($('<td>').css('width', '295px').html(this.email))
					.append($('<td>').css('width', '45px').html(this.depto.sigla))
					.append($('<td>')
					.append($(editar).attr('href', '/Reconhecimento/funcionario/editar/'+this.idFuncionario))
					.append($(excluir).attr('href', '/Reconhecimento/funcionario/listar')
						.attr('onclick', 'excluirFunc('+this.idFuncionario+')')).css('width', '55px'))
					.appendTo('#list_depto');
			});					
			$("#list_depto").show();
		});		
	} else {
		$("#list_depto").hide();
		$("#list_all").show();		
	}	
}

o que eu reparei foi que eu retirei a parte do lastIndexOf, substring e concat, depois disso apareceu os botões.
ah, eu testei tb usando .add($(’

’)) e dessa forma tb funcionou
vlw!
Criado 25 de março de 2011
Ultima resposta 1 de jun. de 2011
Respostas 77
Participantes 3