Como criar um aviso de dados não salvos

Sabe quando você está escrevendo um e-mail e tenta sair de tela, o browser te da um aviso, comunicando a possível perda de dados? Pois é sobre isso que vamos falar. O Gmail e o Rally fazem isso, mas muita gente ainda não sabe como isso é feito de fato.

Este recurso é muito interessante e pode evitar muita dor de cabeça por parte da pessoa que estiver utilizando o seu sistema. No meu caso, este recurso foi aplicado a um CMS. A finalidade da implantação era para que os jornalistas fossem avisados quando algum dado no formulário fosse alterado, e que se o usuário intencionalmente (ou não) tentasse mudar de página, o dado seria perdido. Se tratando de um CMS focado para jornalistas, no qual o conteúdo digitado é extremamente importante, todos recurso que for desenvolvido para evitar perda de conteúdo é extremamente bem-vindo.

onBeforeUnload Event

O evento onbeforeunload não tem uma finalidade exclusiva para ele. É um evento como outro qualquer, que é invocado sempre que o usuário tenta sair da página atual, mas quando ele não está setado, simplesmente nada acontece. O evento responsável por pedir para que o usuário confirme ou não a mudança de pagina é o evento onbeforeunload. Sempre que ele é setado, você vai ver um confirm dialog, igual o da imagem abaixo.

O problema

Se fosse só setar o efeito e ele fizesse todo o resto, seria fácil, não? Mas não é assim. Temos que fazer um script que peça a intervenção do usuário nas seguinte situações:

Ao fechar aba/navegador;

Ao clicar em qualquer outro link, senão o submit do formulário;

O alerta deve aparecer somente se algo for alterado no formulário.

A Solução

$(function(){
  var formObject = $('.new_materia, .edit_materia');
  formObject.data('original_serialized_form', formObject.serialize());

  $(':submit').click(function() {
    window.onbeforeunload = null;
  });

  window.onbeforeunload = function() {
    if (formObject.data('original_serialized_form') !== formObject.serialize()) {
      return "As mudanças deste formulário não foram salvas. Saindo desta página, todas as mudanças serão perdidas.";
    }
  };
});

Como funciona?

Utilizei o $.data() do jQuery porque eu não gosto do var para declarar variáveis globais;

Utilizei o $.serialize() do jQuery para serializar o formulário para comparar o estado do formulário no futuro. E foi a forma mais inteligente que encontrei para identificar se algo realmente foi mudado;

Por default, eu seto o evento onbeforeunload e dentro dele eu verifico se algo foi mudado no formulário;

O único caso em que eu tenho que remover o evento onbeforeunload é quando existe a intenção de salvar o dado. Aí eu utilizei o :submit com evento $.click() para remover o evento e cancelar o alerta, caso houvesse a intenção de salvar o formulário.

Bom, é isso!

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *