Eu tenho algumas páginas com formulários no meu aplicativo.
Como posso proteger o formulário de tal maneira que, se alguém navegar ou fechar a guia do navegador, será solicitado que você confirme que realmente deseja deixar o formulário com dados não salvos?
javascript
forms
Khan
fonte
fonte
Respostas:
Resposta curta e errada:
Você pode fazer isso manipulando o
beforeunload
evento e retornando uma sequência não nula :O problema dessa abordagem é que o envio de um formulário também está disparando o evento descarregar . Isso é corrigido facilmente adicionando o sinalizador a que você está enviando um formulário:
Em seguida, ligue para o setter ao enviar:
Mas continue a ler ...
Resposta longa e correta:
Você também não deseja mostrar esta mensagem quando o usuário não alterou nada nos seus formulários . Uma solução é usar o
beforeunload
evento em combinação com um sinalizador "sujo", que somente aciona o prompt se for realmente relevante.Agora, para implementar o
isDirty
método, existem várias abordagens.Você pode usar jQuery e serialização de formulários , mas essa abordagem tem algumas falhas. Primeiro, você precisa alterar o código para funcionar de qualquer forma (o
$("form").each()
que funcionará), mas o maior problema é que o jQueryserialize()
funcionará apenas em elementos nomeados e não desativados; portanto, alterar qualquer elemento desativado ou não nomeado não acionará o sinalizador sujo. Existem soluções alternativas para isso , como fazer controles somente leitura em vez de habilitar, serializar e desabilitar os controles novamente.Então os eventos parecem o caminho a percorrer. Você pode tentar ouvir as teclas pressionadas . Este evento tem alguns problemas:
O
change
evento também não dispara nos valores definidos no código JavaScript , também não funciona para entradas virtuais.Vinculando o
input
evento para todos osinput
s (etextarea
s eselect
s) na sua página não irá funcionar em navegadores mais antigos e, como todas as soluções de tratamento de evento mencionado acima, não suporta desfazer. Quando um usuário altera uma caixa de texto e a desfaz, ou marca e desmarca uma caixa de seleção, o formulário ainda é considerado sujo.E quando você deseja implementar mais comportamentos, como ignorar certos elementos, terá ainda mais trabalho a fazer.
Não reinvente a roda:
Portanto, antes de pensar em implementar essas soluções e todas as soluções necessárias, perceba que você está reinventando a roda e está propenso a encontrar problemas que outras pessoas já resolveram para você.
Se seu aplicativo já usa jQuery, você também pode usar código testado e mantido em vez de criar o seu próprio e usar uma biblioteca de terceiros para tudo isso. jQuery tem certeza? plugin funciona muito bem, veja sua página de demonstração . É simples assim:
Mensagens personalizadas não suportadas em qualquer lugar
Observe que o Firefox 4 não suporta mensagens personalizadas nesta caixa de diálogo. A partir de abril de 2016, o Chrome 51 está sendo implementado, no qual as mensagens personalizadas também estão sendo removidas .
Algumas alternativas existem em outras partes deste site, mas acho que uma caixa de diálogo como essa é clara o suficiente:
fonte
Confira o evento JavaScript onbeforeunload . É um JavaScript não padrão introduzido pela Microsoft, no entanto, funciona na maioria dos navegadores e sua documentação onbeforeunload tem mais informações e exemplos.
fonte
via jquery
Você pode usar a função Serializar formulário do Google JQuery, isso irá coletar todas as entradas do formulário e salvá-lo na matriz. Eu acho que essa explicação é suficiente :)
fonte
Solução universal que não requer configuração que detecte automaticamente todas as modificações de entrada, incluindo elementos editáveis por conteúdo:
fonte
Construído sobre a excelente idéia de Wasim A. de usar serialização. O problema era que o aviso também era mostrado quando o formulário estava sendo enviado. Isso foi corrigido aqui.
Foi testado no Chrome e IE 11.
fonte
Com base nas respostas anteriores e reunidas de vários lugares no estouro de pilha, eis a solução que eu criei que lida com o caso quando você realmente deseja enviar suas alterações:
Vale ressaltar que o IE11 parece exigir que a
closeEditorWarning
função retorneundefined
para não mostrar um alerta.fonte
QC.thisPage.isDirty = false;
serwindow.thisPage.isDirty = false;
? Dessa forma, ele verificará se você está enviando o formulário e não mostra um aviso. Parecia funcionar para os meus testes. Além disso, a maioria dos formulários possui uminput
e não umtextarea
. Eu usei o seguinte, que funciona bastante bem: #$("form").on('keyup', 'textarea,input,select', function () {
A seguinte linha funcionou para mim.
Basta definir
modified
como verdadeiro ou falso, dependendo do estado do seu aplicativo.fonte
undefined
vez denull
o IE imprimir 'null' semodified
for falso.O código a seguir funciona muito bem. Você precisa acessar as alterações de entrada dos elementos do formulário por meio do atributo id:
fonte
fonte
Você pode usar serialize () para criar uma sequência de texto codificada em URL serializando os valores do formulário e verificar se o formulário foi alterado antes da transferência
Consulte este link https://coderwall.com/p/gny70a/alert-when-leaving-page-with-unsaved-form Escrito por Vladimir Sidorenko
fonte
serialize()
, e de fato, ele tem suas desvantagens.Adicionando à idéia do @codecaster, você pode adicioná-lo a todas as páginas com um formulário (no meu caso, eu o uso de maneira global, para que apenas nos formulários o aviso) altere sua função para
Também envie formulários, incluindo links de login e botões de cancelamento, para que quando a pessoa pressionar cancelar ou enviar o formulário não acionar o aviso também em todas as páginas com um formulário ...
fonte
Você pode verificar uma explicação detalhada aqui: http://techinvestigations.redexp.in/comparison-of-form-values-on-load-and-before-close/ comparação-de-forma-valores-em-carga-e -before-close
O código principal:
fonte
Resposta curta:
fonte
A solução de Eerik Sven Puudist ...
... fez o trabalho espontaneamente para mim em um cenário complexo orientado a objetos, sem as alterações necessárias.
A única alteração que apliquei foi me referir ao formulário concreto (apenas um formulário por arquivo) chamado "formForm" ('form' -> '#formForm'):
Especialmente bem feito é o fato de que o botão enviar está sendo "deixado em paz".
Além disso, ele funciona para mim também com a versão mais recente do Firefox (a partir de 7 de fevereiro de 2019).
fonte
Testado a solução universal de Eli Grey, só funcionou depois que simplifiquei o código para
As modificações nele são excluídas do uso
target[defaultValue]
e uso exclusivotarget.dataset[defaultValue]
para armazenar o valor padrão real.E eu adicionei um ouvinte de evento 'salvo', onde o evento 'salvo' será acionado por você mesmo em sua ação de salvamento bem-sucedida.
Mas essa solução "universal" funciona apenas em navegadores, não na visualização da web do aplicativo, por exemplo, nos navegadores.
Para fazê-lo funcionar também nos navegadores wechat (parcialmente), outras melhorias:
fonte
Fiz isso de maneira diferente, compartilhando aqui para que alguém possa obter ajuda, testado apenas com o Chrome.
Eu queria avisar o usuário antes de fechar a guia apenas se houver algumas alterações.
Funciona bem, mas tenho outro problema. Quando envio o formulário, recebo o aviso indesejado, vi muitas soluções alternativas, isso ocorre porque onbeforeunload dispara antes do onsubmit, é por isso que não podemos lidar com isso no evento onsubmit como
onbeforeunload = null
, mas O evento onclick do botão enviar é acionado antes desses dois eventos, então atualizei o códigofonte
Primeiro de tudo, a maioria dos navegadores tem essa função por padrão. E por que você precisa disso? Por que não manter o formulário sincronizado? Quero dizer, salve-o em qualquer alteração sem esperar nenhum envio do usuário. Como os Contatos do Google fazem. Obviamente, se apenas todos os campos no formulário forem obrigatórios. Os usuários não gostam de quando forçam a preencher algo sem a oportunidade de ir embora para pensar se precisam. :)
fonte
save it on any change without waiting any submitting from user
Você nem sempre quer fazer isso. Às vezes, o usuário deseja fazer muitas alterações, revisar e confirmar que deseja salvá-lo.