Menu Accordion com JQuery

11 07 2008

Bem pessoas, o fato qual me levou a desenvolver este menu foi a necessidade de manter um controle no mesmo, podendo fechar e abrir o mesmo item do submenu, tudo isso usando ul li, direto ao ponto.

Primeira coisa a fazer, como verificar qual menu estava aberto antes do reload?
A solução para isso foi gravar o menu em cookie para verificação, segue abaixo as funções para criar e recuperar o cookie.

Função para recuperar o cookie:

/**
 * Retorna o valor do cookie
 * @autor Deusimar Ferreira
 * @param string name
 */
getCookie = function(Name){
	var re=new RegExp(Name+"=[^;]+", "i");
	if (document.cookie.match(re))
		return document.cookie.match(re)[0].split("=")[1];
	return null;
}

Função para criar e setar o valor do cookie:

/**
 * Define cookie
 * @autor Deusimar Ferreira
 * @param string name
 * @param string|int value
 */
setCookie = function(name, value){
	document.cookie = name + "=" + value;
}

Cirei um atributo para meu submenu chamado de menuIndex.

// Pega submenus
var subContents = $('#menu li ul');

// Percorre o menu e adiciona indice
$("#menu li div a").each(function(index) {
	subContents.eq(index).attr({menuIndex: index + 'c'});
})

Este script contém os eventos accordion do menu, ele faz a verificação de qual submenu esta aberto e chama o evento, caso o item clicado esteja aberto ele será fechado ou inverso, caso seja outro item ele abre o item clicado e fecha os outros itens.

$("div a").click(function() {
	//$("#menu li ul:visible").slideUp("slow"); // Esocnde menu item que visivel
	//$(this).parent().next().slideToggle("slow"); // Mostra o menu item que recebeu o evento click		

	// Criar objeto gobal do parent span a
	var _this = $(this).parent().next();

	// Percorre o menu para verificar as ações que deve ser executada
	// Verifica qual submenu deve ser fechado e qual será aberto
	$("div a").each(function(index){
		if ($('#menu li ul:eq(' + index + ')').attr('menuIndex') != _this.attr('menuIndex')) {
			// Verifica se exite algum submenu que não seja o que recebeu o evento do click aberto
			if ($('#menu li ul:eq(' + index + ')').is(':visible'))
				$('#menu li ul:eq(' + index + ')').slideUp("slow"); // Esocnde submenu item que visivel
		} else {
			(_this.is(':visible')) ? _this.slideUp("slow") // Esocnde submenu item que visivel
					       : _this.slideDown("slow"); // Mostra o submenu item que recebeu o evento click
		}
	})

	// Retorna falso funciona como um pause
	return false;
})

Neste outro script ao fechar a página ele recuperar o índice do menu e cria um cookie com seu valor.

// Evento window unload
$(window).bind('unload', function(){
	$('#menu li ul').unbind(); // Remove eventos
	var expandeIndices = []; // Array indice

	$("#menu li ul:visible").each(function(index){
		// Insere o valor do menuindex no array
		expandeIndices.push($(this).attr('menuIndex'));
	})

	expandeIndices = (expandeIndices.length == 0) ? '-1c' : expandeIndices;
	setCookie('menuIndex', expandeIndices); // Seta o cookie e seu respectivo valor
})

Pega o valor do cookie e mantém o respectivo submenu aberto.

// Verifica o cookie para ver qual submenu deve ser mostrado
$("#menu li ul").each(function(){
        // Mostra o submenu
	if ($(this).attr('menuIndex') == getCookie('menuIndex')) {
		$(this).show();
	} else { // Esconde o restante
		$(this).hide();
	}
})

Eis o script completo:

$(document).ready(function() {
	/**
	 * Retorna o valor do cookie
	 * @autor Deusimar Ferreira
	 * @param string name
	 */
	getCookie = function(Name){
		var re=new RegExp(Name+"=[^;]+", "i");
		if (document.cookie.match(re))
			return document.cookie.match(re)[0].split("=")[1];
		return null;
	}

	/**
	 * Define cookie
	 * @autor Deusimar Ferreira
	 * @param string name
	 * @param string|int value
	 */
	setCookie = function(name, value){
		document.cookie = name + "=" + value;
	}

	/**
	 * Accordion Menu
	 * @autor Deusimar Ferreira
	 * @param #menu li ul
	 * @param #menu li div a
	 */
	if (typeof expandeIndices == 'string')
		expandeIndices = expandeIndices.replace(/c/ig, '').split(',') // Transfoma string value em array (ie: "c1,c2,c3" becomes [1,2,3]

	// Pega submenus
	var subContents = $('#menu li ul');

	// Percorre o menu e adiciona indice
	$("#menu li div a").each(function(index) {
		subContents.eq(index).attr({menuIndex: index + 'c'});
	})

	// Apresenta apenas o primeiro menu list
	$('#menu li ul:not(:first)').hide();
	$("div a").click(function() {
		//$("#menu li ul:visible").slideUp("slow"); // Esocnde menu item que visivel
		//$(this).parent().next().slideToggle("slow"); // Mostra o menu item que recebeu o evento click		

		// Criar objeto gobal do parent span a
		var _this = $(this).parent().next();

		// Percorre o menu para verificar as ações que deve ser executada
		// Verifica qual submenu deve ser fechado e qual será aberto
		$("div a").each(function(index){
			if ($('#menu li ul:eq(' + index + ')').attr('menuIndex') != _this.attr('menuIndex')) {
				// Verifica se exite algum submenu que não seja o que recebeu o evento do click aberto
				if ($('#menu li ul:eq(' + index + ')').is(':visible'))
					$('#menu li ul:eq(' + index + ')').slideUp("slow"); // Esocnde submenu item que visivel
			} else {
				(_this.is(':visible')) ? _this.slideUp("slow") // Esocnde submenu item que visivel
									   : _this.slideDown("slow"); // Mostra o submenu item que recebeu o evento click
			}
		})

		// Retorna falso funciona como um pause
		return false;
	})		

	// Evento window unload
	$(window).bind('unload', function(){
		$('#menu li ul').unbind(); // Remove eventos
		var expandeIndices = []; // Array indice

		$("#menu li ul:visible").each(function(index){
			// Insere o valor do menuindex no array
			expandeIndices.push($(this).attr('menuIndex'));
		})

		expandeIndices = (expandeIndices.length == 0) ? '-1c' : expandeIndices;
		setCookie('menuIndex', expandeIndices); // Seta o cookie e seu respectivo valor
	})		

	// Verifica o cookie para ver qual submenu deve ser mostrado
	$("#menu li ul").each(function(){
		if ($(this).attr('menuIndex') == getCookie('menuIndex')) { // Mostra o submenu
			$(this).show();
		} else { // Esconde o restante
			$(this).hide();
		}
	})
})

Folha de estilo css:

div {
	font-family: Verdana, Arial;
	font-size: 11px;
	font-weight: bold;
	margin: 1px 0px;
	padding: 0px;
	border: 1px #06c solid;
	background-color: gray;
}

ul {
	list-style-type: none;
	max-width: 202px;
	_width: 200px; /* Adivinha para quem serve essa linha - Claro que é o IE! */
}

#menu li {
	margin: 0px 0px;
}

#menu li ul{
	margin: 0px;
	padding: 1px 5px;
	display: none;
}

#menu li div a{
	text-decoration: none;
	outline: none;
	line-height: 18px;
	padding: 1px 4px;
	color: white;
}

a {
	font-family: Verdana, Arial;
	font-size: 11px;
	text-decoration: none;
	outline: none;
	padding: 1px 4px;
	color: #06c;
}

a:hover {
	font-family: Verdana, Arial;
	font-size: 11px;
	text-decoration: underline;
	outline: none;
	padding: 1px 4px;
	color: #06c;
}

Estrutura do menu em lista não ordenada, ul li:

<ul id="menu">
	<li>
		<div><a href="">JQuery Documentation</a></div>
		<ul id="submenu">
			<li><a href="http://docs.jquery.com/Main_Page" target="blank" title="Documentation">Documentation</a></li>
			<li><a href="http://docs.jquery.com/Tutorials" target="blank" title="Tutrorials">Tutrorials</a></li>
		</ul>
	</li>

	<li>
		<div><a href="">Player Game</a></div>
		<ul id="submenu">
			<li><a href="http://www.cdt.unb.br/memoria" title="Memória Empreendedora">Memória Empreendedora</a></li>
			<li><a href="" title="Memória Empreendedora">Memória Empreendedora</a></li>
		</ul>
	</li>

	<li>
		<div><a href="">Sobre</a></div>
		<ul id="submenu" style="border-bottom: 1px #06c solid;">
			<li><a href="http://zimar.wordpress.com/about/" title="Sobre Me">Sobre Me</a></li>
			<li><a href="http://docs.google.com/View?docid=ddft82q4_42hmpmmcgv" title="Curriculum">By Curriculum</a></li>
		</ul>
	</li>
</ul>

é isso ai, qualquer dúvida, pergunte!





Unidos pelo récorde

18 03 2008

Unidos para que o Firefox 3 bata o récorde mundial de download.

Abracem esta idéia!


Download Day





Requisitando uma página em ajax

12 02 2008

A finalidade deste exemplo é mostra para os iniciantes em ajax como é simples efetuar uma requisição usando o ajax.

A primeira coisa a fazer é verificar se o browser do cliente suporta o ajax e instânciar o objeto.

var ajax;
try {
  // Verifica se o Firefox, Opera 8.0+, Safari suporta o ajax
  ajax = new XMLHttpRequest();
} catch (e) {
  // Verifica se o Internet Explorer suporta o ajax
  try {
    ajax = new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e) {
    try {
      ajax = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (e) {
      alert("Seu browser não dar suporte ao AJAX!");
      return false;
    }
  }
}

Agora vamos processar nosso ajax, observe que neste exemplo estamos tratando o readyState 4, que seguinifica que a requisição foi bem sucedida.

// Processa requisição ajax
ajax.onreadystatechange = function() {
  if(ajax.readyState == 4) {
    document.getElementById('campoResposta').innerHTML = ajax.responseText;
  }
}
ajax.open('POST', 'time.php', true);
ajax.send(null);

Neste exemplo o ajax requisita uma página que contém uma função date(‘H:i:s’)
time.php

date('H:i:s')

Agora juntamos as partes do objeto ajax em uma função para efetuarmos a requisição.

function ajaxSend() {
  var ajax;
  try {
    // Firefox, Opera 8.0+, Safari
    ajax = new XMLHttpRequest();
  } catch (e) {
      // Internet Explorer
      try {
        ajax = new ActiveXObject("Msxml2.XMLHTTP");
      } catch (e) {
        try {
          ajax = new ActiveXObject("Microsoft.XMLHTTP");
        } catch (e) {
          alert("Seu browser não dar suporte ao AJAX!");
          return false;
        }
      }
  }

  // Processa requisição ajax
  ajax.onreadystatechange=function() {
    if(ajax.readyState == 4) {
      document.getElementById('time').innerHTML = 'Time: ' + ajax.responseText;
    }
  }
  ajax.open('POST', 'time.php', true);
  ajax.send(null);
}




Site da Agência Liberdade de Expressão

4 09 2007

Site da Agência e Asssessoria de Comunicação Liberdade de Expressão, desenvolvido em php e javascript, baseado nos padrões adotados pela W3C.

Projeto de Interface desenvolvida por, Yoda Nakasu.