Atualizando datatable sem mudar de pagina com vraptor

8 respostas
M

bem pessoal, eu tenho um datatable e eu queria que quando eu clicasse nessa imagem obeto_ativo_true, ele mudasse o estado de true para false sem que mudasse de PAGINA, alguem tem algum caminho para me indicar, infelizmente venho do JSF e era muito dependente dos componentes, e como estou iniciando no action based preciso da ajuda de vocês. Obrigado.

<%@ page contentType="text/html; charset=UTF-8" %>
<script type="text/javascript">

	/* Table initialisation */
	$(document).ready(function() {
		$('#usuarioList').dataTable({
			"sDom" : "<'row'<'span8'l><'span8'f>r>t<'row'<'span8'i><'span8'p>>",
			"sPaginationType": "bootstrap"
		});
	});
</script>

<table id="usuarioList" class="table table-bordered table-striped table-hover">
	<thead>
		<tr>
			<th>#</th>
			<th>Nome</th>
			<th>Email</th>
			<th>Senha</th>
			<th>Permissao</th>
			<th>ativo</th>
		</tr>
	</thead>
	<tbody>
		<c:forEach items="${usuarioList}" var="usuario">
			<tr>
				<td>${usuario.id} </td>
				<td>${usuario.nome}</td>
				<td>${usuario.email}</td>
				<td>${usuario.senha}</td>
				<td>
				<c:if test="${usuario.permissao.contains('ROLE_USUARIO')}">
					Usuario
				</c:if>
				</td>
				<td>
				<c:if test="${usuario.ativo == true}">
					<img src="${pageContext.request.contextPath}/resources/img/objeto_ativo_true.png" alt="Ativo">
				</c:if>
				<c:if test="${usuario.ativo == false}">
					<img src="${pageContext.request.contextPath}/resources/img/objeto_ativo_false.png" alt="False">
				</c:if>
				</td>
			</tr>
		</c:forEach>
	</tbody>
</table>

8 Respostas

Rafael_Guerreiro

Você está fazendo o carregamento da tabela com AJAX?

Vc precisa adicionar um evento no click dessa imagem e faz um $.ajax(); para o servidor passando o ID para alterar.

Lá o server altera e retorna 200 caso dê certo e 500 caso dê erro… Se der erro vc manda msg pro usuário, se não, vc faz um refresh do carregamento do seu datatables…

M

por exemplo, eu queria que ao clicar nele, passasse os parametros para o metodo ativar do meu controller e atualizasse o datatable, sabe como poderia ficar isso?

Rafael_Guerreiro

Exatamente como eu te expliquei acima:
1: Colocaria uma classe para você reconhecer a imagem que receberá o click. (dica, use o c:url que ele coloca o contextPath para você)

&lt;img src="&lt;c:url value="/resources/img/objeto_ativo_true.png" /&gt;" alt="Ativo" class="inativar-usuario"&gt;

2: Colocaria uma classe para você pegar a primeira coluna com o ID que você precisa.

&lt;td class="usuario-id"&gt;${usuario.id} &lt;/td&gt;

3: Criaria o seguinte JS para recarregar a tabela;

/* function para recarregar o dataTable */
(function($) {
	$.fn.dataTableExt.oApi.fnReloadAjax = function(oSettings, sNewSource,
			fnCallback, bStandingRedraw) {
		if (typeof sNewSource != 'undefined' && sNewSource != null) {
			oSettings.sAjaxSource = sNewSource;
		}
		this.oApi._fnProcessingDisplay(oSettings, true);
		bStandingRedraw = true;
		var that = this;
		var iStart = oSettings._iDisplayStart;
		var aData = [];
		this.oApi._fnServerParams(oSettings, aData);
		oSettings.fnServerData(oSettings.sAjaxSource, aData, function(json) {
			that.oApi._fnClearTable(oSettings);
			var aData = (oSettings.sAjaxDataProp !== "") ? that.oApi
					._fnGetObjectDataFn(oSettings.sAjaxDataProp)(json) : json;
			for ( var i = 0; i &lt; aData.length; i++) {
				that.oApi._fnAddData(oSettings, aData[i]);
			}
			oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
			that.fnDraw();
			if (typeof bStandingRedraw != 'undefined'
					&& bStandingRedraw === true) {
				oSettings._iDisplayStart = iStart;
				that.fnDraw(false);
			}
			that.oApi._fnProcessingDisplay(oSettings, false);
			if (typeof fnCallback == 'function' && fnCallback != null) {
				fnCallback(oSettings);
			}
		}, oSettings);
	};
})(jQuery);

4: Adicionaria o evento no click dessa imagem.

$(document).ready(function(){
	$('img.inativar-usuario').on('click', function(){
		var self = $(this);
		$.ajax({
			url: '/url/para/a/action',
			data: {'id' : $.trim(self.parent().siblings('td.usuario-id').text())},
			type: 'post',
			dataType: 'json',
			success: function(){
				// Deu certo. Vai chamar a função fnReloadAjax
				self.closest('table').dataTable().fnReloadAjax();
			},
			error: function(){
				// Deu errado.
				alert('Ocorreu um erro.');
			}
		});
	});
});

To te dando a comida na boca hein… Tente entender essas coisas… Qualquer coisa posta aqui.

M

olha rafael, a mudanças quanto ao c:url eu ja mudei, mais nao vou implementar esse codigo que vc falou sem entender cada linha, essa é a forma mais facil que tem de chamar um metodo e atualizar o proprio datatable? tem uma forma mais pratica nao? até peço desculpas pelo abuso, mais acho que isso para quem estar iniciando é um tiro no pé colocar no codigo se na verdade nao sabe 20% do que está sendo feito(digo da parte do function… o resto eu entendi.)

Rafael_Guerreiro

Eu acho que você deveria implementá-lo, é que o código é feio, só isso… Tente lê-lo.

(function($) { $.fn.dataTableExt.oApi.fnReloadAjax = function(oSettings, sNewSource, fnCallback, bStandingRedraw) { if (typeof sNewSource != 'undefined' && sNewSource != null) { oSettings.sAjaxSource = sNewSource; } this.oApi._fnProcessingDisplay(oSettings, true); // Coloca o processando na sua tabela bStandingRedraw = true; var that = this; var iStart = oSettings._iDisplayStart; var aData = []; this.oApi._fnServerParams(oSettings, aData); // Pega os parâmetros para enviar ao server oSettings.fnServerData(oSettings.sAjaxSource, aData, function(json) { // Executa ação ao server e pega as linhas that.oApi._fnClearTable(oSettings); var aData = (oSettings.sAjaxDataProp !== &quot;&quot;) ? that.oApi ._fnGetObjectDataFn(oSettings.sAjaxDataProp)(json) : json; for ( var i = 0; i &lt; aData.length; i++) { that.oApi._fnAddData(oSettings, aData[i]); } oSettings.aiDisplay = oSettings.aiDisplayMaster.slice(); that.fnDraw(); // Desenha a tabela if (typeof bStandingRedraw != 'undefined' && bStandingRedraw === true) { oSettings._iDisplayStart = iStart; // Mantém a tabela na mesma página que estava that.fnDraw(false); } that.oApi._fnProcessingDisplay(oSettings, false); // Tira o processando da tabela if (typeof fnCallback == 'function' && fnCallback != null) { fnCallback(oSettings); // Chama os callbacks } }, oSettings); }; })(jQuery);
Coloque esse código em um JS separado e esqueça-se dele, só o chame junto com o DataTables. (ele é um plugin feito pelo cara que fez o datatable)

M
function tratarEvento() {

		var id = $('#usuarioId').val();
		$.ajax({  
			   url: '<c:url value="/usuario/ativar/"/>',  
			   data: id}).success(function(data) {  
				   alert('salvo com sucesso');  
			   }).error(function() {  
			       alert('falha ao salvar');  
			   }); 
	}
</script>

<table id="usuarioList" class="table table-bordered table-striped table-hover">
	<thead>
		<tr>
			<th>#</th>
			<th>Nome</th>
			<th>Email</th>
			<th>Senha</th>
			<th>Permissao</th>
			<th>ativo</th>
		</tr>
	</thead>
	<tbody>
		<c:forEach items="${usuarioList}" var="usuario">
			<tr>
				<td id="usuarioId">${usuario.id}</td>
				<td id="usuarioNome">${usuario.nome}</td>
				<td>${usuario.email}</td>
				<td>${usuario.senha}</td>
				<td>
				<c:if test="${usuario.permissao.contains('ROLE_USUARIO')}">
					Usuario
				</c:if>
				</td>
				<td>
					<c:if test="${usuario.ativo == true}">
						<a href="#" onclick="tratarEvento();">
							<img src="<c:url value="/resources/img/objeto_ativo_true.png"/>" alt="Ativado">
						</a>
					</c:if>
					<c:if test="${usuario.ativo == false}">
						<a href="#" onclick="tratarEvento();">
							<img src="<c:url value="/resources/img/objeto_ativo_false.png"/>" alt="Desativado">
						</a>
					</c:if>
				</td>
			</tr>
		</c:forEach>
	</tbody>
</table>

como pegar o valor de ${usuario.id} no metodo tratarEvento e passar no data do ajax?

Rafael_Guerreiro

Rafael Guerreiro:
Exatamente como eu te expliquei acima:
1: Colocaria uma classe para você reconhecer a imagem que receberá o click. (dica, use o c:url que ele coloca o contextPath para você)

&lt;img src="&lt;c:url value="/resources/img/objeto_ativo_true.png" /&gt;" alt="Ativo" class="inativar-usuario"&gt;

2: Colocaria uma classe para você pegar a primeira coluna com o ID que você precisa.

&lt;td class="usuario-id"&gt;${usuario.id} &lt;/td&gt;

3: Criaria o seguinte JS para recarregar a tabela;

/* function para recarregar o dataTable */
(function($) {
	$.fn.dataTableExt.oApi.fnReloadAjax = function(oSettings, sNewSource,
			fnCallback, bStandingRedraw) {
		if (typeof sNewSource != 'undefined' && sNewSource != null) {
			oSettings.sAjaxSource = sNewSource;
		}
		this.oApi._fnProcessingDisplay(oSettings, true);
		bStandingRedraw = true;
		var that = this;
		var iStart = oSettings._iDisplayStart;
		var aData = [];
		this.oApi._fnServerParams(oSettings, aData);
		oSettings.fnServerData(oSettings.sAjaxSource, aData, function(json) {
			that.oApi._fnClearTable(oSettings);
			var aData = (oSettings.sAjaxDataProp !== "") ? that.oApi
					._fnGetObjectDataFn(oSettings.sAjaxDataProp)(json) : json;
			for ( var i = 0; i &lt; aData.length; i++) {
				that.oApi._fnAddData(oSettings, aData[i]);
			}
			oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
			that.fnDraw();
			if (typeof bStandingRedraw != 'undefined'
					&& bStandingRedraw === true) {
				oSettings._iDisplayStart = iStart;
				that.fnDraw(false);
			}
			that.oApi._fnProcessingDisplay(oSettings, false);
			if (typeof fnCallback == 'function' && fnCallback != null) {
				fnCallback(oSettings);
			}
		}, oSettings);
	};
})(jQuery);

4: Adicionaria o evento no click dessa imagem.

$(document).ready(function(){
	$('img.inativar-usuario').on('click', function(){
		var self = $(this);
		$.ajax({
			url: '/url/para/a/action',
			data: {'id' : $.trim(self.parent().siblings('td.usuario-id').text())},
			type: 'post',
			dataType: 'json',
			success: function(){
				// Deu certo. Vai chamar a função fnReloadAjax
				self.closest('table').dataTable().fnReloadAjax();
			},
			error: function(){
				// Deu errado.
				alert('Ocorreu um erro.');
			}
		});
	});
});

To te dando a comida na boca hein… Tente entender essas coisas… Qualquer coisa posta aqui.


Faça o que eu te mostrei nesses passos.

M

vou testar.

Criado 29 de abril de 2013
Ultima resposta 30 de abr. de 2013
Respostas 8
Participantes 2