Para quem ainda não conhece, o Local Storage é um recurso do HTML 5 que funciona, assim podemos dizer, como um cookie que não possui tempo para expirar. Ou seja, é um local para se armazenar dados que não são perdidos ao fim da seção, logo, podemos fechar e abrir o browser várias vezes e as informações gravadas permanecerão lá.

Neste artigo, veremos como utilizar o local storage na prática, criando um cadastro simples de clientes, com as operações básicas de CRUD. Não vamos nos ater aqui ao design e sim às suas funcionalidades. No código-fonte disponível no topo desta página, porém, a interface está aprimorada.

Inicialmente, vejamos a estrutura do nosso HTML, a qual é bastante simples. Constitui-se apenas de um formulário com 4 campos (para operações de adição e edição de registros) e uma tabela para listar os registros existentes.


<!DOCTYPE html>
<html>
<head>
	<title>HTML5 Storage com JSON</title>
	<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
	<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
	<script type="text/javascript" src="funcoes.js"></script>
</head>
<body>
	<form id="frmCadastro">
		<ul>
			<li>
				<label for="txtCodigo">Código:</label>
				<input type="text" id="txtCodigo"/>
			</li>
			<li>
				<label for="txtNome">Nome:</label>
				<input type="text" id="txtNome"/>
			</li>
			<li>
				<label for="txtTelefone">Telefone:</label>
				<input type="text" id="txtTelefone"/>
			</li>
			<li>
				<label for="txtEmail">Email:</label>
				<input type="text" id="txtEmail"/>
			</li>
			<li>
				<input type="submit" value="Salvar" id="btnSalvar"/>
			</li>
		</ul>
	</form>

	<table id="tblListar">

	</table>
</body>
</html>
Listagem 1. estrutura do HTML

Vale observar que fazemos referência a dois arquivos JavaScript. O primeiro é da jQuery e o segundo é o nosso arquivo contendo as funções que tratarão o cadastro propriamente dito.

Durante este artigo, utilizaremos algumas funções do JavaScript que merecem atenção especial, são elas:

  • localStorage.setItem(nome, valor): esta função é utilizada para armazenar um valor no local storage. Cada objeto gravado é referenciado por uma chave (nome).
  • localStorage.getItem(nome): por sua vez, o getItem é usado para recuperar um valor armazenado a partir da sua chave identificadora.
  • JSON.stringfy(objeto): para armazenar os dados, utilizaremos o formato JSON e esta função transforma um objeto em string com sintaxe adequado ao JSON.
  • JSON.parse(objeto): já a função parse transforma um item no formato JSON no seu formato original.

Criemos, então, nosso arquivo funções.js e nele utilizaremos também a sintaxe jQuery, logo, todo conteúdo deverá ficar no corpo da função que é executada ao carregar a página.

Primeiramente, definiremos algumas variáveis globais que serão necessárias para manipular os dados.


$(function(){
	var operacao = "A"; //"A"=Adição; "E"=Edição
	var indice_selecionado = -1; //Índice do item selecionado na lista
	var tbClientes = localStorage.getItem("tbClientes");// Recupera os dados armazenados
	tbClientes = JSON.parse(tbClientes); // Converte string para objeto
	if(tbClientes == null) // Caso não haja conteúdo, iniciamos um vetor vazio
	tbClientes = [];
});
Listagem 2. definição de variáveis globais

A variável “operacao” será utilizada para definir se o usuário está adicionando ou editando um registro. “índice_selecionado” servirá para referenciarmos o registro selecionado na tabela. “tbClientes” é nossa “tabela de clientes” e a iniciamos com o valor recuperado do local storage (salvo com a chave “tbClientes”). Caso não haja conteúdo, inicializamos a variável como um vetor vazio.

Por padrão, a variável “operacao” terá valor “A”, ou seja, caso o usuário digite as informações e clique no botão para salvar os dados, um novo registro será adicionado, exceto quando tiver clicado em um item na tabela para editá-lo.

Agora vamos às funções do CRUD. Utilizaremos 4 funções: Adicionar, Editar, Excluir e Listar. Vejamos o código:


function Adicionar(){
	var cliente = JSON.stringify({
		Codigo   : $("#txtCodigo").val(),
		Nome     : $("#txtNome").val(),
		Telefone : $("#txtTelefone").val(),
		Email    : $("#txtEmail").val()
	});
	tbClientes.push(cliente);
	localStorage.setItem("tbClientes", JSON.stringify(tbClientes));
	alert("Registro adicionado.");
	return true;
}
Listagem 3. função Adicionar

function Editar(){
	tbClientes[indice_selecionado] = JSON.stringify({
			Codigo   : $("#txtCodigo").val(),
			Nome     : $("#txtNome").val(),
			Telefone : $("#txtTelefone").val(),
			Email    : $("#txtEmail").val()
		});//Altera o item selecionado na tabela
	localStorage.setItem("tbClientes", JSON.stringify(tbClientes));
	alert("Informações editadas.")
	operacao = "A"; //Volta ao padrão
	return true;
}
Listagem 4. função Editar

function Excluir(){
	tbClientes.splice(indice_selecionado, 1);
	localStorage.setItem("tbClientes", JSON.stringify(tbClientes));
	alert("Registro excluído.");
}
Listagem 5. função Excluir

function Listar(){
		$("#tblLiWistar tbody").append("</tr>");
	}
}
Listagem 6. função Listar

Vale observar que na primeira coluna da tabela, adicionamos duas imagens que servirão como botões de ação Editar e Excluir, cujo evento onClick será tratado via jQuery mais a frente. As imagens “edit.png” e “delete.png” estão disponíveis no código-fonte, mas podem ser duas quaisquer (utilizei dimensões 16x16 para ficar “discreto” na tabela).

A função Listar deve ser chamada no corpo da função principal, para que a tabela seja atualizada sempre que a página for recarregada.

Agora resta tratar os eventos dos controles HTML que acionarão as funções de CRUD. Para gravar os dados do novo registro ou do registro em edição, utilizamos o evento onSubmit do form frmCadastro. Observemos o código seguinte:


$("#frmCadastro").on("submit",function(){
	if(operacao == "A")
		return Adicionar();
	else
		return Editar();		
});
Listagem 7. evento onSubmit do form

Aos botões de ação Editar e Excluir, por outro lado, foram atribuídas classes “btnEditar” e “btnExcluir”, a partir das quais trataremos o evento onClick:


$("#tblListar").on("click", ".btnEditar", function(){
	operacao = "E";
	indice_selecionado = parseInt($(this).attr("alt"));
	var cli = JSON.parse(tbClientes[indice_selecionado]);
	$("#txtCodigo").val(cli.Codigo);
	$("#txtNome").val(cli.Nome);
	$("#txtTelefone").val(cli.Telefone);
	$("#txtEmail").val(cli.Email);
$("#txtCodigo").attr("readonly","readonly");
	$("#txtNome").focus();
});
Listagem 8. evento onClick dos botões Editar
     
$("#tblListar").on("click", ".btnExcluir", function(){
	indice_selecionado = parseInt($(this).attr("alt"));
	Excluir();
	Listar();
});
Listagem 9. evento onClick dos botões Excluir

As rotinas utilizadas são bem simples, não nos aprofundamos mais nas validações e tratamento de erros, por exemplo. No entanto, no código-fonte do artigo o código está um pouco mais complexo, com algumas funcionalidades a mais.

Abaixo você pode ver o código-fonte do arquivo de funções.js


$(function(){
    var operacao = "A"; //"A"=Adição; "E"=Edição
    var indice_selecionado = -1; //Índice do item selecionado na lista
    var tbClientes = localStorage.getItem("tbClientes");// Recupera os dados armazenados
    tbClientes = JSON.parse(tbClientes); // Converte string para objeto
    if(tbClientes == null) // Caso não haja conteúdo, iniciamos um vetor vazio
    tbClientes = [];
});

function Adicionar(){
    var cliente = JSON.stringify({
        Codigo   : $("#txtCodigo").val(),
        Nome     : $("#txtNome").val(),
        Telefone : $("#txtTelefone").val(),
        Email    : $("#txtEmail").val()
    });
    tbClientes.push(cliente);
    localStorage.setItem("tbClientes", JSON.stringify(tbClientes));
    alert("Registro adicionado.");
    return true;
}

function Editar(){
    tbClientes[indice_selecionado] = JSON.stringify({
            Codigo   : $("#txtCodigo").val(),
            Nome     : $("#txtNome").val(),
            Telefone : $("#txtTelefone").val(),
            Email    : $("#txtEmail").val()
        });//Altera o item selecionado na tabela
    localStorage.setItem("tbClientes", JSON.stringify(tbClientes));
    alert("Informações editadas.")
    operacao = "A"; //Volta ao padrão
    return true;
}

function Excluir(){
    tbClientes.splice(indice_selecionado, 1);
    localStorage.setItem("tbClientes", JSON.stringify(tbClientes));
    alert("Registro excluído.");
}

function Listar(){
    $("#tblListar").html("");
    $("#tblListar").html(
        "<thead>"+
        "   <tr>"+
        "   <th></th>"+
        "   <th>Código</th>"+
        "   <th>Nome</th>"+
        "   <th>Telefone</th>"+
        "   <th>Email</th>"+
        "   </tr>"+
        "</thead>"+
        "<tbody>"+
        "</tbody>"
        );
    for(var i in tbClientes){
        var cli = JSON.parse(tbClientes[i]);
        $("#tblListar tbody").append("<tr>");
        $("#tblListar tbody").append("<td><img src='edit.png' alt='"+i+"'
              class='btnEditar'/><img src='delete.png' alt='"+i+"' class='btnExcluir'/></td>");
        $("#tblListar tbody").append("<td>"+cli.Codigo+"</td>");
        $("#tblListar tbody").append("<td>"+cli.Nome+"</td>");
        $("#tblListar tbody").append("<td>"+cli.Telefone+"</td>");
        $("#tblListar tbody").append("<td>"+cli.Email+"</td>");
        $("#tblListar tbody").append("</tr>");
    }
}

$("#frmCadastro").on("submit",function(){
    if(operacao == "A")
        return Adicionar();
    else
        return Editar();       
});


$("#tblListar").on("click", ".btnEditar", function(){
    operacao = "E";
    indice_selecionado = parseInt($(this).attr("alt"));
    var cli = JSON.parse(tbClientes[indice_selecionado]);
    $("#txtCodigo").val(cli.Codigo);
    $("#txtNome").val(cli.Nome);
    $("#txtTelefone").val(cli.Telefone);
    $("#txtEmail").val(cli.Email);
$("#txtCodigo").attr("readonly","readonly");
    $("#txtNome").focus();
});

$("#tblListar").on("click", ".btnExcluir",function(){
    indice_selecionado = parseInt($(this).attr("alt"));
    Excluir();
    Listar();
});
Listagem 10. Arquivo funcoes.js

Na Figura 1 é possível visualizar como a página ficará.

Página em funcionamento
Figura 1. Página em funcionamento