From 9557908875af76d167797a36e980798349fc63b5 Mon Sep 17 00:00:00 2001 From: Stefan Parviainen Date: Thu, 1 Jan 2015 12:32:15 +0100 Subject: Warn about unsaved settings using jquery.areyousure --- library/jquery.AreYouSure/.gitignore | 166 ++++++ library/jquery.AreYouSure/Gruntfile.js | 26 + library/jquery.AreYouSure/README.md | 297 +++++++++++ library/jquery.AreYouSure/are-you-sure.jquery.json | 39 ++ library/jquery.AreYouSure/ays-beforeunload-shim.js | 31 ++ library/jquery.AreYouSure/bower.json | 30 ++ .../jquery.AreYouSure/demo/are-you-sure-demo.html | 576 +++++++++++++++++++++ library/jquery.AreYouSure/jquery.are-you-sure.js | 192 +++++++ library/jquery.AreYouSure/package.json | 45 ++ .../spec/javascripts/fixtures/input-text.html | 4 + .../spec/javascripts/jquery.are-you-sure_spec.js | 28 + 11 files changed, 1434 insertions(+) create mode 100644 library/jquery.AreYouSure/.gitignore create mode 100644 library/jquery.AreYouSure/Gruntfile.js create mode 100644 library/jquery.AreYouSure/README.md create mode 100644 library/jquery.AreYouSure/are-you-sure.jquery.json create mode 100644 library/jquery.AreYouSure/ays-beforeunload-shim.js create mode 100644 library/jquery.AreYouSure/bower.json create mode 100644 library/jquery.AreYouSure/demo/are-you-sure-demo.html create mode 100644 library/jquery.AreYouSure/jquery.are-you-sure.js create mode 100644 library/jquery.AreYouSure/package.json create mode 100644 library/jquery.AreYouSure/spec/javascripts/fixtures/input-text.html create mode 100644 library/jquery.AreYouSure/spec/javascripts/jquery.are-you-sure_spec.js (limited to 'library/jquery.AreYouSure') diff --git a/library/jquery.AreYouSure/.gitignore b/library/jquery.AreYouSure/.gitignore new file mode 100644 index 000000000..345f0dbeb --- /dev/null +++ b/library/jquery.AreYouSure/.gitignore @@ -0,0 +1,166 @@ +################# +## Eclipse +################# + +*.pydevproject +.project +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.classpath +.settings/ +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# CDT-specific +.cproject + +# PDT-specific +.buildpath + + +################# +## Visual Studio +################# + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results +[Dd]ebug/ +[Rr]elease/ +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.vspscc +.builds +*.dotCover + +## TODO: If you have NuGet Package Restore enabled, uncomment this +#packages/ + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf + +# Visual Studio profiler +*.psess +*.vsp + +# ReSharper is a .NET coding add-in +_ReSharper* + +# Installshield output folder +[Ee]xpress + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish + +# Others +[Bb]in +[Oo]bj +sql +TestResults +*.Cache +ClientBin +stylecop.* +~$* +*.dbmdl +Generated_Code #added for RIA/Silverlight projects + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML + + + +############ +## Windows +############ + +# Windows image file caches +Thumbs.db + +# Folder config file +Desktop.ini + + +############# +## Python +############# + +*.py[co] + +# Packages +*.egg +*.egg-info +dist +build +eggs +parts +bin +var +sdist +develop-eggs +.installed.cfg + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox + +#Translations +*.mo + +#Mr Developer +.mr.developer.cfg + +# Mac crap +.DS_Store + +bower_components/ +node_modules/ diff --git a/library/jquery.AreYouSure/Gruntfile.js b/library/jquery.AreYouSure/Gruntfile.js new file mode 100644 index 000000000..efca34c0a --- /dev/null +++ b/library/jquery.AreYouSure/Gruntfile.js @@ -0,0 +1,26 @@ +module.exports = function(grunt) { + grunt.config.init({ + karma: { + options: { + browsers: [ 'Chrome', 'Firefox', 'Safari', 'IE' ], + frameworks: [ 'jasmine' ], + reportSlowerThan: 500, + singleRun: true + }, + unit: { + files: [ + { pattern: 'bower_components/jquery/dist/jquery.min.js' }, + { pattern: 'bower_components/jasmine-jquery/lib/jasmine-jquery.js' }, + { pattern: 'jquery.are-you-sure.js' }, + { pattern: 'spec/javascripts/*.js' }, + { pattern: 'spec/javascripts/fixtures/**/*.html', included: false } + ] + } + } + }); + + grunt.registerTask('test', 'Run tests.', [ 'karma' ]); + grunt.registerTask('default', [ 'test' ]); + + grunt.loadNpmTasks('grunt-karma'); +}; diff --git a/library/jquery.AreYouSure/README.md b/library/jquery.AreYouSure/README.md new file mode 100644 index 000000000..6a538648a --- /dev/null +++ b/library/jquery.AreYouSure/README.md @@ -0,0 +1,297 @@ +Are You Sure? - A light "dirty forms" JQuery Plugin +====== +**Version:** 1.9 + +*Are-you-sure* (```jquery.are-you-sure.js```) is simple light-weight "dirty +form" JQuery Plugin for modern browsers. It helps prevent users from losing +unsaved HTML Form changes by promoting the user to save/submit. + +It's simple to use. Just add the following line to your page's ready +function: + +```javascript +$('form').areYouSure(); +``` + +*Are-you-sure* is a minimal plugin for modern browsers. There are plenty of +"dirty forms" implementations out there, however they all seemed very +heavyweight and over-engineered...! Most were written some time back and +contain many 'hacks' to support legacy browsers, and/or rely on other fat +dependencies such as FaceBox or jQueryUI. *Are-you-sure* solves this by +doing this simple task in the simplest possible way. + +*Are-you-sure* is as simple as it gets: + + * 100% JS with zero dependencies and no external CSS. + * Leverages `onBeforeUnload` to detect all page/browser exit events. + * Works on forms of any size. + * Correct state management - if a user edits then restores a value, the form + is not considered dirty. + * Easy to understand - less than a "terminal screen" of code! + * Graceful degradation on legacy browsers (i.e. if you're running an old + browser... remember to save :-) + +###Basic Usage + +```javascript + +$(function() { + + // Enable on all forms + $('form').areYouSure(); + + // Enable on selected forms + $('form.dirty-check').areYouSure(); + + // With a custom message + $('form').areYouSure( {'message':'Your profile details are not saved!'} ); + +} +``` +To ignore selected fields from the dirtyness check: + +```html +
+ + Field 1: (checked)
+ Field 2: (ignored):
+ Field 3: (ignored):
+ + + +
+``` + +###Advanced Usage + +```javascript + +$(function() { + + /* + * Make Are-You-Sure "silent" by disabling the warning message + * (tracking/monitoring only mode). This option is useful when you wish to + * use the dirty/save events and/or use the dirtyness tracking in your own + * beforeunload handler. + */ + $('form').areYouSure( {'silent':true} ); + + /* + * Dirtyness Change Events + * Are-You-Sure fires off "dirty" and "clean" events when the form's state + * changes. You can bind() or on(), these events to implement your own form + * state logic. A good example is enabling/disabling a Save button. + * + * "this" refers to the form that fired the event. + */ + $('form').on('dirty.areYouSure', function() { + // Enable save button only as the form is dirty. + $(this).find('input[type="submit"]').removeAttr('disabled'); + }); + $('form').on('clean.areYouSure', function() { + // Form is clean so nothing to save - disable the save button. + $(this).find('input[type="submit"]').attr('disabled', 'disabled'); + }); + + /* + * It's easy to test if a form is dirty in your own code - just check + * to see if it has a "dirty" CSS class. + */ + if ($('#my-form').hasClass('dirty')) { + // Do something + } + + /* + * If you're dynamically adding new fields/inputs, and would like to track + * their state, trigger Are-You-Sure to rescan the form like this: + */ + $('#my-form').trigger('rescan.areYouSure'); + + /* + * If you'd like to reset/reinitialize the form's state as clean and + * start tracking again from this new point onwards, trigger the + * reinitalize as follows. This is handy if say you've managing your + * own form save/submit via asyc AJAX. + */ + $('#my-form').trigger('reinitialize.areYouSure'); + + /* + * In some situations it may be desirable to look for other form + * changes such as adding/removing fields. This is useful for forms that + * can change their field count, such as address/phone contact forms. + * Form example, you might remove a phone number from a contact form + * but update nothing else. This should mark the form as dirty. + */ + $('form').areYouSure( {'addRemoveFieldsMarksDirty':true} ); + + /* + * Sometimes you may have advanced forms that change their state via + * custom JavaScript or 3rd-party component JavaScript. Are-You-Sure may + * not automatically detect these state changes. Examples include: + * - Updating a hidden input field via background JS. + * - Using a [rich WYSIWYG edit control](https://github.com/codedance/jquery.AreYouSure/issues/17). + * One solution is to manually trigger a form check as follows: + */ + $('#my-form').trigger('checkform.areYouSure'); + + /* + * As an alternative to using events, you can pass in a custom change + * function. + */ + $('#my-adv-form').areYouSure({ + change: function() { + // Enable save button only if the form is dirty. i.e. something to save. + if ($(this).hasClass('dirty')) { + $(this).find('input[type="submit"]').removeAttr('disabled'); + } else { + $(this).find('input[type="submit"]').attr('disabled', 'disabled'); + } + } + }); + + /* + * Mixing in your own logic into the warning. + */ + $('#my-form').areYouSure( {'silent':true} ); + $(window).on('beforeunload', function() { + isSunday = (0 == (new Date()).getDay()); + if ($('#my-form').hasClass('dirty') && isSunday) { + return "Because it's Sunday, I'll be nice and let you know you forgot to save!"; + } + } + +} +``` +The [demo page](http://www.papercut.com/products/free_software/are-you-sure/demo/are-you-sure-demo.html) +shows the advanced usage options in more detail. + + +###Install +Are-You-Sure is a light-weight jQuery plugin - it's a single standalone +JavaScript file. You can download the +[jquery.are-you-sure.js](https://raw.github.com/codedance/jquery.AreYouSure/master/jquery.are-you-sure.js) +file and include it in your page. Because it's so simple it seems a shame +to add an extra browser round trip. It's recommended that you consider +concatenating it with other common JS lib files, and/or even cut-n-pasting +the code (and license header) into one of your existing JS files. + +For experimental Mobile Safari support, also include ```ays-beforeunload-shim.js``` +(see Known Issues below). + +*Are-you-sure* may also be installed with [Bower](http://twitter.github.com/bower/): + +```bash +$ bower install jquery.are-you-sure +``` + +If you're using, or like, *Are-you-sure* make sure you **star/watch** this project +so you can stay up-to-date with updates. + +###Demo +This [demo page](http://www.papercut.com/products/free_software/are-you-sure/demo/are-you-sure-demo.html) +hosts a number of example forms. + +###Supported Browsers +*Are-you-sure* has been tested on and fully supports the following browsers: + +* IE 9 through 11 +* Google Chrome (versions since 2012) +* Firefox (versions since 2012) +* Safari (versions since 2012) + +Experimental support is available on iOS and Opera via the *beforeunload* shim (see below). + +###Known Issues & Limitations + +####Mobile Safari and Opera +The ```windows.beforeunload``` event is not supported on iOS (iPhone, iPad, and iPod). An +experimental shim offering partial *beforeunload* emulation is provided to help plug this gap. +It works by scanning the page for anchor links and augments the default behaviour to first +check with *Are-you-sure* before navigating away. To use, simply include +```ays-beforeunload-shim.js``` in your page. + +####Firefox +The custom message option may not work on Firefox ([Firefox bug 588292](https://bugzilla.mozilla.org/show_bug.cgi?id=588292)). + +###Development +The aim is to keep *Are-you-sure* simple and light. If you think you have +a good idea which is aligned with this objective, please voice your thoughts +in the issues list. + +####Pull Requests +If possible, please submit your pull request against the most recent ```dev-*``` branch rather than master. This will make it easier to merge your code into the next planned release. + +####Running tests +```bash +$ npm install +$ npm test +``` + +###Release History + +**2014-08-13** (1.9) - This is a minor bugfix release: + +* Addressed issue [#45](https://github.com/codedance/jquery.AreYouSure/issues/55) seen with empty select fields. +* Thanks [valgen](https://github.com/valgen) and [tus124](https://github.com/tus124) for the contribution. + +**2014-06-22** (1.8) - This is a minor bugfix release: + +* Fixed NPE that may occur when using a 'multiple' option field. +* Minor timing tweak to help mitigate bypass issue raised in [#45](https://github.com/codedance/jquery.AreYouSure/issues/45) +* Thanks [apassant](https://github.com/apassant) and [amatenkov](https://github.com/amatenkov) for the contribution. + +**2014-05-28** (1.7) + +* Fixed multiple warning dialogs that may appear on IE and recent versions of Chrome +* Experimental support for iOS Mobile Safari (via a *beforeunload* shim) +* Various minor fixes (e.g. support input fields with no type=) +* Minor performance improvements on pages with multiple forms +* Improved documentation and examples +* Thanks to [lfjeff](https://github.com/lfjeff) and [aqlong](https://github.com/aqlong) for the contribution and ideas! + +**2014-02-07** (1.6) + +* Add field count tracking (```addRemoveFieldsMarksDirty```) (contrib *jonegerton*) +* Added event to manually trigger a form check/recheck (contrib *jonegerton*) +* Thanks to [jonegerton](https://github.com/jonegerton) for the contribution! + +**2013-11-15** (1.5) + +* Added support for HTML5 input field types. (contrib *albinsunnanbo*) +* New option to reinitialize/reset the dirty state. This is handy if you're managing your own async submit/save using AJAX. (contrib *albinsunnanbo*) +* Thanks to [albinsunnanbo](https://github.com/albinsunnanbo) for the contribution! + +**2013-10-2** (1.4) + +* Added dirty and clean "events" +* Added an option to disable the message (dirty tracking only) +* Added an option to rescan a form to look/detect any new fields + +**2013-07-24** - Minor fix - don't fail if form elements have no "name" attribute. + +**2013-05-14** - Added support for form reset buttons (contributed by codev). + +**2013-05-01** - Added support for hidden and disabled form fields. + +**2013-02-03** - Add demo page. + +**2013-01-28** - Add ```change``` event support and a demo page. + +**2012-10-26** - Use dashes in class names rather than camel case. + +**2012-10-24** - Initial public release. + + +###Prerequisites +jQuery version 1.4.2 or higher. 2.0+ or 1.10+ recommended. + + +###License +The same as JQuery... + + jQuery Plugin: Are-You-Sure (Dirty Form Detection) + https://github.com/codedance/jquery.AreYouSure/ + + Copyright (c) 2012-2014, Chris Dance - PaperCut Software http://www.papercut.com/ + Dual licensed under the MIT or GPL Version 2 licenses. + http://jquery.org/license diff --git a/library/jquery.AreYouSure/are-you-sure.jquery.json b/library/jquery.AreYouSure/are-you-sure.jquery.json new file mode 100644 index 000000000..9c699b72b --- /dev/null +++ b/library/jquery.AreYouSure/are-you-sure.jquery.json @@ -0,0 +1,39 @@ +{ + "name": "are-you-sure", + "title": "Are You Sure? - a dirty forms check plugin", + "description": "Are-you-sure is simple light-weight dirty forms JQuery Plugin for modern browsers. It helps prevent users from loosing unsaved form changes by prompting the user to save/submit. It's dependency free and designed for modern browsers... just the features you need and nothing more! See the project page and demo for usage and examples.", + "keywords": [ + "form", + "dirty", + "field", + "change", + "save", + "save-check", + "save-warning" + ], + "version": "1.9.0", + "author": { + "name": "Chris Dance (codedance) at PaperCut Software", + "url": "https://github.com/codedance" + }, + "maintainers": [ + { + "name": "Chris Dance", + "email": "chris.dance@papercut.com", + "url": "http://www.papercut.com/" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/codedance/jquery.AreYouSure/blob/master/README.md" + } + ], + "bugs": "https://github.com/codedance/jquery.AreYouSure/issues", + "homepage": "https://github.com/codedance/jquery.AreYouSure", + "docs": "https://github.com/codedance/jquery.AreYouSure", + "demo": "http://www.papercut.com/products/free_software/are-you-sure/demo/are-you-sure-demo.html", + "dependencies": { + "jquery": ">=1.4.2" + } +} diff --git a/library/jquery.AreYouSure/ays-beforeunload-shim.js b/library/jquery.AreYouSure/ays-beforeunload-shim.js new file mode 100644 index 000000000..cb864cdeb --- /dev/null +++ b/library/jquery.AreYouSure/ays-beforeunload-shim.js @@ -0,0 +1,31 @@ +/*! + * An experimental shim to partially emulate onBeforeUnload on iOS. + * Part of https://github.com/codedance/jquery.AreYouSure/ + * + * Copyright (c) 2012-2014, Chris Dance and PaperCut Software http://www.papercut.com/ + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Author: chris.dance@papercut.com + * Date: 19th May 2014 + */ +$(function() { + if (!navigator.userAgent.toLowerCase().match(/iphone|ipad|ipod|opera/)) { + return; + } + $('a').bind('click', function(evt) { + var href = $(evt.target).closest('a').attr('href'); + if (href !== undefined && !(href.match(/^#/) || href.trim() == '')) { + var response = $(window).triggerHandler('beforeunload', response); + if (response && response != "") { + var msg = response + "\n\n" + + "Press OK to leave this page or Cancel to stay."; + if (!confirm(msg)) { + return false; + } + } + window.location.href = href; + return false; + } + }); +}); diff --git a/library/jquery.AreYouSure/bower.json b/library/jquery.AreYouSure/bower.json new file mode 100644 index 000000000..8591dc0d0 --- /dev/null +++ b/library/jquery.AreYouSure/bower.json @@ -0,0 +1,30 @@ +{ + "name": "jquery.are-you-sure", + "version": "1.9.0", + "homepage": "https://github.com/codedance/jquery.AreYouSure", + "authors": [ + "CodeDance " + ], + "description": "A light-weight jQuery 'dirty forms' Plugin - it monitors html forms and alerts users to unsaved changes if they attempt to close the browser or navigate away from the page. (Are you sure?)", + "main": "jquery.are-you-sure.js", + "keywords": [ + "form", + "dirty", + "field", + "change", + "save-check", + "are-you-sure", + "save-warning" + ], + "license": "MIT/GPLv2", + "ignore": [ + "**/.*", + "demo" + ], + "dependencies": { + "jquery": ">=1.4.2" + }, + "devDependencies": { + "jasmine-jquery": "~2.0.3" + } +} diff --git a/library/jquery.AreYouSure/demo/are-you-sure-demo.html b/library/jquery.AreYouSure/demo/are-you-sure-demo.html new file mode 100644 index 000000000..3f0327b2e --- /dev/null +++ b/library/jquery.AreYouSure/demo/are-you-sure-demo.html @@ -0,0 +1,576 @@ + + + + Demo: Are You Sure? - a dirty forms jQuery Plugin + + + + + + + + + + + + +

jQuery Plugin Demo: Are You Sure?

+

+ This page hosts a demo of the jQuery Are-You-Sure plugin (jquery.are-you-sure.js). +

+

+ Are-you-sure is simple light-weight "dirty forms" JQuery Plugin for modern browsers. It helps prevent users from loosing unsaved form changes. +

+

+ Features: +

+

+ +

Example 1: It's simple!

+

+ This example shows how easy it is to add a dirty check to your form(s) with one line + of code. (View the page's source) +

+ +
+

Enter Your Coffee Order

+
+ + +
+
+
+ 1 Shot - Standard
+ 2 Shots - Morning wakeup!
+ 3 Shots - Overdrive!
+
+
+ +
+
+ + +
+ +
+ Remember my order
+ + +
+
+

... or visit Google or close the window without saving!

+
+
+ +

Example 2: Ignore the unimportant!

+

+ This example highlights how to disregard a field from the dirty check. In this form + the first field is dynamically populated and hence a change on this field should not + mark the form as dirty. +

+
+

Enter Your Coffee Order

+
+ + + + +
+
+ + +
+
+
+ 1 Shot - Standard
+ 2 Shots - Morning wakeup!
+ 3 Shots - Overdrive!
+
+
+ +
+
+ + +
+ +
+ Remember my order
+ +
+
+

... or visit Google or close the window without saving!

+
+
+ + +

Example 3: Lets be intelligent!

+

+ This is a more advanced example. The dirty and clean change events are + intercepted so the save button is only enabled if the form is dirty (i.e. something to save). + It also demonstrates how to customize the warning message and change the style of a dirty + form (CSS styling using the .dirty class). +

+
+

Update My Standard Order

+
+ + +
+
+
+ 1 Shot - Standard
+ 2 Shots - Morning wakeup!
+ 3 Shots - Overdrive!
+
+
+ + +
+
+ + +
+ +
+ +
+
+

... or visit Google or close the window without saving!

+
+
+ +

Example 4: Lets be dynamic!

+

+ In this example we'll dymaically add a field and fire off the rescan event. After + the rescan, Are-You-Sure will start looking for changes on the new fields as well. +

+
+

Order Coffee For Pickup Now

+
+ Set my preferences from my last order
+
+
+ + +
+
+
+ +
+
+

... or visit Google or close the window without saving!

+
+
+ +

Example 5: Edge cases

+

+ This example demonstrates tracking of hidden and disabled form elements that are changed by non-input elements. + E.g.: +

+ +
+

Update My Standard Order

+
+ + +
+
+ + + + +
+
+ + + +
+
+ +
+
+

... or visit Google or close the window without saving!

+
+
+ +

Example 6: HTML5 inputs!

+

+ This example shows support for HTML5 input types. It's not a coffee order form, + but you need coffee if you're working with HTML5 :-) +

+ +
+

Doing HTML5? You'll need coffee!

+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+ +
+ + +
+
+

... or visit Google or close the window without saving!

+
+
+

Example 7: Mark current state as not dirty!

+

+ This example shows how you can mark the current state as not dirty. Handy for AJAX forms + we're you're managing your own submits. +

+ +
+

Tell us your default coffee

+
+ + +
+
+ +
+
+ +
+
+

... or visit Google or close the window without saving!

+
+
+ +

+ This jQuery plugin is developed by Chris Dance + at PaperCut Software - Are-You-Sure is used in + PaperCut's printing management software and it has been open sourced with help of + Tom, Jack and Matt from PaperCut's dev team. +

+ + + diff --git a/library/jquery.AreYouSure/jquery.are-you-sure.js b/library/jquery.AreYouSure/jquery.are-you-sure.js new file mode 100644 index 000000000..3c41e2fcc --- /dev/null +++ b/library/jquery.AreYouSure/jquery.are-you-sure.js @@ -0,0 +1,192 @@ +/*! + * jQuery Plugin: Are-You-Sure (Dirty Form Detection) + * https://github.com/codedance/jquery.AreYouSure/ + * + * Copyright (c) 2012-2014, Chris Dance and PaperCut Software http://www.papercut.com/ + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Author: chris.dance@papercut.com + * Version: 1.9.0 + * Date: 13th August 2014 + */ +(function($) { + + $.fn.areYouSure = function(options) { + + var settings = $.extend( + { + 'message' : 'You have unsaved changes!', + 'dirtyClass' : 'dirty', + 'change' : null, + 'silent' : false, + 'addRemoveFieldsMarksDirty' : false, + 'fieldEvents' : 'change keyup propertychange input', + 'fieldSelector': ":input:not(input[type=submit]):not(input[type=button])" + }, options); + + var getValue = function($field) { + if ($field.hasClass('ays-ignore') + || $field.hasClass('aysIgnore') + || $field.attr('data-ays-ignore') + || $field.attr('name') === undefined) { + return null; + } + + if ($field.is(':disabled')) { + return 'ays-disabled'; + } + + var val; + var type = $field.attr('type'); + if ($field.is('select')) { + type = 'select'; + } + + switch (type) { + case 'checkbox': + case 'radio': + val = $field.is(':checked'); + break; + case 'select': + val = ''; + $field.find('option').each(function(o) { + var $option = $(this); + if ($option.is(':selected')) { + val += $option.val(); + } + }); + break; + default: + val = $field.val(); + } + + return val; + }; + + var storeOrigValue = function($field) { + $field.data('ays-orig', getValue($field)); + }; + + var checkForm = function(evt) { + + var isFieldDirty = function($field) { + var origValue = $field.data('ays-orig'); + if (undefined === origValue) { + return false; + } + return (getValue($field) != origValue); + }; + + var $form = ($(this).is('form')) + ? $(this) + : $(this).parents('form'); + + // Test on the target first as it's the most likely to be dirty + if (isFieldDirty($(evt.target))) { + setDirtyStatus($form, true); + return; + } + + $fields = $form.find(settings.fieldSelector); + + if (settings.addRemoveFieldsMarksDirty) { + // Check if field count has changed + var origCount = $form.data("ays-orig-field-count"); + if (origCount != $fields.length) { + setDirtyStatus($form, true); + return; + } + } + + // Brute force - check each field + var isDirty = false; + $fields.each(function() { + $field = $(this); + if (isFieldDirty($field)) { + isDirty = true; + return false; // break + } + }); + + setDirtyStatus($form, isDirty); + }; + + var initForm = function($form) { + var fields = $form.find(settings.fieldSelector); + $(fields).each(function() { storeOrigValue($(this)); }); + $(fields).unbind(settings.fieldEvents, checkForm); + $(fields).bind(settings.fieldEvents, checkForm); + $form.data("ays-orig-field-count", $(fields).length); + setDirtyStatus($form, false); + }; + + var setDirtyStatus = function($form, isDirty) { + var changed = isDirty != $form.hasClass(settings.dirtyClass); + $form.toggleClass(settings.dirtyClass, isDirty); + + // Fire change event if required + if (changed) { + if (settings.change) settings.change.call($form, $form); + + if (isDirty) $form.trigger('dirty.areYouSure', [$form]); + if (!isDirty) $form.trigger('clean.areYouSure', [$form]); + $form.trigger('change.areYouSure', [$form]); + } + }; + + var rescan = function() { + var $form = $(this); + var fields = $form.find(settings.fieldSelector); + $(fields).each(function() { + var $field = $(this); + if (!$field.data('ays-orig')) { + storeOrigValue($field); + $field.bind(settings.fieldEvents, checkForm); + } + }); + // Check for changes while we're here + $form.trigger('checkform.areYouSure'); + }; + + var reinitialize = function() { + initForm($(this)); + } + + if (!settings.silent && !window.aysUnloadSet) { + window.aysUnloadSet = true; + $(window).bind('beforeunload', function() { + $dirtyForms = $("form").filter('.' + settings.dirtyClass); + if ($dirtyForms.length == 0) { + return; + } + // Prevent multiple prompts - seen on Chrome and IE + if (navigator.userAgent.toLowerCase().match(/msie|chrome/)) { + if (window.aysHasPrompted) { + return; + } + window.aysHasPrompted = true; + window.setTimeout(function() {window.aysHasPrompted = false;}, 900); + } + return settings.message; + }); + } + + return this.each(function(elem) { + if (!$(this).is('form')) { + return; + } + var $form = $(this); + + $form.submit(function() { + $form.removeClass(settings.dirtyClass); + }); + $form.bind('reset', function() { setDirtyStatus($form, false); }); + // Add a custom events + $form.bind('rescan.areYouSure', rescan); + $form.bind('reinitialize.areYouSure', reinitialize); + $form.bind('checkform.areYouSure', checkForm); + initForm($form); + }); + }; +})(jQuery); diff --git a/library/jquery.AreYouSure/package.json b/library/jquery.AreYouSure/package.json new file mode 100644 index 000000000..0b4c38dde --- /dev/null +++ b/library/jquery.AreYouSure/package.json @@ -0,0 +1,45 @@ +{ + "name": "jquery.AreYouSure", + "description": "A light-weight jQuery \"dirty forms\" Plugin - it monitors HTML forms and alerts users to unsaved changes if they attempt to close the browser or navigate away from the page. (Are you sure?)", + "homepage": "https://github.com/codedance/jquery.AreYouSure", + "author": "Chris Dance (https://github.com/codedance)", + "contributors": [ + "Tom Clift (https://github.com/tclift)", + "Jon Egerton (http://www.jonegerton.com/)", + "Scadoodles (https://github.com/Scadoodles)", + "Albin Sunnanbo (https://github.com/albinsunnanbo)", + "Marc Sutton (http://www.codev.co.uk)" + ], + "version": "1.9.0", + "license": "MIT/GPLv2", + "keywords": [ "dirty", "form", "onbeforeunload", "save", "check" ], + "main": "jquery.are-you-sure.js", + "engines": { + "node": ">=0.8.0" + }, + "repository": { + "type": "git", + "url": "https://github.com/codedance/jquery.AreYouSure" + }, + "bugs": { + "url": "https://github.com/codedance/jquery.AreYouSure/issues" + }, + "dependencies": { + "jquery": ">=1.4.2" + }, + "devDependencies": { + "bower": "^1.3.1", + "grunt": "^0.4.5", + "grunt-cli": "^0.1.13", + "grunt-karma": "^0.8.3", + "karma-chrome-launcher": "^0.1.4", + "karma-jasmine": "^0.2.2", + "karma-ie-launcher": "^0.1.5", + "karma-firefox-launcher": "^0.1.3", + "karma-safari-launcher": "^0.1.1" + }, + "scripts": { + "postinstall": "node_modules/.bin/bower install", + "test": "node_modules/.bin/grunt test" + } +} diff --git a/library/jquery.AreYouSure/spec/javascripts/fixtures/input-text.html b/library/jquery.AreYouSure/spec/javascripts/fixtures/input-text.html new file mode 100644 index 000000000..1b2850759 --- /dev/null +++ b/library/jquery.AreYouSure/spec/javascripts/fixtures/input-text.html @@ -0,0 +1,4 @@ +
+ + +
diff --git a/library/jquery.AreYouSure/spec/javascripts/jquery.are-you-sure_spec.js b/library/jquery.AreYouSure/spec/javascripts/jquery.are-you-sure_spec.js new file mode 100644 index 000000000..5e02f7cb0 --- /dev/null +++ b/library/jquery.AreYouSure/spec/javascripts/jquery.are-you-sure_spec.js @@ -0,0 +1,28 @@ +'use strict'; + +// Karma adds 'base/' to the default path +jasmine.getFixtures().fixturesPath = 'base/spec/javascripts/fixtures'; + +describe("A form's", function() { + var $form = undefined; + + describe('text input', function() { + var $textInput = undefined; + + beforeEach(function() { + loadFixtures('input-text.html'); + $form = $('form'); + $textInput = $('input[type=text]'); + $form.areYouSure(); + }); + + it('should cause dirtyness after its value changes', function(done) { + expect($form.hasClass('dirty')).toBe(false); + $textInput.val('new').change(); + setTimeout(function() { + expect($form.hasClass('dirty')).toBe(true); + done(); + }, 0); + }); + }); +}); -- cgit v1.2.3