jQuery + XML

20 12 2007

Aproveitando uma dúvida do fórum do jQuery, escrevi um script para trabalhar com xml retornado via ajax. Vamos por partes:

Nome do script: (xml.php)

Ajax. Este script, valendo-se da condição, escreve um xml válido.

<?php
if ($_GET['xml']) {
header("Content-type: text/xml; charset=ISO-8859-1");
   echo '
<empresa>
<funcionario>
<id>10</id>
<nome>Fulano</nome>
<salario>1600</salario>
<cargo>Analista de sistemas</cargo>
<depto>Tecnologia da informao</depto>
</funcionario>
<funcionario>
<id>14</id>
<nome>Beltrano</nome>
<salario>1900</salario>
<cargo>Suporte Help Desk</cargo>
<depto>Tecnologia da informao</depto>
</funcionario>
<funcionario>
<id>24</id>
<nome>Cicrano</nome>
<salario>2000</salario>
<cargo>Compradora Lar</cargo>
<depto>Compras/Lar</depto>
</funcionario>
<funcionario>
<id>34</id>
<nome>Teste</nome>
<salario>3900</salario>
<cargo>Gerente E-Commerce</cargo>
<depto>Comrcio Eletrnico</depto>
</funcionario>
<funcionario>
<id>44</id>
<nome>zefina</nome>
<salario>3900</salario>
<cargo>Design Modas</cargo>
<depto>Vendas</depto>
</funcionario>
</empresa>';
 sleep(1);
 exit;
}

JavaScript – parte legal :) :

$(document).ready(function(){
 var loading = '<span>Aguarde...</span>';
 var $button = $('button');
 var click = false; 

 // extend, para aplicar um zebra table
 $.fn.zebra = function() {
  $('tbody tr:visible',this)
   .filter(':odd').removeClass('even').addClass('odd')
   .end()
   .filter(':even').removeClass('odd').addClass('even');
  return this;
 }

 $().ajaxStart(
  function(){
   $button.after(loading)
  }
 ).ajaxStop(
  function(){
   $button.next().fadeOut('fast',function(){
    $(this).remove();
   })
  }
 );

$button.bind('click',function(){
  if (click) return;
  click = true;
  $.ajax({
   type: 'GET',
   url: 'xml.php?xml=1',
   dataType: 'xml',
   success: function(xml) {
    var $table = $('table').find('tbody').empty().end();
    var $tr = null;
    $('funcionario',xml).each(function(){
     $tr = document.createElement('tr');
     $($tr).hover(
       function(){
        $(this).addClass('hover')
       },
       function(){
        $(this).removeClass('hover')
       }
     ).bind('click',function(){
	alert($('td:first',this).text())
     });
     $(this).children().each(function(){
      $($tr).append('<td>'+$(this).text()+'</td>');
     });
     $table.append($tr);
    });
    $table.zebra().find('tfoot td').text('time: '+new Date().getTime()).end().parent().show();
    click = false;
   }
  });
 });
});

HTML

<style>
table { background:#fff;border:1px solid #dadada;width:500px;}
table tbody tr {cursor:default;}
table tfoot tr {background:#ccc;}
.odd {background:#eee;}
.even {background:#f6f6f6;}
.hover {background:#fff000;}
</style>
<body>
<button>Get XML</button>
<div id="result" style="display:none">
<table border="0" cellpadding="2" cellspacing="1">
<thead style="background:#ccc">
<tr>
        <th>id</th>
        <th>nome</th>
        <th>salario</th>
        <th>cargo</th>
        <th>dpto</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
        <td colspan="5"></td>
</tr>
</tfoot>
</table>
</div>

Adicionei alguns efeitos para melhorar a visualização (zebra e hover)

[s]

JunioR


Ações

Informações

12 respostas

6 01 2008
Marcus

Muito bacana!
Eu estava atrás de algum tutorial mais fácil de entender como o seu!

Parabéns!

Porém estou com uma dúvida.
Como faço para tratar melhor o XML?
Preciso que o conteúdo do atributo do XML apareça como link dentro da TD, trazendo junto o no link.

Não sei como proceder já que há apenas uma criação de td para todos os elementos e não sei como pegar o nome do atributo.
Tentei ” if($(this).attr==”id”) … ” mas não deu.

Desde já agradeço a atenção.

7 01 2008
juareznjunior

Tente assim:
if ($(this).attr(‘id’)==’id’)

ou

if ($(this).get(0).id==’id’)

[s]

JunioR

22 07 2008
Marcelo Caetano

Achoq ue a minha duvida é a mesma do Marcus

Estou tentando adicionar um evento click em cada linha para mostrar um alert com ‘id’ do funcionario

sera que vc poderia me ajudar me mostrando como fazer isso??

no mais agradeço desde já

22 07 2008
juareznjunior

Marcelo,

Creio q seja isto:

.bind('click',function(){
alert($('td:first',this).text())
}).append(''+$(this).text()+'');

[s]

JunioR

23 07 2008
Marcelo Caetano

Junior … ajudou de mais … Mas gostaria de saber mais uma coisa….

Como a “jQuery” manipula dos dados em XML… Não sei se estou falando bobeira.. corrija-me por favor ….

Neste momento “ function(xml){“ , o parâmetro ‘xml’ esta recebendo toda a sua estrutura do xml certo …..

Como faço para manipular esses dados

Ex…. Quero pegar o nome do funcionário que esta no 3º bloco do xml (no caso seria o Cicrano) … como eu faria isto … independente desta sua aplicação

Agradeço desde já.

24 07 2008
JunioR

Marcelo,

A manipulação do xml é por loop, perceba que criei 2 loops. O primeiro buscando pela tag “funcionario”. Dentro deste loop, faço o segundo, buscando pelos filhos desta tag.

Vc pode criar uma validação simples com um contador. Quando ele for 3, vc grava/resgata o valor da tag.

[s]

JunioR

6 08 2008
Marcus

Júnior,

Vi na resposta que você deu ao Marcelo, que está usando o “.bind”. Já tentei entender pelo http://docs.jquery.com/Events/bind mas não compreendi muito bem qual a utilidade dele…

Outra dúvida é a seguinte:
Recebo os parametros via XML e com eles crio algum elemento na página, não consigo fazer com que minhas funções que existem e funcionam nos elementos que carregaram inicialmente na página funcionem nos novos, que crio com o jQuery…

Existe alguma técnica específica para isso?

6 08 2008
juareznjunior

Marcus,

O “bind” adiciona um evento para qualquer elemento. Ex:
$(‘button’).bind(‘click’,function(){
alert(this)
});

Qto tua outra dúvida, vc pode sim usar outras funções/classes juntamente com o jQuery. Não existe técnica para isto.

[s]

JunioR

9 08 2008
Marcus

Entendi…
Bom saber… sempre quando precisei, fiz de forma obstrusiva por não conhecer isso.

Valeu!

Sobre a outra dúvida, não consegui fazer funcionar até hoje…

Por exemplo:

Imagine que eu carregue junto com a página vários botões e devido a uma requisição ajax que eu fizer, acrescente mais botões à página.

Então eu tenho a função que será executada no clique do botão:

$(‘.exclui_registro’).click(function(){
alert(‘OK’);
});

Porém, se crio esse novo elemento na página via ajax assim:
$(‘button’).click(function(){
$(‘body’).append(‘Excluir’)
});

esses novos elementos não executam a mesma ação dos que já estavam na página anteriormente.

Ouvi falar do livequery, mas também não consegui fazer funcionar com ele…

Grato pela atenção.

Marcus.

9 08 2008
Marcus

Entendi…
Bom saber… sempre quando precisei, fiz de forma obstrusiva por não conhecer isso.

Valeu!

Sobre a outra dúvida, não consegui fazer funcionar até hoje…

Por exemplo:

Imagine que eu carregue junto com a página vários botões e devido a uma requisição ajax que eu fizer, acrescente mais botões à página.

Então eu tenho a função que será executada no clique do botão:

$('.exclui_registro').click(function(){
alert('OK');
});

Porém, se crio esse novo elemento na página via ajax assim:

$('button').click(function(){
$('body').append('Excluir')
});

esses novos elementos não executam a mesma ação dos que já estavam na página anteriormente.

Ouvi falar do livequery, mas também não consegui fazer funcionar com ele…

Grato pela atenção.

Marcus.

9 08 2008
Marcus

O codigo foi convertido, então ficria assim:

$(‘body’).append(‘Excluir’)

11 08 2008
juareznjunior

O live query é uma das saídas. Já testei e funciona muito bem. Outra forma seria vc criar os botões via DOM.

$.ajax({...
success: function(){
var btn = document.createElement('button');
$(btn).bind('click',function(){
alert('OK')
}).appendTo('body');
}
});

[s]

JunioR

Deixe um comentário