Image Image Image Image Image
Scroll to Top

Topo

onbeforeunload

10

abr
2012

Sem Comentários

Em Blog

Por Allison

Como criar um aviso de dados não salvos

Em 10, abr 2012 | Sem Comentários | Em Blog | Por Allison

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!

Tags | , , , ,