Oi pessoal! Estava estudando Spring pela apostila FJ-21 e estou com dificuldades para implementar o desafio da remoção de um item de uma lista com Ajax:
“use o JQuery para acionar o método removeTarefa quando clicado em um botão de “excluir”. Para isso, crie uma nova coluna na tabela com um link que o onClick vai chamar o endereço associado a removeTarefa, e via AJAX devemos remover a linha da tabela.”
Obs.: No lugar de Tarefa estou usando Categoria.
Abaixo seguem os arquivos:
@Controller
public class CategoriasController {
@RequestMapping("removeCategoriaAjax")
public void removeTarefaAjax(Long id, HttpServletResponse response){
Categoria categoria = new Categoria();
categoria.setId(id);
new CategoriaDao().remove(categoria);
response.setStatus(200);
}
/*@RequestMapping("removeCategoria")
public String removeCategoria(Categoria categoria) {
new CategoriaDao().remove(categoria);
return "redirect:listaCategoria";
}*/
@RequestMapping("listaCategoria")
public String lista(Model model) {
CategoriaDao dao = new CategoriaDao();
model.addAttribute("categorias", dao.listAll());
return "categoria/lista";
}
@RequestMapping("novaCategoria")
public String form() {
return "categoria/formulario";
}
@RequestMapping("adicionaCategoria")
public String adiciona(@Valid Categoria categoria, BindingResult result) {
if (result.hasErrors()) {
return "categoria/formulario";
}
CategoriaDao dao = new CategoriaDao();
dao.insert(categoria);
return "redirect:listaCategoria";
}
}
Quando clico no link para remover a Categoria no lista.jsp:
uma página em branco aparece com o seguinte endereço:
Clico em voltar para a página http://localhost:8080/livros/listaCategoria clico em atualizar e vejo que o registro foi excluído, mas não deveria acontecer dessa forma, certo?
Alguém tem alguma sugestão de como fazer o Ajax funcionar normalmente?
A sua URL esta retornando o removeCategoria, porém este método esta comentado no sua CategoriasController, logo ele não existe, o seu método de remoção removeTarefaAjax e do tipo void, porém não retorna nada , porque vc não altera para String e adiciona o return “redirect:listaCategoria”; como vc fez no removeCategoria.
Obrigado pela resposta, amigo. Fiz conforme você falou, porém o problema é que dessa maneira a página dá refresh. Meu objetivo é usar o Ajax para não ter que dar refresh na página. Por isso uso este código:
@RequestMapping("removeCategoriaAjax")
public void removeCategoriaAjax(Long id, HttpServletResponse response){
Categoria categoria = new Categoria();
categoria.setId(id);
new CategoriaDao().remove(categoria);
response.setStatus(200);
}
Ele é semelhante o que a apostila ensina para atualizar o status de uma tarefa na mesma tela de listagem de tarefas:
@RequestMapping("finalizaTarefa")
public void finaliza(Long id, HttpServletResponse response){
TarefaDAO dao = new TarefaDAO();
dao.finaliza(id);
response.setStatus(200);
}
Perfeito, não tinha atentado para esse detalhe!!
Mas analisando sua linha Remover percebi que vc não utliza o evento onClick, pois pela descrição o registro deve ser removido quando ocorrer o click no link remover, e outra coisa, que talvez possa esta errado pois não manjo muito de javaScript, com relação ao link vc chama por removeCategoriaAjax, o certo não seria chamar a função criada no script ?, ou seja, removeCategoria, algo assim:
[/code]
O que acontece é o seguinte: eu clico no link e não acontece nada mas quando faço um refresh a linha some. Ou seja também é preciso que eu faça um refresh manual. Acho que estamos perto de resolver, mas o que será que está faltando?
Bom, isso parece ser definido na sua function, tenta adicionar o id que recebe a açao AJAX no tabelaCategorias como abaixo:
<script type="text/javascript">
function removeCategoriaAjax(id) {
$.post("removeCategoriaAjax", {'id': id}, function(){
$("#tabelaCategorias"+id).closest("tr").hide;
});
}
</script>
ou assim que defini apenas o elemento que recebe a ação
Tentei aqui das duas formas que você me mostrou mas ainda assim dá o mesmo problema. Tenho que dar refresh para atualizar a linha removida.
Será que estou usando o JQuery errado?
<script type="text/javascript">
function removeCategoriaAjax(id) {
$.post("removeCategoriaAjax", {'id': id}, function(){
$("#tabelaCategorias"+id).closest("tr").hide; // aqui vc deixa como esta
});
}
</script>
<c:forEach items="${categorias}" var="categoria" varStatus="status">
<tr bgcolor="${(status.index % 2) == 0 ? 'lightblue' : 'white' }" id="tabelaCategorias${categoria.id}"> // aqui vc adiciona o id que sera atualizado na ação
<td>${categoria.id}</td>
<td>${categoria.nome}</td>
<td><a href="#" onClick="removeCategoriaAjax(${categoria.id})">Remover</a></td>
<td><a href="mostraCategoria?id=${categoria.id}">Alterar</a></td>
</tr>
</c:forEach>
Com relação ao JQuery não sei te informar.
Blz, a ultima alteração que talvez quem sabe resolva e adicionar um parametro na sua segunda function no seu script, como neste link http://www.guj.com.br/posts/listByUser/143709.java ficando assim; <script type="text/javascript">
function removeCategoriaAjax(id) {
$.post("removeCategoriaAjax", {'id': id}, function(dados){
$("#tabelaCategorias"+id).closest("tr").hide;
});
}
</script>
Amigo, talvez o problema não esteja no JSP. Talvez o problema esteja no controller, tente colocar algum retorno no controller, por exemplo: uma String, que retorne um JSon com o resultado da remoção.
@RequestMapping(“removeCategoriaAjax”)
public @ResponseBody String removeTarefaAjax(Long id, HttpServletResponse response){
Categoria categoria = new Categoria();
categoria.setId(id);
String retorno = null;
Camarada, estou tentando implementar do jeito que você mostrou. Perdoe a minha ignorância, não sei usar JSON. Hoje o meu método remove do CategoriaDao está assim:
douglaskd, a dica do remove que você deu era o que estava faltando para funcionar. Valeu!
Agora, ficou uma dúvida: quando rodo no Firefox funciona sem refresh mas no Chrome ainda vejo que ainda ocorre o refresh.
Isso é problema do Chrome ou tem alguma coisa errada no meu código mesmo?
[size=18] [/size]Tente Colocar o Script da Function dentro do Body do jsp Comigo funcionou e o mais importante era q vc estava esquecendo de colocar os () depois do hide.hide é um metodo q aceita ate parametros como “slow” q faz akela parte desaparecer mais devagar
Fala Peull!!! Você acertou na mosca!! O meu problema é que não coloquei os parênteses depois da função hide!!! Não acredito que não consegui enxergar isso! :x
Agora sim está funcionando do jeito que eu queria!!!