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!