Sabe quando você está escrevendo um e-mail e se você 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 faz isso, o Rally faz isso, mas muita gente ainda não sabe como isso é feito de fato.
Este tipo de 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 deste recurso no CMS era para que os jornalistas fossem avisados quando algum dado no formulário fosse alterado, porém, o usuário intencionalmente (ou não) tenta mudar de página e este dado dado seria perdido. Se tratando de um CMS focado para jornalistas onde 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, mas ele é 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 fazia todo o resto, seria fácil, né? Pois é… mas não é assim (#lol). Temos que fazer um script 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
[javascript]
$(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.";
}
};
});
[/javascript]
Como funciona?
- Utilizei o $.data() do jQuery por que eu não gosto de utilizar o 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 no formulário.
- 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, no caso utilizei o :submit com evento $.click() para remover o evento e cancelar o alerta, caso houve a intenção de salvar o formulário.
Parabéns pela matéria Igor. É de extrema importância esta rotina, pois muitas das vezes saimos de uma página “acidentalmente” e perdemos todas informações preenchidas. Com o alerta fica fácil prever isso.
Abraços.
LikeLike
Não funcionou no Opera. Foi só comigo ou é geral? Geralmente essas coisas só acontecem com o IE. rs… Parabéns pelo post! Sucesso.
LikeLike
Infelizmente, o Opera não suporta o evento ainda. Tem uma thread no stackoverflow falando sobre o problema e comentando sobre uma alternativa (onunload): http://stackoverflow.com/questions/7527969/detecting-browsers-that-dont-support-onunload-onbeforeunload
LikeLike
Amigo, como você trata o evento “onbeforeunload” em casos que existam outras requests diferentes do submit.
Exemplo:
Formulário que possua a validação de um CPF/CNPJ.
Caso essa validação tenha que ir para o servidor, o windows.onbeforeunload vai alertar que você esta saindo da pagina, mas na verdade você esta só fazendo uma validação.
O que ocorre é que mesmo anulando o onbeforeunload no evento desse botão, quando a pagina carrega novamente, o “form original” vai se atualizar (no exemplo o cpf entraria no form Original), ai ao tentar sair o onbeforeunload não acusaria. pois o form original vai estar igual ao form atualizado, mas ao sair. a função de alerta do Sair sem Salvar não vai funcionar.
Alguma idéia ?
Abraços.
LikeLike
Muito bom, mas no MEU CASO, PRECISO FAZER UMA VALIDAÇÃO DESSA NO SISTEMA, PORÉM COM JS PURO, COMO EU FARIA?
LikeLike