jQuery

индекс
283,92

Дополненный jQuery FormNavigate или «не дай юзеру потерять данные»

Однажды на просторах Хабра встретил плагин FormNavigate (требующий у пользователя подтверждения на закрытие вкладки или переход по ссылке, когда данные в форме заполнены, а-ля gmail), а однажды потребовалось его даже применить.

Но тот вид в котором плагин был меня не устроил и я позволил себе немного его переписать.

Так, например, мне неудобно было выбирать те ссылки, на которых следует отлавливать подтверждения, а наоборот требовалось указывать ссылки на которые действие плагина не будет распространяться. Тут продвинутые разработчики начнут меня закидывать помидорами, что я не знаю правильную работу селекторов в jQuery. Но это не так, сами можете проверить как работает прошлая версия плагина, например, для: $('a:not([class~="ajax"])') (предложенный автором прошлого топика $('a:[class!="ajax"]') вообще вытворяла чудеса).

Что стыда скрывать, я позволил себе немного переписать плагин:
  1. jQuery.fn.extend({
  2.   FormNavigate: function(o){
  3.     var formdata_original = true;
  4.     jQuery(window).bind('beforeunload', function (){
  5.       if (!formdata_original) return settings.message;
  6.     });
  7.  
  8.     var def = {
  9.       message: '',
  10.       aOutConfirm: 'a:not([target!=_blank])'
  11.     };
  12.     var settings = jQuery.extend(false, def, o);
  13.  
  14.     if (o.aOutConfirm && o.aOutConfirm != def.aOutConfirm){
  15.       jQuery('a').addClass('aOutConfirmPlugin');
  16.       jQuery(settings.aOutConfirm).removeClass("aOutConfirmPlugin");
  17.       jQuery(settings.aOutConfirm).click(function(){
  18.         formdata_original = true;
  19.         return true;
  20.       });
  21.     }
  22.  
  23.     jQuery("a.aOutConfirmPlugin").click(function(){
  24.       if (formdata_original == false)
  25.         if(confirm(settings.message))
  26.           formdata_original = true;
  27.       return formdata_original;
  28.     });
  29.  
  30.     jQuery(this).find("input[type=text], textarea, input[type='password'], input[type='radio'], input[type='checkbox'], input[type='file']").live('change keypress', function(event){
  31.       formdata_original = false;
  32.     });
  33.  
  34.     jQuery(this).find(":submit, input[type='image']").click(function(){
  35.       formdata_original = true;
  36.     });
  37.   }
  38. });
* This source code was highlighted with Source Code Highlighter.


Пример использования:
  1.   $(document).ready(function(){
  2.     $("#changeme").FormNavigate({
  3.       message: "Содержимое было изменено!\nВы уверены, что хотите покинуть страницу без сохранения?",
  4.       aOutConfirm: "a.ignore"
  5.     });
  6.   });
* This source code was highlighted with Source Code Highlighter.

где
message — текстовая информация в окошке подтверждения,
aOutConfirm — теги игнорируемые на подтверждение.

Исправлены некоторые проблемы, например, переопределения события onbeforeunload, неправильной работы с текстовым полем (textarea).

Скачать исправленную версию.
Посмотреть пример.

Надеюсь Вам это пригодится!
+21
5 июля 2010, 23:23
68

комментарии (19)

+3
Stark #
Можно еще прикрутить сохранялку введенных данных в локалсторадж, и тогда даже краш браузера не будет страшен :)
0
leonnash #
в опере 10.60 никаких подтверждений
0
AlexSuslin #
да и в хроме ничего не работает
0
aleXoid #
В нестабильном канале Chrome 6.0.453.1 Dev все в порядке. Хочется услышать специалистов по Opera, куда копнуть — у нас до 35% посещений из-под Opera…
+1
w0den #
Решить проблему... Узнать почему Opera не поддерживает onbeforeunload — можно здесь: Javascript and History Navigation
0
ZaiSL #
Угу( Страшно вспомнить, как некоторое время назад перевернула полтырнета в попытках найти решение для Opera и потоооом только заглянула в спецификацию (посыпаю голову пеплом). Обидно(
0
DonSleza4e #
в хроме работает 5.0.375.86
нужно незабыть изменить данные формы
0
Denai #
Ссылку на яндекс поправьте, а то браузеры в шоке
+1
rvsob #
Упс, извините, исправил…
0
noRerih #
Код плагина опенсорсный, вы пропатчили форк?)
0
rvsob #
Да, я честно написал об этом…
0
noRerih #
Вы меня не поняли. Имелся в виду коммит и пуш своих изменений в оригинальный репозиторий (посильный вклад в развитие плагина). Вопрос снимается, исходников там оказывается нет, доступны только downloads.
–1
CAH4A #
Вы написали плагином одну строчку?

$('a').live('click', function(){ $(this).isA(aOutConfirm) || !confirm(message) || return; });
0
rvsob #
Я плагин не писал, я немного переписал и об этом честно написал в посте.

А Ваш комментарий более уместен в топике, ссылку на который я привел в начале этого блога.
+1
CAH4A #
Забираю свой код обратно!-)
0
DonSleza4e #
спасибо, пригодился
сейчас тестирую в реальном приложении)
0
SpirITzzz #
Да, изменения мелкие, но нужные, добавлю ссылку на этот топик из своего топика :)
0
DjOnline #
live('change keypress') не отслеживает выделение мышью и нажатие клавиши del.
0
pelenka #
как быть со скрытыми полями, которые меняются яваскриптом?
добавление input[type='hidden'] в 30ю строку не помогает

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.