Daviferreira.com blog

ago

12

Interface drag and drop com jQuery

comentários (13)publicado por Davi Ferreira . 12/08/2007 . 02:47

Customização é um dos principais conceitos da web 2.0 — deixar o usuário participar ativamente em seu website, seja com conteúdo ou com um visual personalizado. Neste artigo você confere como montar uma interface drag and drop (arrastar & soltar) utilizando a biblioteca javascript jQuery, permitindo ao usuário montar uma página a seu gosto, escolhendo a disposição dos boxes de conteúdo disponíveis no site.

Este tutorial é voltado para quem domina HTML e CSS e tem, pelo menos, uma relativa noção de javascript.

jQuery

Antes de começar, vamos falar um pouco da jQuery. Trata-se de um framework que visa facilitar a programação em javascript, tornando o código mais simples, flexível e infinitamente mais elegante. Além de ser bem leve, a jQuery conta ainda com uma comunidade bastante ativa e uma vasta gama de plugins (seu ponto forte).

Veja a seguir um exemplo de código escrito em javascript convencional e uma versão do mesmo código com jQuery.

javascript:

jQuery

Notaram a diferença? Vamos entender o código jQuery, por partes:

$('#box') — o símbolo do dólar, seguido por parênteses, é o construtor da jQuery. Graças a ele você não precisa mais perder tempo digitando document.getElementById toda vez que precisar capturar um objeto HTML pelo id. O seletor $('#box') representa o elemento HTML de id box. Alguns outros exemplos de seletores são:

.css() — a propriedade .css funciona para exibir ou atribuir um valor CSS de um elemento HTML. No exemplo acima, atribuímos a cor "#ff0000" à propriedade background-color do nosso elemento de id box. Para exibir a propriedade ao invés de atribuir um valor, basta omitir o segundo parâmetro, por exemplo:

Confira algumas outras propriedades dos seletores jQuery:

É claro que isso não cobre quase nada do que a jQuery tem a oferecer. Para conferir a lista completa de seletores, comandos, propriedades e métodos visite o wiki do projeto em docs.jquery.com.

Arquivos necessários

A interface drag an drop que iremos desenvolver aqui utiliza os plugins de interface disponíveis neste link e nosso código será baseado no módulo Sortables.

O primeiro passo é declarar os arquivos javascript no <head> de nosso documento HTML.

Observação: neste exemplo, estamos utilizando uma versão completa do arquivo interface.js, com todos os seus módulos, mas nada impede (e eu até recomendo) que você utilize no seu projeto final uma versão compactada apenas com os módulos necessários. Você pode conferir a lista de dependências do Sortables acessando este link.

Downloads:

 

Elementos da interface

Agora vejamos o que é necessário, esquecendo um pouco a parte de javascript, para a construção de uma interface drag and drop. Que elementos vamos utilizar?

Sendo assim, definiremos as seguintes classes CSS para identificar os elementos de nossa interface:

No caso do handle não utilizaremos uma classe, mas sim um elemento específico: a tag <h2>.

Todos os elementos com a classe recebeDrag servirão de base para os elementos arrastáveis. Estes, por sua vez, virão acompanhados da classe itemDrag. O elemento de ajuda (dragAjuda) não precisa ser declarado no documento HTML — o plugin de interface da jQuery se encarrega de fazer isso, apenas o CSS precisa ser criado. Todo itemDrag deve ainda possuir um elemento H2 para arrastá-lo. Nossa estrutura ficou assim:

Elementos da interface drag and drop

E o CSS:

Monte um documento HTML com o CSS acima e inclua quantas áreas e ítens quiser para efetuarmos nosso teste.

document.ready

Com nosso HTML pronto, agora resta apenas instanciar o elemento Sortable da jQuery. Ao invés de utilizar o bom e velho onload no body, vamos adotar uma abordagem mais elegante e garantida, já que espera todo o DOM ser carregado antes de ser executada. Ao final de nosso HTML, antes de fecharmos o <body>, utilizaremos o seguinte código javascript:

O comando/seletor $(document).ready funciona, de certa forma, como o <body onload>. Estamos solicitando que, ao carregar o documento, os elementos div com a classe recebeDrag sejam inicializados como objetos Sortables. Logo em seguida declaramos os parâmetros aceitos na nossa interface drag and drop, bem como as ações a serem executadas quando o elemento é mudado de lugar, quando tem início a ação de arrastar e quanto termina esta mesma ação.

O bloco dos parâmetros é bem simples. Primeiro, utilizando o parâmetro accept, definimos que os divs com a classe recebeDrag aceitarão apenas elementos com a classe itemDrag arrastados dentro deles. Os quatro parâmetros seguintes são referentes às classes e estilos CSS. helperclass define a classe do elemento que demarca áreas em que os divs itemDrag podem ser soltos. hoverclass e activeclass são as classes de estado active e hover para o elemento recebeDrag. Já o parâmetro opacity define o nível de transparência de um elemento, podendo variar de 0 a 1.

handle, conforme explicado anteriormente, define o elemento HTML que servirá como "link" para arrastar os divs itemDrag.

E, por fim, as ações:

 

Interface em ação

Clique aqui para conferir um exemplo bem simples da nossa interface drag and drop. O CSS e o javascript foram todos declarados no arquivo, basta exibir o código-fonte para entender melhor o funcionamento do nosso exemplo.

Para visualizar a versão final deste teste, visite o site beta do Democracia.

 

Sugestões de funcionalidades

 

Referências

 

Atualização [06/12/2008]

Muita gente me pergunta sobre isso, então aí vai um exemplo utilizando cookies para salvar o posicionamento e ordenação definidos pelo usuário.

Exemplo com cookies

Os cookies estão sendo gerenciados diretamente via javascript, através do plugin jCookie: http://plugins.jquery.com/project/cookie.

Confira o que mudou no código. Na propriedade onchange do elemento sortable adicionamos o método $.cookie() para criar um cookie relacionado à cada coluna:

E, após carregar o documento, verificamos se o cookie existe e definimos o posicionamento dos boxes nas colunas:

Simples, não? :)

publicado em: Design | Interfaces | Javascript | jQuery
envie seu comentário

13 pessoas já comentaram este artigo

 

1

13/12/2007 22:09DanielDaniel

Olá!
Consegui seguir os passos acima. Porém, seria importante salvar essas alterações, tipo cookies temporários.. mas não entendo nada de JS.. Jquerry.. teria algum tutorial explicando como fazer esta integração com este código do tutorial?

abs!

2

16/12/2007 23:26Davi FerreiraDavi Ferreira

E aí, Daniel. Estou preparando um post com essa segunda etapa. Mas o segredo está na propriedade onChange do Sortable, é ali que você deve salvar o cookie.

O próprio jquery tem um plugin para cookies:
http://www.stilbuero.de/2006/09/17/cookie-plugin-for-jquery/

Abraços!

3

03/01/2008 21:59Eduardo Ferreira LeiteEduardo Ferreira Leite

Ola Davi estou precisando de alguém que faça um código deste p/ que eu possa implementar em um site,com 14 box destes tipo somente 2 colunas uma maior e outra menor.Sou webdesigner…preciso do valor que vc cobraria p/ desenvolver ou se tem alguém para indicar…valeu

4

30/01/2008 19:05RamonRamon

Valeu cara, era disso que eu tava precisando!! Eu to tentando adaptar isso pro joomla e to conseguindo =D VALEU MESMO!!!

PS: Como colocar uma opção pra desaparecer a div e outra pra ocultar e só deixar o h2?

5

12/11/2008 10:37rodrigorodrigo

Olá amigo, muito bom o post, só que to tendo alguns problemas, veja esse site aqui como exemplo: http://beta.democracia.com.br/# , as divs simplesmente depois de movimentar-se 2 vezes no IE7, não movimenta mais, enquanto no FF funfa na boa… eu estou implementando a jquery e o interface em um site e está dando o mesmo problema, será que poderia me ajudar a ver o erro??? Obrigado desde já

6

13/11/2008 00:08Davi FerreiraDavi Ferreira

@rodrigo
Realmente tá com esse bug no democracia no IE7, valeu o toque, vou dar uma conferida e depois te falo. Talvez seja porque lá usa uma versão antiga ainda do jquery. O próprio drag and drop já tem uma versão mais atual do que a deste post, no http://ui.jquery.com.

O exemplo do artigo funciona na boa no IE7. Tem um link ali no último parágrafo. Se quiser me mandar uma URL de teste do teu site pra eu dar uma conferida, fique a vontade, manda ali pelo form de contato.

7

11/12/2008 11:33rodrigorodrigo

opa. eu aki denovo, conseguiu ver ql o problema? eu ja tentei usar a versão mais nova da jquery e msm assim naum to conseguindo, não tenho o link pois o site ainda não está no ar.

8

12/12/2008 02:41Davi FerreiraDavi Ferreira

@Rodrigo: é problema de versão do jQuery sim, só não pode ser a mais nova mesmo :( Só consegui fazer funfar no IE7 com a 1.1.2. Se quiser baixa daqui, usei no exemplo dos cookies: http://www.daviferreira.com/blog/exemplos/draganddrop/jquery.js.

Vou ver depois se consigo fazer com a versão mais nova, mas provavelmente vou ter que migrar tudo pro interface.js novo.

9

12/12/2008 14:16RodrigoRodrigo

Vlw cara. Funcionou na boa!!! Mas acho q naum vai funfar na versão nova não pq era com ela q eu tava, e o interface tb… :S

Qlqr coisa me dá um tok.

Forte abraço!

10

16/12/2008 10:17RodrigoRodrigo

Olha eu aqui denovo, ¬¬ ^^, é q no site do democracia eu achei interessante tb o fato de poder minimizar e maximizar as divs, até to tentando implementar isso, mas gostaria de saber se tem um idéia de como ficaria o script para o estado inicial dela ser display none, tipo so abre qnd o usuario clicar… tem alguma idéia??? vlw! Abraço!

11

18/12/2008 23:54Davi FerreiraDavi Ferreira

Fala Rodrigo!

Não sei bem se entendi sua dúvida, mas não seria só colocar o CSS inicial do elemento com 'display:none;'?

12

30/12/2008 17:47kirotawakirotawa

Opa, gostei do teu tutorial. Mas tipo eu fiz um controlC, controlV aqui e funfou legal, mas não to conseguindo salvar as posições com o cookie. to fazendo algo errado:

$(document).ready(
function () {
if ($.cookie('coluna1') != null) {
// formata string do cookie
var coluna1 = $.cookie('coluna1').replace(/drop-esquerda\[\]=/g, ");
var coluna1 = coluna1.split('&');
var div_id = ";
for (var x = 0; x < = coluna1.length; x++) {
div_id = coluna1[x];
$('#drop-esquerda').append($('#'+div_id));
}
}
if ($.cookie('coluna2') != null) {
// formata string do cookie
var coluna2 = $.cookie('coluna2').replace(/drop-direita\[\]=/g, ");
var coluna2 = coluna2.split('&');
var div_id = ";
for (var x = 0; x <= coluna2.length; x++) {
div_id = coluna2[x];
$('#drop-direita').append($('#'+div_id));
}
}
}

$('div.recebeDrag').Sortable(
{
accept : 'itemDrag',
helperclass : 'dragAjuda',
activeclass : 'dragAtivo',
hoverclass : 'dragHover',
handle : 'h2',
opacity : 0.7,
onChange : function()
{
serialEsq = $.SortSerialize('drop-esquerda');
serialDir = $.SortSerialize('drop-direita');
$.cookie('coluna1', serialEsq.hash, {expires: 7});
$.cookie('coluna2', serialDir.hash, {expires: 7});
$('#ser-e').val(serialEsq.hash);
$('#ser-d').val(serialDir.hash);
},
onStart : function()
{
$.iAutoscroller.start(this, document.getElementsByTagName('body'));
},
onStop : function()
{
$.iAutoscroller.stop();
}
}
);
}
);

13

30/12/2008 18:08kirotawakirotawa

Opa eu denovo, esquece aí. Nesse negócio de ControlC controlV, esqueci do jquery.cookie.js :P. Agora funfou, vlws.

enviar comentário

(não será publicado, utilizado para avatar [Gravatar])

Tags disponíveis: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>