Warn about unsaved settings using jquery.areyousure
This commit is contained in:
parent
93b9470487
commit
9557908875
166
library/jquery.AreYouSure/.gitignore
vendored
Normal file
166
library/jquery.AreYouSure/.gitignore
vendored
Normal file
@ -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/
|
26
library/jquery.AreYouSure/Gruntfile.js
Normal file
26
library/jquery.AreYouSure/Gruntfile.js
Normal file
@ -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');
|
||||
};
|
297
library/jquery.AreYouSure/README.md
Normal file
297
library/jquery.AreYouSure/README.md
Normal file
@ -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
|
||||
<form id="myForm" name="myform" action="/post" method="post">
|
||||
|
||||
Field 1: (checked) <input type="text" name="field1"> <br />
|
||||
Field 2: (ignored): <input type="text" name="field2" data-ays-ignore="true"> <br />
|
||||
Field 3: (ignored): <input type="text" name="field3" class="ays-ignore"> <br />
|
||||
|
||||
<input type="submit" value="Submit">
|
||||
|
||||
</form>
|
||||
```
|
||||
|
||||
###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
|
39
library/jquery.AreYouSure/are-you-sure.jquery.json
Normal file
39
library/jquery.AreYouSure/are-you-sure.jquery.json
Normal file
@ -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"
|
||||
}
|
||||
}
|
31
library/jquery.AreYouSure/ays-beforeunload-shim.js
Normal file
31
library/jquery.AreYouSure/ays-beforeunload-shim.js
Normal file
@ -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;
|
||||
}
|
||||
});
|
||||
});
|
30
library/jquery.AreYouSure/bower.json
Normal file
30
library/jquery.AreYouSure/bower.json
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "jquery.are-you-sure",
|
||||
"version": "1.9.0",
|
||||
"homepage": "https://github.com/codedance/jquery.AreYouSure",
|
||||
"authors": [
|
||||
"CodeDance <chris.dance@papercut.com>"
|
||||
],
|
||||
"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"
|
||||
}
|
||||
}
|
576
library/jquery.AreYouSure/demo/are-you-sure-demo.html
Normal file
576
library/jquery.AreYouSure/demo/are-you-sure-demo.html
Normal file
@ -0,0 +1,576 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Demo: Are You Sure? - a dirty forms jQuery Plugin</title>
|
||||
|
||||
<!--
|
||||
|
||||
We'll use an old version of jQuery to show we're backwards compatible. In
|
||||
production we recommend using a later version. e.g.
|
||||
|
||||
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
|
||||
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
|
||||
|
||||
-->
|
||||
|
||||
<script src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
|
||||
<script src="../jquery.are-you-sure.js"></script>
|
||||
<script src="../ays-beforeunload-shim.js"></script>
|
||||
<script>
|
||||
|
||||
$(function() {
|
||||
|
||||
// Example 1 - ... in one line of code
|
||||
$('#example-1-form').areYouSure();
|
||||
|
||||
|
||||
// Example 2 - ignore a dynamic field
|
||||
$('#example-2-form').areYouSure();
|
||||
|
||||
var defaultPickup15min = new Date((new Date()).getTime() + 15 * 60000);
|
||||
$('#pickup').val(defaultPickup15min.getHours()
|
||||
+ ':' + defaultPickup15min.getMinutes());
|
||||
|
||||
|
||||
// Example 3 - custom message and hooking the dirty change events
|
||||
$('#example-3-form').areYouSure(
|
||||
{
|
||||
message: "Did you forget to save your standard coffee order?"
|
||||
}
|
||||
);
|
||||
// Enable save button only if the form is dirty - using events.
|
||||
$('#example-3-form').bind('dirty.areYouSure', function() {
|
||||
$(this).find('input[type="submit"]').removeAttr('disabled');
|
||||
});
|
||||
$('#example-3-form').bind('clean.areYouSure', function() {
|
||||
$(this).find('input[type="submit"]').attr('disabled', 'disabled');
|
||||
});
|
||||
|
||||
|
||||
// Example 4 - dynamically change and add form fields.
|
||||
$('#example-4-form').areYouSure(
|
||||
{
|
||||
message: "Did you forget to submit your coffee order?"
|
||||
}
|
||||
);
|
||||
|
||||
$('#example-4-lastorder').click(function() {
|
||||
// ... set our saved coffee type.
|
||||
$('#example-4-coffee').val('espresso');
|
||||
// Because we've made a change from our own JavaScript, we need to fire
|
||||
// off manual 'form check'.
|
||||
$('#example-4-form').trigger('checkform.areYouSure');
|
||||
});
|
||||
|
||||
// If it's warm enough, offer an iced coffee special.
|
||||
$.getJSON("http://api.openweathermap.org/data/2.5/weather?q=Melbourne,AU&mode=json&units=metric&callback=?",
|
||||
function(data) {
|
||||
var temp = data.main.temp;
|
||||
if (temp > 5) {
|
||||
$('#example-4-special').append('<p>It\'s currently '
|
||||
+ temp + 'C in Melbourne. Ice it up!</p>');
|
||||
$('#example-4-special').append('<input type="checkbox" name="make-it-iced" value="true" />'
|
||||
+ ' Make it an iced coffee<br />');
|
||||
|
||||
// Trigger rescan event on the form so we start tracking the new field.
|
||||
$('#example-4-form').trigger('rescan.areYouSure');
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* Example 5
|
||||
* - extra shots button to enable/disable shots options
|
||||
* - like/unlike button (changing hidden form field value)
|
||||
* - hook dirty change event to enable/disable submit (using method),
|
||||
* to more easily demonstrate when the form is dirty
|
||||
*/
|
||||
$('#example-5-extra-shots').click(function() {
|
||||
// we trigger a change event on the fields so that the AreYouSure event handler is called
|
||||
$('#example-5-form input[name=shots]').removeAttr('disabled').change();
|
||||
$('#example-5-extra-shots').hide();
|
||||
$('#example-5-shots-options').show();
|
||||
return false;
|
||||
});
|
||||
$('#example-5-like-button').click(function() {
|
||||
var currentLike = $('#example-5-like').val() == 'true';
|
||||
var newLike = !currentLike;
|
||||
// we trigger a change event on the fields so that the areYouSure event handler is called
|
||||
$('#example-5-like').val(newLike).change();
|
||||
$('#example-5-like-button').text(newLike ? 'Unlike' : 'Like');
|
||||
return false;
|
||||
});
|
||||
$('#example-5-form').areYouSure({
|
||||
change: function() {
|
||||
// Enable save button only if the form is dirty.
|
||||
if ($(this).hasClass('dirty')) {
|
||||
$(this).find('input[type="submit"]').removeAttr('disabled');
|
||||
} else {
|
||||
$(this).find('input[type="submit"]').attr('disabled', 'disabled');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Example 6 - HTML5 input types
|
||||
$('#example-6-form').areYouSure();
|
||||
|
||||
// Example 7 - ... in one line of code for the form and some more optional to toggle disabled state of the save button
|
||||
$('#example-7-form').areYouSure();
|
||||
$('#example-7-save-button').click(function () {
|
||||
$('#example-7-form').trigger('reinitialize.areYouSure');
|
||||
});
|
||||
// code below is optional to handle disabled state of the save button
|
||||
$('#example-7-form').bind('dirty.areYouSure', function () {
|
||||
// Enable save button only as the form is dirty.
|
||||
$('#example-7-save-button').attr({ 'disabled': false });
|
||||
});
|
||||
$('#example-7-form').bind('clean.areYouSure', function () {
|
||||
// Form is clean so nothing to save - disable the save button.
|
||||
$('#example-7-save-button').attr({ 'disabled': true });
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style type="text/css">
|
||||
body {
|
||||
font-family: myriad-pro-1, myriad-pro-2, 'Lucida Grande', 'Arial', sans-serif;
|
||||
margin: 25px;
|
||||
}
|
||||
|
||||
form {
|
||||
width: 350px;
|
||||
border: 1px solid #AA5303;
|
||||
padding: 10px 20px;
|
||||
background-image: -webkit-linear-gradient(top, rgba(170,83,3, 0.1), rgba(170,83,3, 0.5));
|
||||
background-image: -moz-linear-gradient(top, rgba(170,83,3, 0.1), rgba(170,83,3, 0.5));
|
||||
background-image: -ms-linear-gradient(top, rgba(170,83,3, 0.1), rgba(170,83,3, 0.5));
|
||||
background-image: -o-linear-gradient(top, rgba(170,83,3, 0.1), rgba(170,83,3, 0.5));
|
||||
background-image: linear-gradient(top, rgba(170,83,3, 0.1), rgba(170,83,3, 0.5));
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
/* A bit of custom styling on example 3 */
|
||||
#example-3-form.dirty, #example-4-form.dirty {
|
||||
box-shadow: 0 0 8px rgba(255, 0, 0, 1);
|
||||
-webkit-box-shadow: 0 0 8px rgba(255, 0, 0, 1);
|
||||
-moz-box-shadow: 0 0 8px rgba(255, 0, 0, 1);
|
||||
border:1px solid rgba(255,0,0, 0.8);
|
||||
}
|
||||
|
||||
form h2 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
form > div {
|
||||
padding: 8px;
|
||||
font-size: 12px;
|
||||
}
|
||||
form > div input[type="text"],
|
||||
form > div input[type="color"],
|
||||
form > div input[type="date"],
|
||||
form > div input[type="datetime"],
|
||||
form > div input[type="datetime-local"],
|
||||
form > div input[type="email"],
|
||||
form > div input[type="month"],
|
||||
form > div input[type="number"],
|
||||
form > div input[type="range"],
|
||||
form > div input[type="search"],
|
||||
form > div input[type="tel"],
|
||||
form > div input[type="time"],
|
||||
form > div input[type="url"],
|
||||
form > div input[type="week"],
|
||||
form > div input:not([type]),
|
||||
form > div textarea,
|
||||
form > div select,
|
||||
form > div button {
|
||||
float: right;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
form > div input[type="radio"],
|
||||
form > div input[type="checkbox"] {
|
||||
display: inline-block;
|
||||
margin-left: 130px;
|
||||
}
|
||||
|
||||
form > div input[type="submit"] {
|
||||
float: right;
|
||||
}
|
||||
form > div.buttons {
|
||||
clear: both;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>jQuery Plugin Demo: Are You Sure?</h1>
|
||||
<p>
|
||||
This page hosts a demo of the <a href="https://github.com/codedance/jquery.AreYouSure">jQuery Are-You-Sure</a> plugin (<code>jquery.are-you-sure.js</code>).
|
||||
</p>
|
||||
<p>
|
||||
<i>Are-you-sure</i> is simple light-weight "dirty forms" JQuery Plugin for modern browsers. It helps prevent users from loosing unsaved form changes.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Features:</strong>
|
||||
<ul>
|
||||
<li>Light weight - only the features you need!</li>
|
||||
<li>Dependency free.</li>
|
||||
<li>Correct state management - if a user edits then restores a value, the form is not considered dirty.</li>
|
||||
<li>Easy to understand - less than a "terminal screen" of code!</li>
|
||||
<li>... and <a href="https://github.com/codedance/jquery.AreYouSure">more</a>.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2>Example 1: It's simple!</h2>
|
||||
<p>
|
||||
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)
|
||||
</p>
|
||||
|
||||
<form id="example-1-form" name="coffeeOrder1" method="post">
|
||||
<h2>Enter Your Coffee Order</h2>
|
||||
<div>
|
||||
<label for="example-1-coffee">Coffee</label>
|
||||
<select name="coffee" id="example-1-coffee">
|
||||
<option value="espresso">Espresso</option>
|
||||
<option value="dbl-espresso">Caffe Doppio</option>
|
||||
<option value="latte">Caffe Latte</option>
|
||||
<option value="macciato">Machhiato</option>
|
||||
<option value="cappuccino">Cappuccino</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label>Shots</label><br />
|
||||
<input type="radio" name="shots" value="1" checked /> 1 Shot - Standard<br />
|
||||
<input type="radio" name="shots" value="2" /> 2 Shots - Morning wakeup!<br />
|
||||
<input type="radio" name="shots" value="3" /> 3 Shots - Overdrive!<br />
|
||||
</div>
|
||||
<div>
|
||||
<label for="example-1-sugar">Sugar</label> <input type="text" name="sugar" value="0" id="example-1-sugar" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="example-1-instructions">Special Instructions</label>
|
||||
<textarea name="instructions" rows="5" id="example-1-instructions"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="buttons">
|
||||
<input type="checkbox" name="remember" value="true" /> Remember my order<br />
|
||||
<input type="submit" value="Submit">
|
||||
<input type="reset" value="Reset">
|
||||
</div>
|
||||
<div>
|
||||
<p>... or visit <a href="http://www.google.com/">Google</a> or close the window without saving!</p>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<h2>Example 2: Ignore the unimportant!</h2>
|
||||
<p>
|
||||
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 <em>not</em>
|
||||
mark the form as dirty.
|
||||
</p>
|
||||
<form id="example-2-form" name="coffeeOrder2" method="post">
|
||||
<h2>Enter Your Coffee Order</h2>
|
||||
<div>
|
||||
<!-- The ays-ignore class means a change on this field is not considered "dirty" -->
|
||||
<label for="pickup">Pickup Time</label>
|
||||
<input class="ays-ignore" type="text" name="pickup" id="pickup" />
|
||||
<!-- or you can use a data attribute like this:
|
||||
<label for="pickup">Pickup Time</label> <input data-ays-ignore="true" type="text" name="pickup" id="pickup" />
|
||||
-->
|
||||
</div>
|
||||
<div>
|
||||
<label for="example-2-coffee">Coffee</label>
|
||||
<select name="coffee" id="example-2-coffee">
|
||||
<option value="espresso">Espresso</option>
|
||||
<option value="dbl-espresso">Caffe Doppio</option>
|
||||
<option value="latte">Caffe Latte</option>
|
||||
<option value="macciato">Machhiato</option>
|
||||
<option value="cappuccino">Cappuccino</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label>Shots</label><br />
|
||||
<input type="radio" name="shots" value="1" checked /> 1 Shot - Standard<br />
|
||||
<input type="radio" name="shots" value="2" /> 2 Shots - Morning wakeup!<br />
|
||||
<input type="radio" name="shots" value="3" /> 3 Shots - Overdrive!<br />
|
||||
</div>
|
||||
<div>
|
||||
<label for="example-2-sugar">Sugar</label> <input type="text" name="sugar" value="0" id="example-2-sugar" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="example-2-instructions">Special Instructions</label>
|
||||
<textarea name="instructions" rows="5" id="example-2-instructions"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="buttons">
|
||||
<input type="checkbox" name="remember" value="true" /> Remember my order<br />
|
||||
<input type="submit" value="Submit">
|
||||
</div>
|
||||
<div>
|
||||
<p>... or visit <a href="http://www.google.com/">Google</a> or close the window without saving!</p>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
<h2>Example 3: Lets be intelligent!</h2>
|
||||
<p>
|
||||
This is a more advanced example. The <code>dirty</code> and <code>clean</code> 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 <code>.dirty</code> class).
|
||||
</p>
|
||||
<form id="example-3-form" name="coffeeOrder3" method="post">
|
||||
<h2>Update My Standard Order</h2>
|
||||
<div>
|
||||
<label for="example-3-coffee">Coffee</label>
|
||||
<select name="coffee" id="example-3-coffee">
|
||||
<option value=""></option>
|
||||
<option value="cappuccino">Cappuccino</option>
|
||||
<option value="espresso">Espresso</option>
|
||||
<option value="dbl-espresso">Caffe Doppio</option>
|
||||
<option value="latte">Caffe Latte</option>
|
||||
<option value="macciato">Machhiato</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label>Shots</label><br />
|
||||
<input type="radio" name="shots" value="1" /> 1 Shot - Standard<br />
|
||||
<input type="radio" name="shots" value="2" checked /> 2 Shots - Morning wakeup!<br />
|
||||
<input type="radio" name="shots" value="3" /> 3 Shots - Overdrive!<br />
|
||||
</div>
|
||||
<div>
|
||||
<label for="example-3-sugar">Sugar</label>
|
||||
<input type="text" name="sugar" value="1" id="example-3-sugar" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="example-3-instructions">Special Instructions</label>
|
||||
<textarea name="instructions" rows="5" id="example-3-instructions">No chocolate please</textarea>
|
||||
</div>
|
||||
|
||||
<div class="buttons">
|
||||
<input type="submit" value="Save" disabled="disabled">
|
||||
</div>
|
||||
<div>
|
||||
<p>... or visit <a href="http://www.google.com/">Google</a> or close the window without saving!</p>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<h2>Example 4: Lets be dynamic!</h2>
|
||||
<p>
|
||||
In this example we'll dymaically add a field and fire off the <code>rescan</code> event. After
|
||||
the rescan, Are-You-Sure will start looking for changes on the new fields as well.
|
||||
</p>
|
||||
<form id="example-4-form" name="coffeeOrder4" method="post">
|
||||
<h2>Order Coffee For Pickup Now</h2>
|
||||
<div>
|
||||
<a id="example-4-lastorder" href="javascript:void(0);">Set my preferences from my last order</a><br />
|
||||
</div>
|
||||
<div>
|
||||
<label for="example-4-coffee">Coffee</label>
|
||||
<select name="coffee" id="example-4-coffee">
|
||||
<option value="cappuccino">Cappuccino</option>
|
||||
<option value="espresso">Espresso</option>
|
||||
<option value="dbl-espresso">Caffe Doppio</option>
|
||||
<option value="latte">Caffe Latte</option>
|
||||
</select>
|
||||
</div>
|
||||
<div id="example-4-special"></div>
|
||||
<div class="buttons">
|
||||
<input type="submit" value="Place Order">
|
||||
</div>
|
||||
<div>
|
||||
<p>... or visit <a href="http://www.google.com/">Google</a> or close the window without saving!</p>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<h2>Example 5: Edge cases</h2>
|
||||
<p>
|
||||
This example demonstrates tracking of hidden and disabled form elements that are changed by non-input elements.
|
||||
E.g.:
|
||||
</p>
|
||||
<ul>
|
||||
<li>clicking a link or non-input button that changes the value of a hidden form field, or</li>
|
||||
<li>
|
||||
clicking a link or non-input button that enables or disables some form fields (which has an effect on whether
|
||||
or not those fields will be submitted with the form, despite the values not changing).
|
||||
</li>
|
||||
</ul>
|
||||
<form id="example-5-form" name="coffeeOrder5" method="post">
|
||||
<h2>Update My Standard Order</h2>
|
||||
<div>
|
||||
<label for="example-5-coffee">Coffee</label>
|
||||
<select name="coffee" id="example-3-coffee">
|
||||
<option value="cappuccino">Cappuccino</option>
|
||||
<option value="espresso">Espresso</option>
|
||||
<option value="dbl-espresso">Caffe Doppio</option>
|
||||
<option value="latte">Caffe Latte</option>
|
||||
<option value="macciato">Machhiato</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label>Shots</label>
|
||||
<!--
|
||||
The visually hidden "shots" radio buttons are disabled and would not normally be submitted with the form.
|
||||
Clicking the following button will visually show and enable these buttons, resulting in a form state change
|
||||
(and hence the form is considered dirty) without the values having changed.
|
||||
-->
|
||||
<button id="example-5-extra-shots">I want extra shots</button>
|
||||
<div id="example-5-shots-options" style="display: none;">
|
||||
<input type="radio" name="shots" value="1" disabled /> 1 Shot - Standard<br />
|
||||
<input type="radio" name="shots" value="2" disabled /> 2 Shots - Morning wakeup!<br />
|
||||
<input type="radio" name="shots" value="3" disabled /> 3 Shots - Overdrive!<br />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label>Do you like us?</label>
|
||||
<input type="hidden" name="like" value="false" id="example-5-like" />
|
||||
<button id="example-5-like-button">Like</button>
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<input type="submit" value="Save" disabled="disabled">
|
||||
</div>
|
||||
<div>
|
||||
<p>... or visit <a href="http://www.google.com/">Google</a> or close the window without saving!</p>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<h2>Example 6: HTML5 inputs!</h2>
|
||||
<p>
|
||||
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 :-)
|
||||
</p>
|
||||
|
||||
<form id="example-6-form" name="coffeeOrder6" method="post">
|
||||
<h2>Doing HTML5? You'll need coffee!</h2>
|
||||
<div>
|
||||
<label for="example-6-color">color</label>
|
||||
<input type="color" name="example-6-color" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="example-6-date">date</label>
|
||||
<input type="date" name="example-6-date" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="example-6-datetime">datetime</label>
|
||||
<input type="datetime" name="example-6-datetime" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="example-6-datetime-local">datetime-local</label>
|
||||
<input type="datetime-local" name="example-6-datetime-local" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="example-6-email">email</label>
|
||||
<input type="email" name="example-6-email" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="example-6-month">month</label>
|
||||
<input type="month" name="example-6-month" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="example-6-number">number</label>
|
||||
<input type="number" name="example-6-number" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="example-6-range">range</label>
|
||||
<input type="range" name="example-6-range" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="example-6-search">search</label>
|
||||
<input type="search" name="example-6-search" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="example-6-tel">tel</label>
|
||||
<input type="tel" name="example-6-tel" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="example-6-time">time</label>
|
||||
<input type="time" name="example-6-time" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="example-6-url">url</label>
|
||||
<input type="url" name="example-6-url" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="example-6-week">week</label>
|
||||
<input type="week" name="example-6-week" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="example-6-select">select/optgroup</label>
|
||||
<select>
|
||||
<optgroup label="Beans">
|
||||
<option value="india">India</option>
|
||||
<option value="indonesia" selected="selected">Indonesia</option>
|
||||
<option value="brazil">Brazil</option>
|
||||
</optgroup>
|
||||
<optgroup label="Roast">
|
||||
<option value="l">Light</option>
|
||||
<option value="m">Medium</option>
|
||||
<option value="h">Heavy</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="example-6-mselect">multi select</label>
|
||||
<select multiple>
|
||||
<option value="arabica">Arabica</option>
|
||||
<option value="arabica">Peaberry</option>
|
||||
<option value="malabar " selected="selected">Malabar</option>
|
||||
<option value="robusta ">Robusta</option>
|
||||
</select>
|
||||
</div>
|
||||
<div style="clear:both;"></div>
|
||||
<div>
|
||||
<label for="example-6-plain">plain old field</label>
|
||||
<input name="example-6-plain" />
|
||||
</div>
|
||||
|
||||
<div class="buttons">
|
||||
<input type="submit" value="Submit">
|
||||
<input type="reset" value="Reset">
|
||||
</div>
|
||||
<div>
|
||||
<p>... or visit <a href="http://www.google.com/">Google</a> or close the window without saving!</p>
|
||||
</div>
|
||||
</form>
|
||||
<h2>Example 7: Mark current state as not dirty!</h2>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
|
||||
<form id="example-7-form" name="coffeeOrder7" method="post">
|
||||
<h2>Tell us your default coffee</h2>
|
||||
<div>
|
||||
<label for="example-7-coffee">Default coffee</label>
|
||||
<select name="coffee" id="example-7-coffee">
|
||||
<option value="espresso">Espresso</option>
|
||||
<option value="dbl-espresso">Caffe Doppio</option>
|
||||
<option value="latte">Caffe Latte</option>
|
||||
<option value="macciato">Machhiato</option>
|
||||
<option value="cappuccino">Cappuccino</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<button id="example-7-save-button" disabled="disabled">Save without submit</button>
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<input type="submit" value="Submit">
|
||||
</div>
|
||||
<div>
|
||||
<p>... or visit <a href="http://www.google.com/">Google</a> or close the window without saving!</p>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<p>
|
||||
This jQuery plugin is developed by <a href="https://github.com/codedance">Chris Dance</a>
|
||||
at <a href="http://www.papercut.com/">PaperCut Software</a> - 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.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
192
library/jquery.AreYouSure/jquery.are-you-sure.js
Normal file
192
library/jquery.AreYouSure/jquery.are-you-sure.js
Normal file
@ -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);
|
45
library/jquery.AreYouSure/package.json
Normal file
45
library/jquery.AreYouSure/package.json
Normal file
@ -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 <chris.dance@papercut.com> (https://github.com/codedance)",
|
||||
"contributors": [
|
||||
"Tom Clift <tom.clift@papercut.com> (https://github.com/tclift)",
|
||||
"Jon Egerton <jon@ja2.co.uk> (http://www.jonegerton.com/)",
|
||||
"Scadoodles (https://github.com/Scadoodles)",
|
||||
"Albin Sunnanbo (https://github.com/albinsunnanbo)",
|
||||
"Marc Sutton <ashre@iname.com> (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"
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
<form>
|
||||
<input type="text" name="a">
|
||||
<input type="submit">
|
||||
</form>
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
3
view/js/mod_admin.js
Normal file
3
view/js/mod_admin.js
Normal file
@ -0,0 +1,3 @@
|
||||
$(document).ready(function() {
|
||||
$('form').areYouSure(); // Warn user about unsaved settings
|
||||
});
|
3
view/js/mod_profiles.js
Normal file
3
view/js/mod_profiles.js
Normal file
@ -0,0 +1,3 @@
|
||||
$(document).ready(function() {
|
||||
$('form').areYouSure(); // Warn user about unsaved settings
|
||||
});
|
@ -2,6 +2,7 @@
|
||||
var ispublic = aStr['everybody'] ;
|
||||
|
||||
$(document).ready(function() {
|
||||
$('form').areYouSure(); // Warn user about unsaved settings
|
||||
|
||||
$("a#settings-default-perms-menu").colorbox({
|
||||
'inline' : true,
|
||||
|
@ -44,6 +44,7 @@ head_add_js('docready.js');
|
||||
head_add_js('library/colorbox/jquery.colorbox-min.js');
|
||||
head_add_js('library/bootstrap-tagsinput/bootstrap-tagsinput.js');
|
||||
|
||||
head_add_js('library/jquery.AreYouSure/jquery.are-you-sure.js');
|
||||
/**
|
||||
* Those who require this feature will know what to do with it.
|
||||
* Those who don't, won't.
|
||||
|
Reference in New Issue
Block a user