- Como Criar Um Site, Blog – WebMaster.pt - http://www.webmaster.pt -

Painel Administrativo Com CSS E jQuery Parte2

Tweet [3]

Dando prosseguimento ao tutorial sobre o painel administrativo totalmente interativo:

Painel Administrativo Com CSS E jQuery Parte1 [4]

veremos como listar os dados cadastrados e editar os valores de maneira prática e elegante.

listar dados

Apresentando Os Dados Da Tabela

Com os dados já cadastrados vamos apresenta-los na página.


<form action="#" id="altera">
<?php
  include("db.php");
  $busca = mysql_query("SELECT * FROM integrantes ORDER BY nome ASC");
  if (mysql_num_rows($busca))
  {
    echo '<ul>';
    while ($resultado = mysql_fetch_array($busca))
    {
      extract($resultado);
      echo '<li>';
      echo '<fieldset title="'.$id.'">';
      echo '<input type="text" name="nome" value="'.$nome.'" />';
      echo '<input type="text" name="instrumento"  value="'.$instrumento.'"/>
  ';    
      echo '<a href="#"><img src="delete.png" alt="" width="16" height="16" /></a>';
      echo '</fieldset>';
      echo '</li>';
    }      
    echo '</ul>';
  }

?>

</form>

É feita a consulta e são criados itens de lista para a organização e também para o efeito de zebra que será providenciado posteriormente. Poderia ser utilizada tabela na organização, o que permite maior controle, mas para tornar o código mais sucinto foi escolhido lista.

Tudo esta sendo adicionado dentro de um formulário como indicado na primeira linha do código. Então cada item da lista engloba os campos do formulário.

Um fieldset engloba os campos porque precisaremos do id do registro que será modificado e como o identificador deve ser único, e temos mais de um campo de inserção a melhor opção foi incluí-lo no fieldset e como valor de title, pois id não permite que o nome inicie com número segundo os padrões da W3C.

Graças a estilização, não parece que os dados são apresentados dentro de inputs. E esta maneira é bem mais conveniente do que transformar elementos de texto, que quando clicados tornam-se elementos de formulário. Principalmente por este ser um painel administrativo.

Foi adicionado também um link que permite a deleção do registro.

Veja que praticamente não existe classe ou id no código. Isso porque localizaremos os elementos com base em sua posição na árvore do documento.

Estilizando A Lista

Vamos fazer alguns ajustes para melhorar a apresentação



ul{list-style:none;}

ul li{padding:3px;}

ul li:nth-child(even){background-color:#eaeaea;}

ul li:nth-child(odd){background-color:#cccccc;}

São tirados os marcadores padrão os elementos de lista e adicionado um espaçamento nos itens da lista.

As duas linhas seguintes são as responsáveis pelas listras alternadas. Para entender os seletores nth-child() veja este tutorial: Especial! CSS3 – Selectores [5]. A principal vantagem de criar as listras com o CSS é que mais adiante os registros serão deletados dinamicamente e o visual da lista será atualizado de acordo. O que não acontece se forem criadas via javascript.

O problema é que o Internet Explorer só vai interpretar o seletor nth-child() na versão 9. Para que funcione no IE você pode utilizar o javascript.

O Arquivo Para Alteração

Crie um arquivo chamado ‘altera.php’. Ele terá o código responsável pela alteração das informações na tabela.



<?php
  include("db.php");
  $id = mysql_real_escape_string($_POST['id']);  
  $campo = mysql_real_escape_string($_POST['campo']);
  $valor = mysql_real_escape_string($_POST['valor']);
  
  if (mysql_query("UPDATE integrantes SET ".$campo."='$valor' WHERE id='$id'"))
  {
    echo 'ok';
  } else {
    echo 'Problema na gravação';  
  }
?>

Não temos como saber qual dos campos esta sendo alterado. Por isso é passado o id do registro, o campo e valor que foram encontrados com o código javascript.

O Javascript

No arquivo ‘javascript.js’ é adicionado comportamento quando o campo foi alterado. Para isso utilizaremos o change(), pois somente se o campo foi alterado é que haverá o trafego dos dados.


  $('#altera input[type=text]').change(function(){
    var $this = $(this);
    var nome = $(this).attr('name');
    var valor = $(this).val();
    var id = $(this).parents().attr('title');
    $(this).addClass('loading');
    $.post('altera.php', {id:id, campo:nome, valor:valor}, function(retorno){
        $($this).removeClass('loading').addClass('alterado');
    })
  })  

Ao haver a mudança no conteúdo do campo é criada uma variável para guardar a referência a este campo. Isso é necessário, pois precisaremos nos referir a ele dentro do $.post(). Usando os atributos val() e attr() conseguimos os dados de que precisamos passar para o arquivo que fará a alteração. Para conseguir o id a ser alterado o fieldset é acessado graças ao parents() que atinge o antecessor do elemento atual.

O campo alterado recebe a classe ‘loading’ para mostrar a animação do processamento.

A requisição é bastante simples e no mesmo molde da gravação dos dados. Só que ao invés de serializar os dados eles são passados separadamente. Recebendo o retorno é removida a classe ‘loading’ e adicionada a ‘alterado’ que mostra um sinal de ok, informando desta maneira, que a alteração foi bem sucedida. O que é muito importante para informar ao usuário que esta acontecendo. Você pode também adicionar uma verificação para garantir que o retorno é de sucesso antes de mostrar o sinal positivo. Na verdade você deve fazer isso para uma aplicação real.

Ainda falta o código que entra em ação quando o link para deleção do registro for clicado. Vamos a ele.



  $('fieldset a img').click(function(){
    var ancora = $(this);
    var id_integrante = $(this).closest('fieldset').attr('title');
    $.post('apaga.php', {id:id_integrante}, function(){
      $(ancora).closest('li').slideUp('slow', function(){
        $(this).remove();
      })
    })
  })  

Olhando a estrutura do documento vemos que a única imagem dentro de um link é o ‘x’ vermelho que vai apagar o registro. Então quando um destes for clicado é guardada uma referência a ele para utilizá-lo dentro do $.post().

É preciso também do id para saber qual registro deletar. Poderiamos pegá-lo usando o mesmo código visto no trecho anterior, com o patents(), mas para fins didáticos apresento aqui o closest() que faz o mesmo trabalho só de um jeito um pouco diferente.

Com os dados prontos é feita a requisição e no retorno o item da lista que engloba o link clicado desaparece com a animação do slideUp() e ao final da animação esse item é removido da estrutura.

Adicionando O Novo Item À Lista

Legal mesmo ficaria se o usuário pudesse ver imediatamente o novo integrante aparecer na lista dos cadastrados. Pois vamos fazer isso então!

Primeiro precisamos de um arquivo que informe qual o último registro da tabela. Crie um e salve com o nome de ‘ultimo.php’. O código é bastante simples:



<?php

include('db.php');
$busca = mysql_query("SELECT * FROM integrantes ORDER BY id DESC LIMIT 1");
$resultado = mysql_fetch_array($busca);
extract($resultado);
echo json_encode($resultado);

?>

Como foi a recém cadastrado, é certo que será o item mais atual da tabela. Para chegar até ele basta ordenar os itens pelo id de maneira descendente. A saída do arquivo é no formato json que nos permite maior controle das informações no javascript.

O item será adicionado assim que o cadastro acabar e o formulário for zerado e será com o método getJSON() especial para lidar com os dados neste formato.



$.getJSON('ultimo.php', function(registro){
  var trechohtml = '<li class="novo">';
  trechohtml += '<span>'+registro.nome+'</span>';
  trechohtml += '<span>'+registro.instrumento+'</span>';
  trechohtml += '</fieldset></li>'          $('ul').prepend(trechohtml);
})

A requisição é feita sem parâmetros porque o arquivo já tem todos os dados necessários. A vantagem do JSON é de que os dados vem de forma bastante legível e assim é possível criar o trecho HTML a ser inserido sem dificuldades. Ao final ele é anexado a estrutura no início da lista.

Este item anexado recebe a classe “novo” que adiciona um fundo amarelo-claro, e chama a atenção do usuário sobre o item que foi anexado. O código completo fica:



  $('#grava').submit(function(){
    var nome_int = $('#grava input[name=nome]').val();
    var instr = $('#grava input[name=instrumento]').val();
    if (nome_int!='' && instr!='' && nome_int!='Integrante' && instr!='Instrumento')
    {
      $('#grava input[type=text]').each(function(){
        $(this).addClass('loading');
      })
      $.post('grava.php', $('#grava').serialize(), function(resposta){
        $('#grava').prepend(resposta).find('p').fadeOut(2000, function(){$(this).remove();});
        $('#grava input[type=text]').removeClass('loading');
        $('form')[0].reset();
        $.getJSON('ultimo.php', function(registro){
          var trechohtml = '<li class="novo">';
          trechohtml += '<span>'+registro.nome+'</span>';
          trechohtml += '<span>'+registro.instrumento+'</span>';
          trechohtml += '</fieldset></li>'        
              
          $('ul').prepend(trechohtml);
        })
      })
      return false;
    } else {
      alert('Complete todos os campos');  
      return false;
    }
  })

Eventos Manipuladores

Surge um problema com esse novo item anexado. Se você tentar editar ou apagar ele não conseguirá. Isso porque os eventos change() e click() somente são anexados aos elementos que já existirem na estrutura quando o código é executado.

Para fazer com que os eventos funcionem também no novo item da lista temos o live(). O truque é que o live() anexa o manipulador na raiz do documento e não no item. Porém, o change não funciona com o live(), nem com bind(). Por isso ao invés de permitir a edição deste novo item colocamos como texto.

Apesar dos pesares, este é um ótimo exemplo da utilização dos eventos manipuladores. Se você quer permitir ao usuário a deleção deste novo item, onde esta:



$('fieldset a img').click(function(){

Muda para:



$('fieldset a img').live('click', function(){

O click funciona como o esperado. A alteração é bastante tranquila e nos arquivos para download no final do tutorial o código esta com o live().

Código Javascript Completo



$(function(){

  $('#altera input[type=text]').change(function(){
    var $this = $(this);
    var nome = $(this).attr('name');
    var valor = $(this).val();
    var id = $(this).parents().attr('title');
    $(this).addClass('loading');
    $.post('altera.php', {id:id, campo:nome, valor:valor}, function(retorno){
        $($this).removeClass('loading').addClass('alterado');
    })
  })
  

  $('fieldset a img').live('click', function(){
    var ancora = $(this);
    var id_integrante = $(this).closest('fieldset').attr('title');
    $.post('apaga.php', {id:id_integrante}, function(){
      $(ancora).closest('li').slideUp('slow', function(){
        $(this).remove();
      })
    })
  })

  $('#grava input[type=text]').focus(function(){
    var valor = $(this).val();
    if (valor === "Integrante" || valor === "Instrumento"){
      $(this).val('');  
    }
  })
  
  $('#grava').submit(function(){
    var nome_int = $('#grava input[name=nome]').val();
    var instr = $('#grava input[name=instrumento]').val();
    if (nome_int!='' && instr!='' && nome_int!='Integrante' && instr!='Instrumento')
    {
      $('#grava input[type=text]').each(function(){
        $(this).addClass('loading');
      })
      $.post('grava.php', $('#grava').serialize(), function(resposta){
        $('#grava').prepend(resposta).find('p').fadeOut(2000, function(){$(this).remove();});
        $('#grava input[type=text]').removeClass('loading');
        $('form')[0].reset();
        $.getJSON('ultimo.php', function(registro){
          var trechohtml = '<li class="novo">';
          trechohtml += '<span>'+registro.nome+'</span>';
          trechohtml += '<span>'+registro.instrumento+'</span>';
          trechohtml += '</fieldset></li>'        
              
          $('ul').prepend(trechohtml);
        })
      })
      return false;
    } else {
      alert('Complete todos os campos');  
      return false;
    }
  })
})

Download do código usado neste tutorial: Painel Administrativo Com CSS E jQuery [6]

Tweet [3]
Be Sociable, Share!
  • [7]
  • [8]
  • [9]
  • [10]
  • [11]