Ordenando dados JSON em javascript

Trabalho com javascript há mais de 5 anos, e nunca tive que usar o método sort() da classe Array.
Porque? Em todos projetos que participei os dados já vinham ordenados pelo backend.

Ai, essa semana apareceu uma demanda para fazer a ordenação de dados que vêm através de uma requisição assíncrona no formato JSON. Pensei em alterar o backend, mas ia ter impacto em outros lugares e não daria tempo de validar se iria quebrar em outros pontos… então, procurei uma forma de como fazer isso, e encontrei, usando o método sort(). É possível usá-lo, passando uma função como parâmetro e nela criando a lógica para ordenar por uma determinada chave (lembrando que dados JSON são uma sequencia de chaves/valores).

Parece complexo, mas não é. Por exemplo, tendo dados nesse formato:

var featureData = [{name:"chris",description:"description 1}, {name:"guilherme",description:"description 2"},{name:"bianca",descrip tion:"description 3"}];

Digamos que você queira organizar esses dados pela cahe name, em ordem alfabética. Simples:

featureData.sort(function (obj1, obj2) {
return obj1.name < obj2.name ? -1 :
(obj1.name > obj2.name ? 1 : 0);
});

Referência: http://www.highdots.com/forums/javascript/re-sorting-json-data-270187.html

Usando a prototype – passo 7 – lendo dados em formato JSON

Em mais um texto de série sobre o uso da prototype, vou mostrar como fazer para requisitar, via AJAX, dados em formato JSON e exibí-lo na tela.

JSON
Javascript Object Notation é um dos formatos de troca de dados mais utilizados atualmente. Tem como principais vantagens ser mais leve do que outros (como XML) e seguir o modelo de dados do javascript, por isso para aplicações AJAX é altamente recomendado.

O exemplo é simples, e consiste de uma tabela num banco de dados (utilizei MySQL), uma página que lista uma série de estados e dá ao usuário a opção de buscar as cidades desse estado com o seu respectivo DDD.
Segue, abaixo, o modelo da tabela com alguns poucos dados (obviamente, esse modelo nem de longe é o ideal, mas para efeitos de estudo, se aplica, uma vez que o foco é o JSON):

CREATE TABLE IF NOT EXISTS `cidades` (
  `estado` varchar(2) character set latin1 NOT NULL,
  `cidade` varchar(128) character set latin1 NOT NULL,
  `DDD` int(2) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin ROW_FORMAT=DYNAMIC;
--
-- Extraindo dados da tabela `cidades`
--
INSERT INTO `cidades` (`estado`, `cidade`, `DDD`) VALUES
(´sp´, ´Sao Paulo´, 11),
(´sp´, ´Santos´, 13),
(´sp´, ´Campinas´, 12),
(´rj´, ´Rio de Janeiro´, 21),
(´rj´, ´Buzios´, 23);

 
Então, criei uma página, em PHP, que recebe por POST o id do estado e retorna a lista de cidades e seus respectivos DDDs. Para mostrar no formato JSON, primeiro fazemos a consulta (mysql_query()), então criamos um array ($rows) e, percorrendo linha a linha do resultado (mysql_fetch_assoc()), jogamos cada entrada no array. Então, usamos a função nativa do PHP json_encode()

 

 

<?php
mysql_connect("localhost", "root", "******") or die(mysql_error());
mysql_select_db("exemplos") or die(mysql_error());
$sql = "SELECT cidade, DDD FROM cidades WHERE estado=´" . $_POST["estado"] . "´";
$result = mysql_query($sql);
$rows = array(); //cria array
//intera nos resultados e adiciona item a item no array
while($row = mysql_fetch_assoc($result)) {
$rows[] = $row;
}
echo json_encode($rows); //codifica para formato JSON
?>

Feito isso, vamos criar a página principal. Nela, criamos um formulário com a action apontando para a página recém criada e montamos um select com a lista dos estados (repito que esse não é o modelo adequado, deveria haver uma tabela com a lista de estados e a tabela com a lista de cidades usar essa como chave estrangeira, mas ter feito dessa maneira não atrapalha esse exemplo).
Ai começa o uso da prototype: no onload da página, dizemos que sempre que o select sofrer o evento onchange (ou seja, alguém selecionar um item da lista), vamos fazer a requisição usando o método Request do objeto Form da prototype (nesse post eu explico como fazer isso com detalhes).
No retorno da requisição, usamos o método evalJSON() da classe Array da prototype. A partir daí, o trabalho é manipulação de dados via javascript: usando o .each() do objeto Array, percorremos a lista e podemos acessar pelo nome da coluna da tabela os itens de cada registro, criando elementos de lista li e inserindo numa lista! Aí mais uma ótima vantagem do JSON: você pode acessar os dados de uma forma bem abstrata, usando os mesmos nomes dados na base de dados como se fossem atributos de um objeto.

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Prototype com PHP - usando json</title>
<script src="http://www.prototypejs.org/assets/2008/1/25/prototype-1.6.0.2.js"></script>
<script type="application/javascript">
    //no onload da página, cria listener para o select dos estados
    Event.observe(window , "load", function() {
        Event.observe($("estados"), "change", function() {
            //chama método para listar as cidades a partir do estado selecionado
            $("buscaCidades").request({ 
                onComplete: function(transport){
                    //decodifica JSON
                   
                    var list = $("cidades");
                    //limpa a lista
                    list.innerHTML = "";
                    //percorre lista de cidades com seu DDD usando o iterator each da classe Array da prototype
                    transport.responseText.evalJSON(true).each(function(city) {
                        var li = new Element("li").update(city.cidade + " (" + city.DDD + ")");
                        list.insert(li);
                    });
                }
            });
           
        });
       
    });
   
</script>
</head>
<body>
<h1>Teste para trazer lista de cidades com o seu DDD a partir de um estado</h1>
<form id="buscaCidades" action="cidadeddd_json.php" method="POST">
    <label for="estados">estado:</label>
    <select name="estado" id="estados">
    <option value="-1">selecione um estado...</option>
    <?php
    //conecta ao banco e retorna a lista de estados a partir da tabela de cidades
    mysql_connect("localhost", "root", "******") or die(mysql_error());
    mysql_select_db("exemplos") or die(mysql_error());
   
    $sql = "SELECT estado FROM cidades GROUP by estado";
   
    $result = mysql_query($sql);
    while($row = mysql_fetch_array( $result )) {
    ?>
    <option value="<?php echo $row["estado"];?>"><?php echo $row["estado"]; ?></option>
    <?php
    }
    ?>
    </select>
</form>
<h2>Lista de cidades e seu DDD</h2>
<ul id="cidades">
</ul>
</body>
</html>