Contact Form Clean and Simple - Version 4.1.3

Version Description

  • Fixed escaped characters.
  • Added more translation files
  • Forms now submit via ajax.
  • Upgraded jquery-validate.js to 1.11. Removed jquery metadata plugin, form validation is now built with data attributes instead of json in classes.
  • Improved view html.
  • Added Dutch and Armenian translations
Download this release

Release Info

Developer megnicholas
Plugin Icon wp plugin Contact Form Clean and Simple
Version 4.1.3
Comparing to
See all releases

Code changes from version 4.1.2 to 4.1.3

ajax.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ add_action("wp_ajax_cscf-submitform", "cscfsubmitform");
3
+ add_action("wp_ajax_nopriv_cscf-submitform", "cscfsubmitform");
4
+
5
+ //http://wp.smashingmagazine.com/2011/10/18/how-to-use-ajax-in-wordpress/
6
+ function cscfsubmitform() {
7
+
8
+ $contact = new cscf_Contact;
9
+ $result['sent'] = false;
10
+
11
+ $result['valid'] = $contact->IsValid();
12
+ $result['errorlist'] = $contact->Errors;
13
+
14
+ if ($result['valid']) $result['sent'] = $contact->SendMail();
15
+
16
+ header('Content-type: application/json');
17
+ echo json_encode($result);
18
+ die();
19
+ }
class.cscf.php CHANGED
@@ -44,14 +44,18 @@ class cscf
44
  {
45
  wp_register_script('jquery-validate', CSCF_PLUGIN_URL . '/js/jquery.validate.min.js', array(
46
  'jquery'
47
- ) , '1.10.0', true);
48
- wp_register_script('jquery-meta', CSCF_PLUGIN_URL . '/js/jquery.metadata.js', array(
49
- 'jquery'
50
- ) , '4187', true);
51
- wp_register_script('jquery-validate-contact-form', CSCF_PLUGIN_URL . '/js/jquery.validate.contact.form.js', array(
52
- 'jquery'
53
- ) , '1.00', true);
54
- wp_register_style('cscf-bootstrap', CSCF_PLUGIN_URL . '/css/bootstrap-forms.min.css', null, '2.3.1');
 
 
 
 
55
  }
56
 
57
  function Upgrade()
44
  {
45
  wp_register_script('jquery-validate', CSCF_PLUGIN_URL . '/js/jquery.validate.min.js', array(
46
  'jquery'
47
+ ) , '1.11.0', true);
48
+
49
+ wp_register_script( 'cscf-validate', CSCF_PLUGIN_URL . "/js/jquery.validate.contact.form.js",
50
+ 'jquery',
51
+ CSCF_VERSION_NUM, true );
52
+
53
+ wp_localize_script( 'cscf-validate', 'cscfvars',
54
+ array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
55
+
56
+ wp_register_style('cscf-bootstrap', CSCF_PLUGIN_URL . '/css/bootstrap-forms.min.css',
57
+ null, '2.3.1');
58
+
59
  }
60
 
61
  function Upgrade()
class.cscf_contact.php CHANGED
@@ -28,14 +28,15 @@ class cscf_Contact
28
  if ( $_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['cscf']) )
29
  {
30
  $cscf = $_POST['cscf'];
31
- $this->Name = filter_var($cscf['name'], FILTER_SANITIZE_STRING);
32
  $this->Email = filter_var($cscf['email'], FILTER_SANITIZE_EMAIL);
33
  $this->ConfirmEmail = filter_var($cscf['confirm-email'], FILTER_SANITIZE_EMAIL);
34
- $this->Message = filter_var($cscf['message'], FILTER_SANITIZE_STRING);
35
  unset($_POST['cscf']);
36
  }
37
  }
38
 
 
39
  function IsValid()
40
  {
41
  $this->Errors = array();
@@ -83,5 +84,26 @@ class cscf_Contact
83
 
84
  return count($this->Errors) == 0;
85
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  }
87
 
28
  if ( $_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['cscf']) )
29
  {
30
  $cscf = $_POST['cscf'];
31
+ $this->Name = filter_var($cscf['name'], FILTER_SANITIZE_STRING,FILTER_FLAG_NO_ENCODE_QUOTES);
32
  $this->Email = filter_var($cscf['email'], FILTER_SANITIZE_EMAIL);
33
  $this->ConfirmEmail = filter_var($cscf['confirm-email'], FILTER_SANITIZE_EMAIL);
34
+ $this->Message = filter_var($cscf['message'], FILTER_SANITIZE_STRING,FILTER_FLAG_NO_ENCODE_QUOTES);
35
  unset($_POST['cscf']);
36
  }
37
  }
38
 
39
+ public
40
  function IsValid()
41
  {
42
  $this->Errors = array();
84
 
85
  return count($this->Errors) == 0;
86
  }
87
+
88
+ public
89
+ function SendMail() {
90
+
91
+ $filters = new cscf_Filters;
92
+
93
+ $filters->fromEmail=$this->Email;
94
+ $filters->fromName=$this->Name;
95
+
96
+ //add filters
97
+ $filters->add('wp_mail_from');
98
+ $filters->add('wp_mail_from_name');
99
+
100
+ $result = (wp_mail(cscf_PluginSettings::RecipientEmail() , cscf_PluginSettings::Subject(), stripslashes($this->Message)));
101
+
102
+ //remove filters (play nice)
103
+ $filters->remove('wp_mail_from');
104
+ $filters->remove('wp_mail_from_name');
105
+
106
+ return $result;
107
+ }
108
  }
109
 
class.cscf_filters.php CHANGED
@@ -13,8 +13,9 @@ class cscf_Filters {
13
  return $this->fromEmail;
14
  }
15
 
 
16
  function wp_mail_from_name () {
17
- return $this->fromName;
18
  }
19
 
20
  function add($filter, $priority = 10, $args = 1) {
13
  return $this->fromEmail;
14
  }
15
 
16
+ //strip slashes from the name
17
  function wp_mail_from_name () {
18
+ return stripslashes($this->fromName);
19
  }
20
 
21
  function add($filter, $priority = 10, $args = 1) {
class.view.php CHANGED
@@ -46,5 +46,5 @@ class CSCF_View
46
 
47
  return ob_get_clean();
48
  }
49
- }
50
 
46
 
47
  return ob_get_clean();
48
  }
49
+ }
50
 
clean-and-simple-contact-form-by-meg-nicholas.php CHANGED
@@ -7,7 +7,7 @@
7
  Plugin Name: Clean and Simple Contact Form
8
  Plugin URI: http://www.megnicholas.co.uk/wordpress-plugins/clean-and-simple-contact-form
9
  Description: A clean and simple contact form with Google reCAPTCHA and Twitter Bootstrap markup.
10
- Version: 4.1.2
11
  Author: Meghan Nicholas
12
  Author URI: http://www.megnicholas.co.uk
13
  License: GPLv2 or later
@@ -39,6 +39,7 @@ include ('class.cscf_settings.php');
39
  include ('class.cscf_contact.php');
40
  include ('class.view.php');
41
  include ('class.cscf_filters.php');
 
42
 
43
  if (cscf_PluginSettings::UseRecaptcha()) include ('recaptcha-php-1.11/recaptchalib.php');
44
 
@@ -52,7 +53,7 @@ if (!defined('CSCF_PLUGIN_URL')) define('CSCF_PLUGIN_URL', WP_PLUGIN_URL . '/' .
52
 
53
  if (!defined('CSCF_VERSION_KEY')) define('CSCF_VERSION_KEY', 'cscf_version');
54
 
55
- if (!defined('CSCF_VERSION_NUM')) define('CSCF_VERSION_NUM', '4.1.2');
56
 
57
  if (!defined('CSCF_OPTIONS_KEY')) define('CSCF_OPTIONS_KEY', 'cscf_options');
58
 
7
  Plugin Name: Clean and Simple Contact Form
8
  Plugin URI: http://www.megnicholas.co.uk/wordpress-plugins/clean-and-simple-contact-form
9
  Description: A clean and simple contact form with Google reCAPTCHA and Twitter Bootstrap markup.
10
+ Version: 4.1.3
11
  Author: Meghan Nicholas
12
  Author URI: http://www.megnicholas.co.uk
13
  License: GPLv2 or later
39
  include ('class.cscf_contact.php');
40
  include ('class.view.php');
41
  include ('class.cscf_filters.php');
42
+ include ('ajax.php');
43
 
44
  if (cscf_PluginSettings::UseRecaptcha()) include ('recaptcha-php-1.11/recaptchalib.php');
45
 
53
 
54
  if (!defined('CSCF_VERSION_KEY')) define('CSCF_VERSION_KEY', 'cscf_version');
55
 
56
+ if (!defined('CSCF_VERSION_NUM')) define('CSCF_VERSION_NUM', '4.1.3');
57
 
58
  if (!defined('CSCF_OPTIONS_KEY')) define('CSCF_OPTIONS_KEY', 'cscf_options');
59
 
js/jquery.metadata.js DELETED
@@ -1,122 +0,0 @@
1
- /*
2
- * Metadata - jQuery plugin for parsing metadata from elements
3
- *
4
- * Copyright (c) 2006 John Resig, Yehuda Katz, J�örn Zaefferer, Paul McLanahan
5
- *
6
- * Dual licensed under the MIT and GPL licenses:
7
- * http://www.opensource.org/licenses/mit-license.php
8
- * http://www.gnu.org/licenses/gpl.html
9
- *
10
- * Revision: $Id: jquery.metadata.js 4187 2007-12-16 17:15:27Z joern.zaefferer $
11
- *
12
- */
13
-
14
- /**
15
- * Sets the type of metadata to use. Metadata is encoded in JSON, and each property
16
- * in the JSON will become a property of the element itself.
17
- *
18
- * There are three supported types of metadata storage:
19
- *
20
- * attr: Inside an attribute. The name parameter indicates *which* attribute.
21
- *
22
- * class: Inside the class attribute, wrapped in curly braces: { }
23
- *
24
- * elem: Inside a child element (e.g. a script tag). The
25
- * name parameter indicates *which* element.
26
- *
27
- * The metadata for an element is loaded the first time the element is accessed via jQuery.
28
- *
29
- * As a result, you can define the metadata type, use $(expr) to load the metadata into the elements
30
- * matched by expr, then redefine the metadata type and run another $(expr) for other elements.
31
- *
32
- * @name $.metadata.setType
33
- *
34
- * @example <p id="one" class="some_class {item_id: 1, item_label: 'Label'}">This is a p</p>
35
- * @before $.metadata.setType("class")
36
- * @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
37
- * @desc Reads metadata from the class attribute
38
- *
39
- * @example <p id="one" class="some_class" data="{item_id: 1, item_label: 'Label'}">This is a p</p>
40
- * @before $.metadata.setType("attr", "data")
41
- * @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
42
- * @desc Reads metadata from a "data" attribute
43
- *
44
- * @example <p id="one" class="some_class"><script>{item_id: 1, item_label: 'Label'}</script>This is a p</p>
45
- * @before $.metadata.setType("elem", "script")
46
- * @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
47
- * @desc Reads metadata from a nested script element
48
- *
49
- * @param String type The encoding type
50
- * @param String name The name of the attribute to be used to get metadata (optional)
51
- * @cat Plugins/Metadata
52
- * @descr Sets the type of encoding to be used when loading metadata for the first time
53
- * @type undefined
54
- * @see metadata()
55
- */
56
-
57
- (function($) {
58
-
59
- $.extend({
60
- metadata : {
61
- defaults : {
62
- type: 'class',
63
- name: 'metadata',
64
- cre: /({.*})/,
65
- single: 'metadata'
66
- },
67
- setType: function( type, name ){
68
- this.defaults.type = type;
69
- this.defaults.name = name;
70
- },
71
- get: function( elem, opts ){
72
- var settings = $.extend({},this.defaults,opts);
73
- // check for empty string in single property
74
- if ( !settings.single.length ) settings.single = 'metadata';
75
-
76
- var data = $.data(elem, settings.single);
77
- // returned cached data if it already exists
78
- if ( data ) return data;
79
-
80
- data = "{}";
81
-
82
- if ( settings.type == "class" ) {
83
- var m = settings.cre.exec( elem.className );
84
- if ( m )
85
- data = m[1];
86
- } else if ( settings.type == "elem" ) {
87
- if( !elem.getElementsByTagName )
88
- return undefined;
89
- var e = elem.getElementsByTagName(settings.name);
90
- if ( e.length )
91
- data = $.trim(e[0].innerHTML);
92
- } else if ( elem.getAttribute != undefined ) {
93
- var attr = elem.getAttribute( settings.name );
94
- if ( attr )
95
- data = attr;
96
- }
97
-
98
- if ( data.indexOf( '{' ) <0 )
99
- data = "{" + data + "}";
100
-
101
- data = eval("(" + data + ")");
102
-
103
- $.data( elem, settings.single, data );
104
- return data;
105
- }
106
- }
107
- });
108
-
109
- /**
110
- * Returns the metadata object for the first member of the jQuery object.
111
- *
112
- * @name metadata
113
- * @descr Returns element's metadata object
114
- * @param Object opts An object contianing settings to override the defaults
115
- * @type jQuery
116
- * @cat Plugins/Metadata
117
- */
118
- $.fn.metadata = function( opts ){
119
- return $.metadata.get( this[0], opts );
120
- };
121
-
122
- })(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/jquery.validate.contact.form.js CHANGED
@@ -1,29 +1,99 @@
1
- /*! jQuery Contact-Form Validation - v1.0.0 - 22/04/2013
2
- * Author Meghan Nicholas
3
- * Licence GPL2 */
4
-
5
  jQuery(document).ready(function($) {
6
 
7
- $('#frmCSCF').submit(function() {
8
- return $('#frmCSCF').valid();
9
- //alert('here');
10
- });
11
 
 
 
 
12
 
13
- $('#frmCSCF').validate({
14
-
15
- errorElement: 'span',
16
- errorClass: 'help-inline',
17
-
18
- highlight: function(element) {
19
- $(element).closest('.control-group').removeClass('success').addClass('error');
20
- },
21
- success: function(element) {
22
- element
23
- .closest('.control-group').removeClass('error').addClass('success');
24
- }
25
-
26
-
27
- });
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  jQuery(document).ready(function($) {
2
 
3
+ var $div = $("#cscf");
 
 
 
4
 
5
+ var $form = $div.find("#frmCSCF");
6
+
7
+ $form.find("#recaptcha_response_field").focus(function() {
8
 
9
+ $errele = $form.find("div[for='cscf_recaptcha']");
10
+ $errele.html('');
11
+
12
+ });
 
 
 
 
 
 
 
 
 
 
 
13
 
14
+ $form.validate({
15
+
16
+ errorElement: 'span',
17
+ errorClass: 'help-inline',
18
+
19
+ highlight: function(element) {
20
+ $(element).closest('.control-group').removeClass('success').addClass('error');
21
+ },
22
+ success: function(element) {
23
+ element.closest('.control-group').removeClass('error').addClass('success');
24
+ }
25
+
26
+
27
+ });
28
+
29
+ $form.submit(function (event) {
30
+
31
+ $button = $(this).find("button");
32
+ $button.attr("disabled","disabled");
33
+
34
+ event.preventDefault();
35
+
36
+ if ($form.validate().valid() ) {
37
+
38
+ $.ajax({
39
+ type : "post",
40
+ dataType : "json",
41
+ cache: false,
42
+ url : cscfvars.ajaxurl,
43
+ data : $($form).serialize() + "&action=cscf-submitform",
44
+ success: function(response,strText) {
45
+ if (response.valid === true) {
46
+ //show sent message div
47
+ $formdiv=$div.find(".cscfForm");
48
+ $formdiv.css('display','none');
49
+ $messagediv=$div.find(".cscfMessageSent");
50
+ if (response.sent === false ) {
51
+ $messagediv=$div.find(".cscfMessageNotSent");
52
+ }
53
+
54
+ $messagediv.css('display','block');
55
+
56
+ if ( isScrolledIntoView($div) == false) {
57
+ scrollTo($div.selector);
58
+ }
59
+ }
60
+
61
+ else {
62
+ $.each(response.errorlist, function(name, value) {
63
+ $errele = $form.find("div[for='cscf_" + name +"']");
64
+ $errele.html(value);
65
+ $errele.closest('.control-group').removeClass('success').addClass('error');
66
+ });
67
+ }
68
+ },
69
+ error: function(XMLHttpRequest, textStatus, errorThrown) {
70
+ if (window.console) {
71
+ console.log("Status: " + textStatus + "Error: " + errorThrown + "Response: " + XMLHttpRequest.responseText);
72
+ }
73
+
74
+ }
75
+
76
+ });
77
+
78
+ };
79
+ $button.removeAttr("disabled");
80
+ });
81
+
82
  });
83
+
84
+ function scrollTo(id)
85
+ {
86
+ // Scroll
87
+ jQuery('html,body').animate({scrollTop: jQuery(id).offset().top},'slow');
88
+ }
89
+
90
+ function isScrolledIntoView(elem)
91
+ {
92
+ var docViewTop = jQuery(window).scrollTop();
93
+ var docViewBottom = docViewTop + jQuery(window).height();
94
+
95
+ var elemTop = jQuery(elem).offset().top;
96
+ var elemBottom = elemTop + jQuery(elem).height();
97
+
98
+ return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
99
+ }
js/jquery.validate.js ADDED
@@ -0,0 +1,1207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*! jQuery Validation Plugin - v1.11.0 - 7/13/2013
2
+ * https://github.com/jzaefferer/jquery-validation
3
+ * Copyright (c) 2013 Jörn Zaefferer; Licensed MIT */
4
+
5
+ (function($) {
6
+
7
+ $.extend($.fn, {
8
+ // http://docs.jquery.com/Plugins/Validation/validate
9
+ validate: function( options ) {
10
+
11
+ // if nothing is selected, return nothing; can't chain anyway
12
+ if ( !this.length ) {
13
+ if ( options && options.debug && window.console ) {
14
+ console.warn( "Nothing selected, can't validate, returning nothing." );
15
+ }
16
+ return;
17
+ }
18
+
19
+ // check if a validator for this form was already created
20
+ var validator = $.data( this[0], "validator" );
21
+ if ( validator ) {
22
+ return validator;
23
+ }
24
+
25
+ // Add novalidate tag if HTML5.
26
+ this.attr( "novalidate", "novalidate" );
27
+
28
+ validator = new $.validator( options, this[0] );
29
+ $.data( this[0], "validator", validator );
30
+
31
+ if ( validator.settings.onsubmit ) {
32
+
33
+ this.validateDelegate( ":submit", "click", function( event ) {
34
+ if ( validator.settings.submitHandler ) {
35
+ validator.submitButton = event.target;
36
+ }
37
+ // allow suppressing validation by adding a cancel class to the submit button
38
+ if ( $(event.target).hasClass("cancel") ) {
39
+ validator.cancelSubmit = true;
40
+ }
41
+ });
42
+
43
+ // validate the form on submit
44
+ this.submit( function( event ) {
45
+ if ( validator.settings.debug ) {
46
+ // prevent form submit to be able to see console output
47
+ event.preventDefault();
48
+ }
49
+ function handle() {
50
+ var hidden;
51
+ if ( validator.settings.submitHandler ) {
52
+ if ( validator.submitButton ) {
53
+ // insert a hidden input as a replacement for the missing submit button
54
+ hidden = $("<input type='hidden'/>").attr("name", validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm);
55
+ }
56
+ validator.settings.submitHandler.call( validator, validator.currentForm, event );
57
+ if ( validator.submitButton ) {
58
+ // and clean up afterwards; thanks to no-block-scope, hidden can be referenced
59
+ hidden.remove();
60
+ }
61
+ return false;
62
+ }
63
+ return true;
64
+ }
65
+
66
+ // prevent submit for invalid forms or custom submit handlers
67
+ if ( validator.cancelSubmit ) {
68
+ validator.cancelSubmit = false;
69
+ return handle();
70
+ }
71
+ if ( validator.form() ) {
72
+ if ( validator.pendingRequest ) {
73
+ validator.formSubmitted = true;
74
+ return false;
75
+ }
76
+ return handle();
77
+ } else {
78
+ validator.focusInvalid();
79
+ return false;
80
+ }
81
+ });
82
+ }
83
+
84
+ return validator;
85
+ },
86
+ // http://docs.jquery.com/Plugins/Validation/valid
87
+ valid: function() {
88
+ if ( $(this[0]).is("form")) {
89
+ return this.validate().form();
90
+ } else {
91
+ var valid = true;
92
+ var validator = $(this[0].form).validate();
93
+ this.each(function() {
94
+ valid &= validator.element(this);
95
+ });
96
+ return valid;
97
+ }
98
+ },
99
+ // attributes: space seperated list of attributes to retrieve and remove
100
+ removeAttrs: function( attributes ) {
101
+ var result = {},
102
+ $element = this;
103
+ $.each(attributes.split(/\s/), function( index, value ) {
104
+ result[value] = $element.attr(value);
105
+ $element.removeAttr(value);
106
+ });
107
+ return result;
108
+ },
109
+ // http://docs.jquery.com/Plugins/Validation/rules
110
+ rules: function( command, argument ) {
111
+ var element = this[0];
112
+
113
+ if ( command ) {
114
+ var settings = $.data(element.form, "validator").settings;
115
+ var staticRules = settings.rules;
116
+ var existingRules = $.validator.staticRules(element);
117
+ switch(command) {
118
+ case "add":
119
+ $.extend(existingRules, $.validator.normalizeRule(argument));
120
+ staticRules[element.name] = existingRules;
121
+ if ( argument.messages ) {
122
+ settings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages );
123
+ }
124
+ break;
125
+ case "remove":
126
+ if ( !argument ) {
127
+ delete staticRules[element.name];
128
+ return existingRules;
129
+ }
130
+ var filtered = {};
131
+ $.each(argument.split(/\s/), function( index, method ) {
132
+ filtered[method] = existingRules[method];
133
+ delete existingRules[method];
134
+ });
135
+ return filtered;
136
+ }
137
+ }
138
+
139
+ var data = $.validator.normalizeRules(
140
+ $.extend(
141
+ {},
142
+ $.validator.classRules(element),
143
+ $.validator.attributeRules(element),
144
+ $.validator.dataRules(element),
145
+ $.validator.staticRules(element)
146
+ ), element);
147
+
148
+ // make sure required is at front
149
+ if ( data.required ) {
150
+ var param = data.required;
151
+ delete data.required;
152
+ data = $.extend({required: param}, data);
153
+ }
154
+
155
+ return data;
156
+ }
157
+ });
158
+
159
+ // Custom selectors
160
+ $.extend($.expr[":"], {
161
+ // http://docs.jquery.com/Plugins/Validation/blank
162
+ blank: function( a ) { return !$.trim("" + a.value); },
163
+ // http://docs.jquery.com/Plugins/Validation/filled
164
+ filled: function( a ) { return !!$.trim("" + a.value); },
165
+ // http://docs.jquery.com/Plugins/Validation/unchecked
166
+ unchecked: function( a ) { return !a.checked; }
167
+ });
168
+
169
+ // constructor for validator
170
+ $.validator = function( options, form ) {
171
+ this.settings = $.extend( true, {}, $.validator.defaults, options );
172
+ this.currentForm = form;
173
+ this.init();
174
+ };
175
+
176
+ $.validator.format = function( source, params ) {
177
+ if ( arguments.length === 1 ) {
178
+ return function() {
179
+ var args = $.makeArray(arguments);
180
+ args.unshift(source);
181
+ return $.validator.format.apply( this, args );
182
+ };
183
+ }
184
+ if ( arguments.length > 2 && params.constructor !== Array ) {
185
+ params = $.makeArray(arguments).slice(1);
186
+ }
187
+ if ( params.constructor !== Array ) {
188
+ params = [ params ];
189
+ }
190
+ $.each(params, function( i, n ) {
191
+ source = source.replace( new RegExp("\\{" + i + "\\}", "g"), function() {
192
+ return n;
193
+ });
194
+ });
195
+ return source;
196
+ };
197
+
198
+ $.extend($.validator, {
199
+
200
+ defaults: {
201
+ messages: {},
202
+ groups: {},
203
+ rules: {},
204
+ errorClass: "error",
205
+ validClass: "valid",
206
+ errorElement: "label",
207
+ focusInvalid: true,
208
+ errorContainer: $([]),
209
+ errorLabelContainer: $([]),
210
+ onsubmit: true,
211
+ ignore: ":hidden",
212
+ ignoreTitle: false,
213
+ onfocusin: function( element, event ) {
214
+ this.lastActive = element;
215
+
216
+ // hide error label and remove error class on focus if enabled
217
+ if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {
218
+ if ( this.settings.unhighlight ) {
219
+ this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
220
+ }
221
+ this.addWrapper(this.errorsFor(element)).hide();
222
+ }
223
+ },
224
+ onfocusout: function( element, event ) {
225
+ if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) {
226
+ this.element(element);
227
+ }
228
+ },
229
+ onkeyup: function( element, event ) {
230
+ if ( event.which === 9 && this.elementValue(element) === "" ) {
231
+ return;
232
+ } else if ( element.name in this.submitted || element === this.lastElement ) {
233
+ this.element(element);
234
+ }
235
+ },
236
+ onclick: function( element, event ) {
237
+ // click on selects, radiobuttons and checkboxes
238
+ if ( element.name in this.submitted ) {
239
+ this.element(element);
240
+ }
241
+ // or option elements, check parent select in that case
242
+ else if ( element.parentNode.name in this.submitted ) {
243
+ this.element(element.parentNode);
244
+ }
245
+ },
246
+ highlight: function( element, errorClass, validClass ) {
247
+ if ( element.type === "radio" ) {
248
+ this.findByName(element.name).addClass(errorClass).removeClass(validClass);
249
+ } else {
250
+ $(element).addClass(errorClass).removeClass(validClass);
251
+ }
252
+ },
253
+ unhighlight: function( element, errorClass, validClass ) {
254
+ if ( element.type === "radio" ) {
255
+ this.findByName(element.name).removeClass(errorClass).addClass(validClass);
256
+ } else {
257
+ $(element).removeClass(errorClass).addClass(validClass);
258
+ }
259
+ }
260
+ },
261
+
262
+ // http://docs.jquery.com/Plugins/Validation/Validator/setDefaults
263
+ setDefaults: function( settings ) {
264
+ $.extend( $.validator.defaults, settings );
265
+ },
266
+
267
+ messages: {
268
+ required: "This field is required.",
269
+ remote: "Please fix this field.",
270
+ email: "Please enter a valid email address.",
271
+ url: "Please enter a valid URL.",
272
+ date: "Please enter a valid date.",
273
+ dateISO: "Please enter a valid date (ISO).",
274
+ number: "Please enter a valid number.",
275
+ digits: "Please enter only digits.",
276
+ creditcard: "Please enter a valid credit card number.",
277
+ equalTo: "Please enter the same value again.",
278
+ maxlength: $.validator.format("Please enter no more than {0} characters."),
279
+ minlength: $.validator.format("Please enter at least {0} characters."),
280
+ rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."),
281
+ range: $.validator.format("Please enter a value between {0} and {1}."),
282
+ max: $.validator.format("Please enter a value less than or equal to {0}."),
283
+ min: $.validator.format("Please enter a value greater than or equal to {0}.")
284
+ },
285
+
286
+ autoCreateRanges: false,
287
+
288
+ prototype: {
289
+
290
+ init: function() {
291
+ this.labelContainer = $(this.settings.errorLabelContainer);
292
+ this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm);
293
+ this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer );
294
+ this.submitted = {};
295
+ this.valueCache = {};
296
+ this.pendingRequest = 0;
297
+ this.pending = {};
298
+ this.invalid = {};
299
+ this.reset();
300
+
301
+ var groups = (this.groups = {});
302
+ $.each(this.settings.groups, function( key, value ) {
303
+ if ( typeof value === "string" ) {
304
+ value = value.split(/\s/);
305
+ }
306
+ $.each(value, function( index, name ) {
307
+ groups[name] = key;
308
+ });
309
+ });
310
+ var rules = this.settings.rules;
311
+ $.each(rules, function( key, value ) {
312
+ rules[key] = $.validator.normalizeRule(value);
313
+ });
314
+
315
+ function delegate(event) {
316
+ var validator = $.data(this[0].form, "validator"),
317
+ eventType = "on" + event.type.replace(/^validate/, "");
318
+ if ( validator.settings[eventType] ) {
319
+ validator.settings[eventType].call(validator, this[0], event);
320
+ }
321
+ }
322
+ $(this.currentForm)
323
+ .validateDelegate(":text, [type='password'], [type='file'], select, textarea, " +
324
+ "[type='number'], [type='search'] ,[type='tel'], [type='url'], " +
325
+ "[type='email'], [type='datetime'], [type='date'], [type='month'], " +
326
+ "[type='week'], [type='time'], [type='datetime-local'], " +
327
+ "[type='range'], [type='color'] ",
328
+ "focusin focusout keyup", delegate)
329
+ .validateDelegate("[type='radio'], [type='checkbox'], select, option", "click", delegate);
330
+
331
+ if ( this.settings.invalidHandler ) {
332
+ $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);
333
+ }
334
+ },
335
+
336
+ // http://docs.jquery.com/Plugins/Validation/Validator/form
337
+ form: function() {
338
+ this.checkForm();
339
+ $.extend(this.submitted, this.errorMap);
340
+ this.invalid = $.extend({}, this.errorMap);
341
+ if ( !this.valid() ) {
342
+ $(this.currentForm).triggerHandler("invalid-form", [this]);
343
+ }
344
+ this.showErrors();
345
+ return this.valid();
346
+ },
347
+
348
+ checkForm: function() {
349
+ this.prepareForm();
350
+ for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) {
351
+ this.check( elements[i] );
352
+ }
353
+ return this.valid();
354
+ },
355
+
356
+ // http://docs.jquery.com/Plugins/Validation/Validator/element
357
+ element: function( element ) {
358
+ element = this.validationTargetFor( this.clean( element ) );
359
+ this.lastElement = element;
360
+ this.prepareElement( element );
361
+ this.currentElements = $(element);
362
+ var result = this.check( element ) !== false;
363
+ if ( result ) {
364
+ delete this.invalid[element.name];
365
+ } else {
366
+ this.invalid[element.name] = true;
367
+ }
368
+ if ( !this.numberOfInvalids() ) {
369
+ // Hide error containers on last error
370
+ this.toHide = this.toHide.add( this.containers );
371
+ }
372
+ this.showErrors();
373
+ return result;
374
+ },
375
+
376
+ // http://docs.jquery.com/Plugins/Validation/Validator/showErrors
377
+ showErrors: function( errors ) {
378
+ if ( errors ) {
379
+ // add items to error list and map
380
+ $.extend( this.errorMap, errors );
381
+ this.errorList = [];
382
+ for ( var name in errors ) {
383
+ this.errorList.push({
384
+ message: errors[name],
385
+ element: this.findByName(name)[0]
386
+ });
387
+ }
388
+ // remove items from success list
389
+ this.successList = $.grep( this.successList, function( element ) {
390
+ return !(element.name in errors);
391
+ });
392
+ }
393
+ if ( this.settings.showErrors ) {
394
+ this.settings.showErrors.call( this, this.errorMap, this.errorList );
395
+ } else {
396
+ this.defaultShowErrors();
397
+ }
398
+ },
399
+
400
+ // http://docs.jquery.com/Plugins/Validation/Validator/resetForm
401
+ resetForm: function() {
402
+ if ( $.fn.resetForm ) {
403
+ $(this.currentForm).resetForm();
404
+ }
405
+ this.submitted = {};
406
+ this.lastElement = null;
407
+ this.prepareForm();
408
+ this.hideErrors();
409
+ this.elements().removeClass( this.settings.errorClass ).removeData( "previousValue" );
410
+ },
411
+
412
+ numberOfInvalids: function() {
413
+ return this.objectLength(this.invalid);
414
+ },
415
+
416
+ objectLength: function( obj ) {
417
+ var count = 0;
418
+ for ( var i in obj ) {
419
+ count++;
420
+ }
421
+ return count;
422
+ },
423
+
424
+ hideErrors: function() {
425
+ this.addWrapper( this.toHide ).hide();
426
+ },
427
+
428
+ valid: function() {
429
+ return this.size() === 0;
430
+ },
431
+
432
+ size: function() {
433
+ return this.errorList.length;
434
+ },
435
+
436
+ focusInvalid: function() {
437
+ if ( this.settings.focusInvalid ) {
438
+ try {
439
+ $(this.findLastActive() || this.errorList.length && this.errorList[0].element || [])
440
+ .filter(":visible")
441
+ .focus()
442
+ // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
443
+ .trigger("focusin");
444
+ } catch(e) {
445
+ // ignore IE throwing errors when focusing hidden elements
446
+ }
447
+ }
448
+ },
449
+
450
+ findLastActive: function() {
451
+ var lastActive = this.lastActive;
452
+ return lastActive && $.grep(this.errorList, function( n ) {
453
+ return n.element.name === lastActive.name;
454
+ }).length === 1 && lastActive;
455
+ },
456
+
457
+ elements: function() {
458
+ var validator = this,
459
+ rulesCache = {};
460
+
461
+ // select all valid inputs inside the form (no submit or reset buttons)
462
+ return $(this.currentForm)
463
+ .find("input, select, textarea")
464
+ .not(":submit, :reset, :image, [disabled]")
465
+ .not( this.settings.ignore )
466
+ .filter(function() {
467
+ if ( !this.name && validator.settings.debug && window.console ) {
468
+ console.error( "%o has no name assigned", this);
469
+ }
470
+
471
+ // select only the first element for each name, and only those with rules specified
472
+ if ( this.name in rulesCache || !validator.objectLength($(this).rules()) ) {
473
+ return false;
474
+ }
475
+
476
+ rulesCache[this.name] = true;
477
+ return true;
478
+ });
479
+ },
480
+
481
+ clean: function( selector ) {
482
+ return $(selector)[0];
483
+ },
484
+
485
+ errors: function() {
486
+ var errorClass = this.settings.errorClass.replace(" ", ".");
487
+ return $(this.settings.errorElement + "." + errorClass, this.errorContext);
488
+ },
489
+
490
+ reset: function() {
491
+ this.successList = [];
492
+ this.errorList = [];
493
+ this.errorMap = {};
494
+ this.toShow = $([]);
495
+ this.toHide = $([]);
496
+ this.currentElements = $([]);
497
+ },
498
+
499
+ prepareForm: function() {
500
+ this.reset();
501
+ this.toHide = this.errors().add( this.containers );
502
+ },
503
+
504
+ prepareElement: function( element ) {
505
+ this.reset();
506
+ this.toHide = this.errorsFor(element);
507
+ },
508
+
509
+ elementValue: function( element ) {
510
+ var type = $(element).attr("type"),
511
+ val = $(element).val();
512
+
513
+ if ( type === "radio" || type === "checkbox" ) {
514
+ return $("input[name='" + $(element).attr("name") + "']:checked").val();
515
+ }
516
+
517
+ if ( typeof val === "string" ) {
518
+ return val.replace(/\r/g, "");
519
+ }
520
+ return val;
521
+ },
522
+
523
+ check: function( element ) {
524
+ element = this.validationTargetFor( this.clean( element ) );
525
+
526
+ var rules = $(element).rules();
527
+ var dependencyMismatch = false;
528
+ var val = this.elementValue(element);
529
+ var result;
530
+
531
+ for (var method in rules ) {
532
+ var rule = { method: method, parameters: rules[method] };
533
+ try {
534
+
535
+ result = $.validator.methods[method].call( this, val, element, rule.parameters );
536
+
537
+ // if a method indicates that the field is optional and therefore valid,
538
+ // don't mark it as valid when there are no other rules
539
+ if ( result === "dependency-mismatch" ) {
540
+ dependencyMismatch = true;
541
+ continue;
542
+ }
543
+ dependencyMismatch = false;
544
+
545
+ if ( result === "pending" ) {
546
+ this.toHide = this.toHide.not( this.errorsFor(element) );
547
+ return;
548
+ }
549
+
550
+ if ( !result ) {
551
+ this.formatAndAdd( element, rule );
552
+ return false;
553
+ }
554
+ } catch(e) {
555
+ if ( this.settings.debug && window.console ) {
556
+ console.log( "Exception occured when checking element " + element.id + ", check the '" + rule.method + "' method.", e );
557
+ }
558
+ throw e;
559
+ }
560
+ }
561
+ if ( dependencyMismatch ) {
562
+ return;
563
+ }
564
+ if ( this.objectLength(rules) ) {
565
+ this.successList.push(element);
566
+ }
567
+ return true;
568
+ },
569
+
570
+ // return the custom message for the given element and validation method
571
+ // specified in the element's HTML5 data attribute
572
+ customDataMessage: function( element, method ) {
573
+ return $(element).data("msg-" + method.toLowerCase()) || (element.attributes && $(element).attr("data-msg-" + method.toLowerCase()));
574
+ },
575
+
576
+ // return the custom message for the given element name and validation method
577
+ customMessage: function( name, method ) {
578
+ var m = this.settings.messages[name];
579
+ return m && (m.constructor === String ? m : m[method]);
580
+ },
581
+
582
+ // return the first defined argument, allowing empty strings
583
+ findDefined: function() {
584
+ for(var i = 0; i < arguments.length; i++) {
585
+ if ( arguments[i] !== undefined ) {
586
+ return arguments[i];
587
+ }
588
+ }
589
+ return undefined;
590
+ },
591
+
592
+ defaultMessage: function( element, method ) {
593
+ return this.findDefined(
594
+ this.customMessage( element.name, method ),
595
+ this.customDataMessage( element, method ),
596
+ // title is never undefined, so handle empty string as undefined
597
+ !this.settings.ignoreTitle && element.title || undefined,
598
+ $.validator.messages[method],
599
+ "<strong>Warning: No message defined for " + element.name + "</strong>"
600
+ );
601
+ },
602
+
603
+ formatAndAdd: function( element, rule ) {
604
+ var message = this.defaultMessage( element, rule.method ),
605
+ theregex = /\$?\{(\d+)\}/g;
606
+ if ( typeof message === "function" ) {
607
+ message = message.call(this, rule.parameters, element);
608
+ } else if (theregex.test(message)) {
609
+ message = $.validator.format(message.replace(theregex, "{$1}"), rule.parameters);
610
+ }
611
+ this.errorList.push({
612
+ message: message,
613
+ element: element
614
+ });
615
+
616
+ this.errorMap[element.name] = message;
617
+ this.submitted[element.name] = message;
618
+ },
619
+
620
+ addWrapper: function( toToggle ) {
621
+ if ( this.settings.wrapper ) {
622
+ toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
623
+ }
624
+ return toToggle;
625
+ },
626
+
627
+ defaultShowErrors: function() {
628
+ var i, elements;
629
+ for ( i = 0; this.errorList[i]; i++ ) {
630
+ var error = this.errorList[i];
631
+ if ( this.settings.highlight ) {
632
+ this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
633
+ }
634
+ this.showLabel( error.element, error.message );
635
+ }
636
+ if ( this.errorList.length ) {
637
+ this.toShow = this.toShow.add( this.containers );
638
+ }
639
+ if ( this.settings.success ) {
640
+ for ( i = 0; this.successList[i]; i++ ) {
641
+ this.showLabel( this.successList[i] );
642
+ }
643
+ }
644
+ if ( this.settings.unhighlight ) {
645
+ for ( i = 0, elements = this.validElements(); elements[i]; i++ ) {
646
+ this.settings.unhighlight.call( this, elements[i], this.settings.errorClass, this.settings.validClass );
647
+ }
648
+ }
649
+ this.toHide = this.toHide.not( this.toShow );
650
+ this.hideErrors();
651
+ this.addWrapper( this.toShow ).show();
652
+ },
653
+
654
+ validElements: function() {
655
+ return this.currentElements.not(this.invalidElements());
656
+ },
657
+
658
+ invalidElements: function() {
659
+ return $(this.errorList).map(function() {
660
+ return this.element;
661
+ });
662
+ },
663
+
664
+ showLabel: function( element, message ) {
665
+ var label = this.errorsFor( element );
666
+ if ( label.length ) {
667
+ // refresh error/success class
668
+ label.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );
669
+ // replace message on existing label
670
+ label.html(message);
671
+ } else {
672
+ // create label
673
+ label = $("<" + this.settings.errorElement + ">")
674
+ .attr("for", this.idOrName(element))
675
+ .addClass(this.settings.errorClass)
676
+ .html(message || "");
677
+ if ( this.settings.wrapper ) {
678
+ // make sure the element is visible, even in IE
679
+ // actually showing the wrapped element is handled elsewhere
680
+ label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
681
+ }
682
+ if ( !this.labelContainer.append(label).length ) {
683
+ if ( this.settings.errorPlacement ) {
684
+ this.settings.errorPlacement(label, $(element) );
685
+ } else {
686
+ label.insertAfter(element);
687
+ }
688
+ }
689
+ }
690
+ if ( !message && this.settings.success ) {
691
+ label.text("");
692
+ if ( typeof this.settings.success === "string" ) {
693
+ label.addClass( this.settings.success );
694
+ } else {
695
+ this.settings.success( label, element );
696
+ }
697
+ }
698
+ this.toShow = this.toShow.add(label);
699
+ },
700
+
701
+ errorsFor: function( element ) {
702
+ var name = this.idOrName(element);
703
+ return this.errors().filter(function() {
704
+ return $(this).attr("for") === name;
705
+ });
706
+ },
707
+
708
+ idOrName: function( element ) {
709
+ return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name);
710
+ },
711
+
712
+ validationTargetFor: function( element ) {
713
+ // if radio/checkbox, validate first element in group instead
714
+ if ( this.checkable(element) ) {
715
+ element = this.findByName( element.name ).not(this.settings.ignore)[0];
716
+ }
717
+ return element;
718
+ },
719
+
720
+ checkable: function( element ) {
721
+ return (/radio|checkbox/i).test(element.type);
722
+ },
723
+
724
+ findByName: function( name ) {
725
+ return $(this.currentForm).find("[name='" + name + "']");
726
+ },
727
+
728
+ getLength: function( value, element ) {
729
+ switch( element.nodeName.toLowerCase() ) {
730
+ case "select":
731
+ return $("option:selected", element).length;
732
+ case "input":
733
+ if ( this.checkable( element) ) {
734
+ return this.findByName(element.name).filter(":checked").length;
735
+ }
736
+ }
737
+ return value.length;
738
+ },
739
+
740
+ depend: function( param, element ) {
741
+ return this.dependTypes[typeof param] ? this.dependTypes[typeof param](param, element) : true;
742
+ },
743
+
744
+ dependTypes: {
745
+ "boolean": function( param, element ) {
746
+ return param;
747
+ },
748
+ "string": function( param, element ) {
749
+ return !!$(param, element.form).length;
750
+ },
751
+ "function": function( param, element ) {
752
+ return param(element);
753
+ }
754
+ },
755
+
756
+ optional: function( element ) {
757
+ var val = this.elementValue(element);
758
+ return !$.validator.methods.required.call(this, val, element) && "dependency-mismatch";
759
+ },
760
+
761
+ startRequest: function( element ) {
762
+ if ( !this.pending[element.name] ) {
763
+ this.pendingRequest++;
764
+ this.pending[element.name] = true;
765
+ }
766
+ },
767
+
768
+ stopRequest: function( element, valid ) {
769
+ this.pendingRequest--;
770
+ // sometimes synchronization fails, make sure pendingRequest is never < 0
771
+ if ( this.pendingRequest < 0 ) {
772
+ this.pendingRequest = 0;
773
+ }
774
+ delete this.pending[element.name];
775
+ if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) {
776
+ $(this.currentForm).submit();
777
+ this.formSubmitted = false;
778
+ } else if (!valid && this.pendingRequest === 0 && this.formSubmitted) {
779
+ $(this.currentForm).triggerHandler("invalid-form", [this]);
780
+ this.formSubmitted = false;
781
+ }
782
+ },
783
+
784
+ previousValue: function( element ) {
785
+ return $.data(element, "previousValue") || $.data(element, "previousValue", {
786
+ old: null,
787
+ valid: true,
788
+ message: this.defaultMessage( element, "remote" )
789
+ });
790
+ }
791
+
792
+ },
793
+
794
+ classRuleSettings: {
795
+ required: {required: true},
796
+ email: {email: true},
797
+ url: {url: true},
798
+ date: {date: true},
799
+ dateISO: {dateISO: true},
800
+ number: {number: true},
801
+ digits: {digits: true},
802
+ creditcard: {creditcard: true}
803
+ },
804
+
805
+ addClassRules: function( className, rules ) {
806
+ if ( className.constructor === String ) {
807
+ this.classRuleSettings[className] = rules;
808
+ } else {
809
+ $.extend(this.classRuleSettings, className);
810
+ }
811
+ },
812
+
813
+ classRules: function( element ) {
814
+ var rules = {};
815
+ var classes = $(element).attr("class");
816
+ if ( classes ) {
817
+ $.each(classes.split(" "), function() {
818
+ if ( this in $.validator.classRuleSettings ) {
819
+ $.extend(rules, $.validator.classRuleSettings[this]);
820
+ }
821
+ });
822
+ }
823
+ return rules;
824
+ },
825
+
826
+ attributeRules: function( element ) {
827
+ var rules = {};
828
+ var $element = $(element);
829
+
830
+ for (var method in $.validator.methods) {
831
+ var value;
832
+
833
+ // support for <input required> in both html5 and older browsers
834
+ if ( method === "required" ) {
835
+ value = $element.get(0).getAttribute(method);
836
+ // Some browsers return an empty string for the required attribute
837
+ // and non-HTML5 browsers might have required="" markup
838
+ if ( value === "" ) {
839
+ value = true;
840
+ }
841
+ // force non-HTML5 browsers to return bool
842
+ value = !!value;
843
+ } else {
844
+ value = $element.attr(method);
845
+ }
846
+
847
+ if ( value ) {
848
+ rules[method] = value;
849
+ } else if ( $element[0].getAttribute("type") === method ) {
850
+ rules[method] = true;
851
+ }
852
+ }
853
+
854
+ // maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs
855
+ if ( rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength) ) {
856
+ delete rules.maxlength;
857
+ }
858
+
859
+ return rules;
860
+ },
861
+
862
+ dataRules: function( element ) {
863
+ var method, value,
864
+ rules = {}, $element = $(element);
865
+ for (method in $.validator.methods) {
866
+ value = $element.data("rule-" + method.toLowerCase());
867
+ if ( value !== undefined ) {
868
+ rules[method] = value;
869
+ }
870
+ }
871
+ return rules;
872
+ },
873
+
874
+ staticRules: function( element ) {
875
+ var rules = {};
876
+ var validator = $.data(element.form, "validator");
877
+ if ( validator.settings.rules ) {
878
+ rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {};
879
+ }
880
+ return rules;
881
+ },
882
+
883
+ normalizeRules: function( rules, element ) {
884
+ // handle dependency check
885
+ $.each(rules, function( prop, val ) {
886
+ // ignore rule when param is explicitly false, eg. required:false
887
+ if ( val === false ) {
888
+ delete rules[prop];
889
+ return;
890
+ }
891
+ if ( val.param || val.depends ) {
892
+ var keepRule = true;
893
+ switch (typeof val.depends) {
894
+ case "string":
895
+ keepRule = !!$(val.depends, element.form).length;
896
+ break;
897
+ case "function":
898
+ keepRule = val.depends.call(element, element);
899
+ break;
900
+ }
901
+ if ( keepRule ) {
902
+ rules[prop] = val.param !== undefined ? val.param : true;
903
+ } else {
904
+ delete rules[prop];
905
+ }
906
+ }
907
+ });
908
+
909
+ // evaluate parameters
910
+ $.each(rules, function( rule, parameter ) {
911
+ rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter;
912
+ });
913
+
914
+ // clean number parameters
915
+ $.each(['minlength', 'maxlength'], function() {
916
+ if ( rules[this] ) {
917
+ rules[this] = Number(rules[this]);
918
+ }
919
+ });
920
+ $.each(['rangelength'], function() {
921
+ var parts;
922
+ if ( rules[this] ) {
923
+ if ( $.isArray(rules[this]) ) {
924
+ rules[this] = [Number(rules[this][0]), Number(rules[this][1])];
925
+ } else if ( typeof rules[this] === "string" ) {
926
+ parts = rules[this].split(/[\s,]+/);
927
+ rules[this] = [Number(parts[0]), Number(parts[1])];
928
+ }
929
+ }
930
+ });
931
+
932
+ if ( $.validator.autoCreateRanges ) {
933
+ // auto-create ranges
934
+ if ( rules.min && rules.max ) {
935
+ rules.range = [rules.min, rules.max];
936
+ delete rules.min;
937
+ delete rules.max;
938
+ }
939
+ if ( rules.minlength && rules.maxlength ) {
940
+ rules.rangelength = [rules.minlength, rules.maxlength];
941
+ delete rules.minlength;
942
+ delete rules.maxlength;
943
+ }
944
+ }
945
+
946
+ return rules;
947
+ },
948
+
949
+ // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
950
+ normalizeRule: function( data ) {
951
+ if ( typeof data === "string" ) {
952
+ var transformed = {};
953
+ $.each(data.split(/\s/), function() {
954
+ transformed[this] = true;
955
+ });
956
+ data = transformed;
957
+ }
958
+ return data;
959
+ },
960
+
961
+ // http://docs.jquery.com/Plugins/Validation/Validator/addMethod
962
+ addMethod: function( name, method, message ) {
963
+ $.validator.methods[name] = method;
964
+ $.validator.messages[name] = message !== undefined ? message : $.validator.messages[name];
965
+ if ( method.length < 3 ) {
966
+ $.validator.addClassRules(name, $.validator.normalizeRule(name));
967
+ }
968
+ },
969
+
970
+ methods: {
971
+
972
+ // http://docs.jquery.com/Plugins/Validation/Methods/required
973
+ required: function( value, element, param ) {
974
+ // check if dependency is met
975
+ if ( !this.depend(param, element) ) {
976
+ return "dependency-mismatch";
977
+ }
978
+ if ( element.nodeName.toLowerCase() === "select" ) {
979
+ // could be an array for select-multiple or a string, both are fine this way
980
+ var val = $(element).val();
981
+ return val && val.length > 0;
982
+ }
983
+ if ( this.checkable(element) ) {
984
+ return this.getLength(value, element) > 0;
985
+ }
986
+ return $.trim(value).length > 0;
987
+ },
988
+
989
+ // http://docs.jquery.com/Plugins/Validation/Methods/remote
990
+ remote: function( value, element, param ) {
991
+ if ( this.optional(element) ) {
992
+ return "dependency-mismatch";
993
+ }
994
+
995
+ var previous = this.previousValue(element);
996
+ if (!this.settings.messages[element.name] ) {
997
+ this.settings.messages[element.name] = {};
998
+ }
999
+ previous.originalMessage = this.settings.messages[element.name].remote;
1000
+ this.settings.messages[element.name].remote = previous.message;
1001
+
1002
+ param = typeof param === "string" && {url:param} || param;
1003
+
1004
+ if ( previous.old === value ) {
1005
+ return previous.valid;
1006
+ }
1007
+
1008
+ previous.old = value;
1009
+ var validator = this;
1010
+ this.startRequest(element);
1011
+ var data = {};
1012
+ data[element.name] = value;
1013
+ $.ajax($.extend(true, {
1014
+ url: param,
1015
+ mode: "abort",
1016
+ port: "validate" + element.name,
1017
+ dataType: "json",
1018
+ data: data,
1019
+ success: function( response ) {
1020
+ validator.settings.messages[element.name].remote = previous.originalMessage;
1021
+ var valid = response === true || response === "true";
1022
+ if ( valid ) {
1023
+ var submitted = validator.formSubmitted;
1024
+ validator.prepareElement(element);
1025
+ validator.formSubmitted = submitted;
1026
+ validator.successList.push(element);
1027
+ delete validator.invalid[element.name];
1028
+ validator.showErrors();
1029
+ } else {
1030
+ var errors = {};
1031
+ var message = response || validator.defaultMessage( element, "remote" );
1032
+ errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message;
1033
+ validator.invalid[element.name] = true;
1034
+ validator.showErrors(errors);
1035
+ }
1036
+ previous.valid = valid;
1037
+ validator.stopRequest(element, valid);
1038
+ }
1039
+ }, param));
1040
+ return "pending";
1041
+ },
1042
+
1043
+ // http://docs.jquery.com/Plugins/Validation/Methods/minlength
1044
+ minlength: function( value, element, param ) {
1045
+ var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element);
1046
+ return this.optional(element) || length >= param;
1047
+ },
1048
+
1049
+ // http://docs.jquery.com/Plugins/Validation/Methods/maxlength
1050
+ maxlength: function( value, element, param ) {
1051
+ var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element);
1052
+ return this.optional(element) || length <= param;
1053
+ },
1054
+
1055
+ // http://docs.jquery.com/Plugins/Validation/Methods/rangelength
1056
+ rangelength: function( value, element, param ) {
1057
+ var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element);
1058
+ return this.optional(element) || ( length >= param[0] && length <= param[1] );
1059
+ },
1060
+
1061
+ // http://docs.jquery.com/Plugins/Validation/Methods/min
1062
+ min: function( value, element, param ) {
1063
+ return this.optional(element) || value >= param;
1064
+ },
1065
+
1066
+ // http://docs.jquery.com/Plugins/Validation/Methods/max
1067
+ max: function( value, element, param ) {
1068
+ return this.optional(element) || value <= param;
1069
+ },
1070
+
1071
+ // http://docs.jquery.com/Plugins/Validation/Methods/range
1072
+ range: function( value, element, param ) {
1073
+ return this.optional(element) || ( value >= param[0] && value <= param[1] );
1074
+ },
1075
+
1076
+ // http://docs.jquery.com/Plugins/Validation/Methods/email
1077
+ email: function( value, element ) {
1078
+ // contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
1079
+ return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value);
1080
+ },
1081
+
1082
+ // http://docs.jquery.com/Plugins/Validation/Methods/url
1083
+ url: function( value, element ) {
1084
+ // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
1085
+ return this.optional(element) || /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
1086
+ },
1087
+
1088
+ // http://docs.jquery.com/Plugins/Validation/Methods/date
1089
+ date: function( value, element ) {
1090
+ return this.optional(element) || !/Invalid|NaN/.test(new Date(value).toString());
1091
+ },
1092
+
1093
+ // http://docs.jquery.com/Plugins/Validation/Methods/dateISO
1094
+ dateISO: function( value, element ) {
1095
+ return this.optional(element) || /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(value);
1096
+ },
1097
+
1098
+ // http://docs.jquery.com/Plugins/Validation/Methods/number
1099
+ number: function( value, element ) {
1100
+ return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value);
1101
+ },
1102
+
1103
+ // http://docs.jquery.com/Plugins/Validation/Methods/digits
1104
+ digits: function( value, element ) {
1105
+ return this.optional(element) || /^\d+$/.test(value);
1106
+ },
1107
+
1108
+ // http://docs.jquery.com/Plugins/Validation/Methods/creditcard
1109
+ // based on http://en.wikipedia.org/wiki/Luhn
1110
+ creditcard: function( value, element ) {
1111
+ if ( this.optional(element) ) {
1112
+ return "dependency-mismatch";
1113
+ }
1114
+ // accept only spaces, digits and dashes
1115
+ if ( /[^0-9 \-]+/.test(value) ) {
1116
+ return false;
1117
+ }
1118
+ var nCheck = 0,
1119
+ nDigit = 0,
1120
+ bEven = false;
1121
+
1122
+ value = value.replace(/\D/g, "");
1123
+
1124
+ for (var n = value.length - 1; n >= 0; n--) {
1125
+ var cDigit = value.charAt(n);
1126
+ nDigit = parseInt(cDigit, 10);
1127
+ if ( bEven ) {
1128
+ if ( (nDigit *= 2) > 9 ) {
1129
+ nDigit -= 9;
1130
+ }
1131
+ }
1132
+ nCheck += nDigit;
1133
+ bEven = !bEven;
1134
+ }
1135
+
1136
+ return (nCheck % 10) === 0;
1137
+ },
1138
+
1139
+ // http://docs.jquery.com/Plugins/Validation/Methods/equalTo
1140
+ equalTo: function( value, element, param ) {
1141
+ // bind to the blur event of the target in order to revalidate whenever the target field is updated
1142
+ // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead
1143
+ var target = $(param);
1144
+ if ( this.settings.onfocusout ) {
1145
+ target.unbind(".validate-equalTo").bind("blur.validate-equalTo", function() {
1146
+ $(element).valid();
1147
+ });
1148
+ }
1149
+ return value === target.val();
1150
+ }
1151
+
1152
+ }
1153
+
1154
+ });
1155
+
1156
+ // deprecated, use $.validator.format instead
1157
+ $.format = $.validator.format;
1158
+
1159
+ }(jQuery));
1160
+
1161
+ // ajax mode: abort
1162
+ // usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
1163
+ // if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
1164
+ (function($) {
1165
+ var pendingRequests = {};
1166
+ // Use a prefilter if available (1.5+)
1167
+ if ( $.ajaxPrefilter ) {
1168
+ $.ajaxPrefilter(function( settings, _, xhr ) {
1169
+ var port = settings.port;
1170
+ if ( settings.mode === "abort" ) {
1171
+ if ( pendingRequests[port] ) {
1172
+ pendingRequests[port].abort();
1173
+ }
1174
+ pendingRequests[port] = xhr;
1175
+ }
1176
+ });
1177
+ } else {
1178
+ // Proxy ajax
1179
+ var ajax = $.ajax;
1180
+ $.ajax = function( settings ) {
1181
+ var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
1182
+ port = ( "port" in settings ? settings : $.ajaxSettings ).port;
1183
+ if ( mode === "abort" ) {
1184
+ if ( pendingRequests[port] ) {
1185
+ pendingRequests[port].abort();
1186
+ }
1187
+ return (pendingRequests[port] = ajax.apply(this, arguments));
1188
+ }
1189
+ return ajax.apply(this, arguments);
1190
+ };
1191
+ }
1192
+ }(jQuery));
1193
+
1194
+ // provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
1195
+ // handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target
1196
+ (function($) {
1197
+ $.extend($.fn, {
1198
+ validateDelegate: function( delegate, type, handler ) {
1199
+ return this.bind(type, function( event ) {
1200
+ var target = $(event.target);
1201
+ if ( target.is(delegate) ) {
1202
+ return handler.apply(target, arguments);
1203
+ }
1204
+ });
1205
+ }
1206
+ });
1207
+ }(jQuery));
js/jquery.validate.min.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! jQuery Validation Plugin - v1.10.0 - 9/7/2012
2
  * https://github.com/jzaefferer/jquery-validation
3
- * Copyright (c) 2012 Jörn Zaefferer; Licensed MIT, GPL */
4
- (function(a){a.extend(a.fn,{validate:function(b){if(!this.length){b&&b.debug&&window.console&&console.warn("nothing selected, can't validate, returning nothing");return}var c=a.data(this[0],"validator");return c?c:(this.attr("novalidate","novalidate"),c=new a.validator(b,this[0]),a.data(this[0],"validator",c),c.settings.onsubmit&&(this.validateDelegate(":submit","click",function(b){c.settings.submitHandler&&(c.submitButton=b.target),a(b.target).hasClass("cancel")&&(c.cancelSubmit=!0)}),this.submit(function(b){function d(){var d;return c.settings.submitHandler?(c.submitButton&&(d=a("<input type='hidden'/>").attr("name",c.submitButton.name).val(c.submitButton.value).appendTo(c.currentForm)),c.settings.submitHandler.call(c,c.currentForm,b),c.submitButton&&d.remove(),!1):!0}return c.settings.debug&&b.preventDefault(),c.cancelSubmit?(c.cancelSubmit=!1,d()):c.form()?c.pendingRequest?(c.formSubmitted=!0,!1):d():(c.focusInvalid(),!1)})),c)},valid:function(){if(a(this[0]).is("form"))return this.validate().form();var b=!0,c=a(this[0].form).validate();return this.each(function(){b&=c.element(this)}),b},removeAttrs:function(b){var c={},d=this;return a.each(b.split(/\s/),function(a,b){c[b]=d.attr(b),d.removeAttr(b)}),c},rules:function(b,c){var d=this[0];if(b){var e=a.data(d.form,"validator").settings,f=e.rules,g=a.validator.staticRules(d);switch(b){case"add":a.extend(g,a.validator.normalizeRule(c)),f[d.name]=g,c.messages&&(e.messages[d.name]=a.extend(e.messages[d.name],c.messages));break;case"remove":if(!c)return delete f[d.name],g;var h={};return a.each(c.split(/\s/),function(a,b){h[b]=g[b],delete g[b]}),h}}var i=a.validator.normalizeRules(a.extend({},a.validator.metadataRules(d),a.validator.classRules(d),a.validator.attributeRules(d),a.validator.staticRules(d)),d);if(i.required){var j=i.required;delete i.required,i=a.extend({required:j},i)}return i}}),a.extend(a.expr[":"],{blank:function(b){return!a.trim(""+b.value)},filled:function(b){return!!a.trim(""+b.value)},unchecked:function(a){return!a.checked}}),a.validator=function(b,c){this.settings=a.extend(!0,{},a.validator.defaults,b),this.currentForm=c,this.init()},a.validator.format=function(b,c){return arguments.length===1?function(){var c=a.makeArray(arguments);return c.unshift(b),a.validator.format.apply(this,c)}:(arguments.length>2&&c.constructor!==Array&&(c=a.makeArray(arguments).slice(1)),c.constructor!==Array&&(c=[c]),a.each(c,function(a,c){b=b.replace(new RegExp("\\{"+a+"\\}","g"),c)}),b)},a.extend(a.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",validClass:"valid",errorElement:"label",focusInvalid:!0,errorContainer:a([]),errorLabelContainer:a([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(a,b){this.lastActive=a,this.settings.focusCleanup&&!this.blockFocusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass),this.addWrapper(this.errorsFor(a)).hide())},onfocusout:function(a,b){!this.checkable(a)&&(a.name in this.submitted||!this.optional(a))&&this.element(a)},onkeyup:function(a,b){if(b.which===9&&this.elementValue(a)==="")return;(a.name in this.submitted||a===this.lastActive)&&this.element(a)},onclick:function(a,b){a.name in this.submitted?this.element(a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(b,c,d){b.type==="radio"?this.findByName(b.name).addClass(c).removeClass(d):a(b).addClass(c).removeClass(d)},unhighlight:function(b,c,d){b.type==="radio"?this.findByName(b.name).removeClass(c).addClass(d):a(b).removeClass(c).addClass(d)}},setDefaults:function(b){a.extend(a.validator.defaults,b)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date (ISO).",number:"Please enter a valid number.",digits:"Please enter only digits.",creditcard:"Please enter a valid credit card number.",equalTo:"Please enter the same value again.",maxlength:a.validator.format("Please enter no more than {0} characters."),minlength:a.validator.format("Please enter at least {0} characters."),rangelength:a.validator.format("Please enter a value between {0} and {1} characters long."),range:a.validator.format("Please enter a value between {0} and {1}."),max:a.validator.format("Please enter a value less than or equal to {0}."),min:a.validator.format("Please enter a value greater than or equal to {0}.")},autoCreateRanges:!1,prototype:{init:function(){function d(b){var c=a.data(this[0].form,"validator"),d="on"+b.type.replace(/^validate/,"");c.settings[d]&&c.settings[d].call(c,this[0],b)}this.labelContainer=a(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||a(this.currentForm),this.containers=a(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var b=this.groups={};a.each(this.settings.groups,function(c,d){a.each(d.split(/\s/),function(a,d){b[d]=c})});var c=this.settings.rules;a.each(c,function(b,d){c[b]=a.validator.normalizeRule(d)}),a(this.currentForm).validateDelegate(":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'] ,[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'] ","focusin focusout keyup",d).validateDelegate("[type='radio'], [type='checkbox'], select, option","click",d),this.settings.invalidHandler&&a(this.currentForm).bind("invalid-form.validate",this.settings.invalidHandler)},form:function(){return this.checkForm(),a.extend(this.submitted,this.errorMap),this.invalid=a.extend({},this.errorMap),this.valid()||a(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(b){b=this.validationTargetFor(this.clean(b)),this.lastElement=b,this.prepareElement(b),this.currentElements=a(b);var c=this.check(b)!==!1;return c?delete this.invalid[b.name]:this.invalid[b.name]=!0,this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),c},showErrors:function(b){if(b){a.extend(this.errorMap,b),this.errorList=[];for(var c in b)this.errorList.push({message:b[c],element:this.findByName(c)[0]});this.successList=a.grep(this.successList,function(a){return!(a.name in b)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){a.fn.resetForm&&a(this.currentForm).resetForm(),this.submitted={},this.lastElement=null,this.prepareForm(),this.hideErrors(),this.elements().removeClass(this.settings.errorClass).removeData("previousValue")},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b=0;for(var c in a)b++;return b},hideErrors:function(){this.addWrapper(this.toHide).hide()},valid:function(){return this.size()===0},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{a(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(b){}},findLastActive:function(){var b=this.lastActive;return b&&a.grep(this.errorList,function(a){return a.element.name===b.name}).length===1&&b},elements:function(){var b=this,c={};return a(this.currentForm).find("input, select, textarea").not(":submit, :reset, :image, [disabled]").not(this.settings.ignore).filter(function(){return!this.name&&b.settings.debug&&window.console&&console.error("%o has no name assigned",this),this.name in c||!b.objectLength(a(this).rules())?!1:(c[this.name]=!0,!0)})},clean:function(b){return a(b)[0]},errors:function(){var b=this.settings.errorClass.replace(" ",".");return a(this.settings.errorElement+"."+b,this.errorContext)},reset:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=a([]),this.toHide=a([]),this.currentElements=a([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(a){this.reset(),this.toHide=this.errorsFor(a)},elementValue:function(b){var c=a(b).attr("type"),d=a(b).val();return c==="radio"||c==="checkbox"?a('input[name="'+a(b).attr("name")+'"]:checked').val():typeof d=="string"?d.replace(/\r/g,""):d},check:function(b){b=this.validationTargetFor(this.clean(b));var c=a(b).rules(),d=!1,e=this.elementValue(b),f;for(var g in c){var h={method:g,parameters:c[g]};try{f=a.validator.methods[g].call(this,e,b,h.parameters);if(f==="dependency-mismatch"){d=!0;continue}d=!1;if(f==="pending"){this.toHide=this.toHide.not(this.errorsFor(b));return}if(!f)return this.formatAndAdd(b,h),!1}catch(i){throw this.settings.debug&&window.console&&console.log("exception occured when checking element "+b.id+", check the '"+h.method+"' method",i),i}}if(d)return;return this.objectLength(c)&&this.successList.push(b),!0},customMetaMessage:function(b,c){if(!a.metadata)return;var d=this.settings.meta?a(b).metadata()[this.settings.meta]:a(b).metadata();return d&&d.messages&&d.messages[c]},customDataMessage:function(b,c){return a(b).data("msg-"+c.toLowerCase())||b.attributes&&a(b).attr("data-msg-"+c.toLowerCase())},customMessage:function(a,b){var c=this.settings.messages[a];return c&&(c.constructor===String?c:c[b])},findDefined:function(){for(var a=0;a<arguments.length;a++)if(arguments[a]!==undefined)return arguments[a];return undefined},defaultMessage:function(b,c){return this.findDefined(this.customMessage(b.name,c),this.customDataMessage(b,c),this.customMetaMessage(b,c),!this.settings.ignoreTitle&&b.title||undefined,a.validator.messages[c],"<strong>Warning: No message defined for "+b.name+"</strong>")},formatAndAdd:function(b,c){var d=this.defaultMessage(b,c.method),e=/\$?\{(\d+)\}/g;typeof d=="function"?d=d.call(this,c.parameters,b):e.test(d)&&(d=a.validator.format(d.replace(e,"{$1}"),c.parameters)),this.errorList.push({message:d,element:b}),this.errorMap[b.name]=d,this.submitted[b.name]=d},addWrapper:function(a){return this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper))),a},defaultShowErrors:function(){var a,b;for(a=0;this.errorList[a];a++){var c=this.errorList[a];this.settings.highlight&&this.settings.highlight.call(this,c.element,this.settings.errorClass,this.settings.validClass),this.showLabel(c.element,c.message)}this.errorList.length&&(this.toShow=this.toShow.add(this.containers));if(this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight)for(a=0,b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return a(this.errorList).map(function(){return this.element})},showLabel:function(b,c){var d=this.errorsFor(b);d.length?(d.removeClass(this.settings.validClass).addClass(this.settings.errorClass),d.attr("generated")&&d.html(c)):(d=a("<"+this.settings.errorElement+"/>").attr({"for":this.idOrName(b),generated:!0}).addClass(this.settings.errorClass).html(c||""),this.settings.wrapper&&(d=d.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.append(d).length||(this.settings.errorPlacement?this.settings.errorPlacement(d,a(b)):d.insertAfter(b))),!c&&this.settings.success&&(d.text(""),typeof this.settings.success=="string"?d.addClass(this.settings.success):this.settings.success(d,b)),this.toShow=this.toShow.add(d)},errorsFor:function(b){var c=this.idOrName(b);return this.errors().filter(function(){return a(this).attr("for")===c})},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(a){return this.checkable(a)&&(a=this.findByName(a.name).not(this.settings.ignore)[0]),a},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).find('[name="'+b+'"]')},getLength:function(b,c){switch(c.nodeName.toLowerCase()){case"select":return a("option:selected",c).length;case"input":if(this.checkable(c))return this.findByName(c.name).filter(":checked").length}return b.length},depend:function(a,b){return this.dependTypes[typeof a]?this.dependTypes[typeof a](a,b):!0},dependTypes:{"boolean":function(a,b){return a},string:function(b,c){return!!a(b,c.form).length},"function":function(a,b){return a(b)}},optional:function(b){var c=this.elementValue(b);return!a.validator.methods.required.call(this,c,b)&&"dependency-mismatch"},startRequest:function(a){this.pending[a.name]||(this.pendingRequest++,this.pending[a.name]=!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[b.name],c&&this.pendingRequest===0&&this.formSubmitted&&this.form()?(a(this.currentForm).submit(),this.formSubmitted=!1):!c&&this.pendingRequest===0&&this.formSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(b){return a.data(b,"previousValue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMessage(b,"remote")})}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(b,c){b.constructor===String?this.classRuleSettings[b]=c:a.extend(this.classRuleSettings,b)},classRules:function(b){var c={},d=a(b).attr("class");return d&&a.each(d.split(" "),function(){this in a.validator.classRuleSettings&&a.extend(c,a.validator.classRuleSettings[this])}),c},attributeRules:function(b){var c={},d=a(b);for(var e in a.validator.methods){var f;e==="required"?(f=d.get(0).getAttribute(e),f===""&&(f=!0),f=!!f):f=d.attr(e),f?c[e]=f:d[0].getAttribute("type")===e&&(c[e]=!0)}return c.maxlength&&/-1|2147483647|524288/.test(c.maxlength)&&delete c.maxlength,c},metadataRules:function(b){if(!a.metadata)return{};var c=a.data(b.form,"validator").settings.meta;return c?a(b).metadata()[c]:a(b).metadata()},staticRules:function(b){var c={},d=a.data(b.form,"validator");return d.settings.rules&&(c=a.validator.normalizeRule(d.settings.rules[b.name])||{}),c},normalizeRules:function(b,c){return a.each(b,function(d,e){if(e===!1){delete b[d];return}if(e.param||e.depends){var f=!0;switch(typeof e.depends){case"string":f=!!a(e.depends,c.form).length;break;case"function":f=e.depends.call(c,c)}f?b[d]=e.param!==undefined?e.param:!0:delete b[d]}}),a.each(b,function(d,e){b[d]=a.isFunction(e)?e(c):e}),a.each(["minlength","maxlength","min","max"],function(){b[this]&&(b[this]=Number(b[this]))}),a.each(["rangelength","range"],function(){b[this]&&(b[this]=[Number(b[this][0]),Number(b[this][1])])}),a.validator.autoCreateRanges&&(b.min&&b.max&&(b.range=[b.min,b.max],delete b.min,delete b.max),b.minlength&&b.maxlength&&(b.rangelength=[b.minlength,b.maxlength],delete b.minlength,delete b.maxlength)),b.messages&&delete b.messages,b},normalizeRule:function(b){if(typeof b=="string"){var c={};a.each(b.split(/\s/),function(){c[this]=!0}),b=c}return b},addMethod:function(b,c,d){a.validator.methods[b]=c,a.validator.messages[b]=d!==undefined?d:a.validator.messages[b],c.length<3&&a.validator.addClassRules(b,a.validator.normalizeRule(b))},methods:{required:function(b,c,d){if(!this.depend(d,c))return"dependency-mismatch";if(c.nodeName.toLowerCase()==="select"){var e=a(c).val();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:a.trim(b).length>0},remote:function(b,c,d){if(this.optional(c))return"dependency-mismatch";var e=this.previousValue(c);this.settings.messages[c.name]||(this.settings.messages[c.name]={}),e.originalMessage=this.settings.messages[c.name].remote,this.settings.messages[c.name].remote=e.message,d=typeof d=="string"&&{url:d}||d;if(this.pending[c.name])return"pending";if(e.old===b)return e.valid;e.old=b;var f=this;this.startRequest(c);var g={};return g[c.name]=b,a.ajax(a.extend(!0,{url:d,mode:"abort",port:"validate"+c.name,dataType:"json",data:g,success:function(d){f.settings.messages[c.name].remote=e.originalMessage;var g=d===!0||d==="true";if(g){var h=f.formSubmitted;f.prepareElement(c),f.formSubmitted=h,f.successList.push(c),delete f.invalid[c.name],f.showErrors()}else{var i={},j=d||f.defaultMessage(c,"remote");i[c.name]=e.message=a.isFunction(j)?j(b):j,f.invalid[c.name]=!0,f.showErrors(i)}e.valid=g,f.stopRequest(c,g)}},d)),"pending"},minlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(a.trim(b),c);return this.optional(c)||e>=d},maxlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(a.trim(b),c);return this.optional(c)||e<=d},rangelength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(a.trim(b),c);return this.optional(c)||e>=d[0]&&e<=d[1]},min:function(a,b,c){return this.optional(b)||a>=c},max:function(a,b,c){return this.optional(b)||a<=c},range:function(a,b,c){return this.optional(b)||a>=c[0]&&a<=c[1]},email:function(a,b){return this.optional(b)||/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(a)},url:function(a,b){return this.optional(b)||/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(a)},date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(new Date(a))},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(a)},number:function(a,b){return this.optional(b)||/^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},creditcard:function(a,b){if(this.optional(b))return"dependency-mismatch";if(/[^0-9 \-]+/.test(a))return!1;var c=0,d=0,e=!1;a=a.replace(/\D/g,"");for(var f=a.length-1;f>=0;f--){var g=a.charAt(f);d=parseInt(g,10),e&&(d*=2)>9&&(d-=9),c+=d,e=!e}return c%10===0},equalTo:function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.unbind(".validate-equalTo").bind("blur.validate-equalTo",function(){a(c).valid()}),b===e.val()}}}),a.format=a.validator.format})(jQuery),function(a){var b={};if(a.ajaxPrefilter)a.ajaxPrefilter(function(a,c,d){var e=a.port;a.mode==="abort"&&(b[e]&&b[e].abort(),b[e]=d)});else{var c=a.ajax;a.ajax=function(d){var e=("mode"in d?d:a.ajaxSettings).mode,f=("port"in d?d:a.ajaxSettings).port;return e==="abort"?(b[f]&&b[f].abort(),b[f]=c.apply(this,arguments)):c.apply(this,arguments)}}}(jQuery),function(a){!jQuery.event.special.focusin&&!jQuery.event.special.focusout&&document.addEventListener&&a.each({focus:"focusin",blur:"focusout"},function(b,c){function d(b){return b=a.event.fix(b),b.type=c,a.event.handle.call(this,b)}a.event.special[c]={setup:function(){this.addEventListener(b,d,!0)},teardown:function(){this.removeEventListener(b,d,!0)},handler:function(b){var d=arguments;return d[0]=a.event.fix(b),d[0].type=c,a.event.handle.apply(this,d)}}}),a.extend(a.fn,{validateDelegate:function(b,c,d){return this.bind(c,function(c){var e=a(c.target);if(e.is(b))return d.apply(e,arguments)})}})}(jQuery)
1
+ /*! jQuery Validation Plugin - v1.11.0 - 7/13/2013
2
  * https://github.com/jzaefferer/jquery-validation
3
+ * Copyright (c) 2013 Jörn Zaefferer; Licensed MIT */
4
+ (function(e){e.extend(e.fn,{validate:function(t){if(!this.length){t&&t.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing.");return}var n=e.data(this[0],"validator");return n?n:(this.attr("novalidate","novalidate"),n=new e.validator(t,this[0]),e.data(this[0],"validator",n),n.settings.onsubmit&&(this.validateDelegate(":submit","click",function(t){n.settings.submitHandler&&(n.submitButton=t.target),e(t.target).hasClass("cancel")&&(n.cancelSubmit=!0)}),this.submit(function(t){function r(){var r;return n.settings.submitHandler?(n.submitButton&&(r=e("<input type='hidden'/>").attr("name",n.submitButton.name).val(n.submitButton.value).appendTo(n.currentForm)),n.settings.submitHandler.call(n,n.currentForm,t),n.submitButton&&r.remove(),!1):!0}return n.settings.debug&&t.preventDefault(),n.cancelSubmit?(n.cancelSubmit=!1,r()):n.form()?n.pendingRequest?(n.formSubmitted=!0,!1):r():(n.focusInvalid(),!1)})),n)},valid:function(){if(e(this[0]).is("form"))return this.validate().form();var t=!0,n=e(this[0].form).validate();return this.each(function(){t&=n.element(this)}),t},removeAttrs:function(t){var n={},r=this;return e.each(t.split(/\s/),function(e,t){n[t]=r.attr(t),r.removeAttr(t)}),n},rules:function(t,n){var r=this[0];if(t){var i=e.data(r.form,"validator").settings,s=i.rules,o=e.validator.staticRules(r);switch(t){case"add":e.extend(o,e.validator.normalizeRule(n)),s[r.name]=o,n.messages&&(i.messages[r.name]=e.extend(i.messages[r.name],n.messages));break;case"remove":if(!n)return delete s[r.name],o;var u={};return e.each(n.split(/\s/),function(e,t){u[t]=o[t],delete o[t]}),u}}var a=e.validator.normalizeRules(e.extend({},e.validator.classRules(r),e.validator.attributeRules(r),e.validator.dataRules(r),e.validator.staticRules(r)),r);if(a.required){var f=a.required;delete a.required,a=e.extend({required:f},a)}return a}}),e.extend(e.expr[":"],{blank:function(t){return!e.trim(""+t.value)},filled:function(t){return!!e.trim(""+t.value)},unchecked:function(e){return!e.checked}}),e.validator=function(t,n){this.settings=e.extend(!0,{},e.validator.defaults,t),this.currentForm=n,this.init()},e.validator.format=function(t,n){return arguments.length===1?function(){var n=e.makeArray(arguments);return n.unshift(t),e.validator.format.apply(this,n)}:(arguments.length>2&&n.constructor!==Array&&(n=e.makeArray(arguments).slice(1)),n.constructor!==Array&&(n=[n]),e.each(n,function(e,n){t=t.replace(new RegExp("\\{"+e+"\\}","g"),function(){return n})}),t)},e.extend(e.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",validClass:"valid",errorElement:"label",focusInvalid:!0,errorContainer:e([]),errorLabelContainer:e([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(e,t){this.lastActive=e,this.settings.focusCleanup&&!this.blockFocusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,e,this.settings.errorClass,this.settings.validClass),this.addWrapper(this.errorsFor(e)).hide())},onfocusout:function(e,t){!this.checkable(e)&&(e.name in this.submitted||!this.optional(e))&&this.element(e)},onkeyup:function(e,t){if(t.which===9&&this.elementValue(e)==="")return;(e.name in this.submitted||e===this.lastElement)&&this.element(e)},onclick:function(e,t){e.name in this.submitted?this.element(e):e.parentNode.name in this.submitted&&this.element(e.parentNode)},highlight:function(t,n,r){t.type==="radio"?this.findByName(t.name).addClass(n).removeClass(r):e(t).addClass(n).removeClass(r)},unhighlight:function(t,n,r){t.type==="radio"?this.findByName(t.name).removeClass(n).addClass(r):e(t).removeClass(n).addClass(r)}},setDefaults:function(t){e.extend(e.validator.defaults,t)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date (ISO).",number:"Please enter a valid number.",digits:"Please enter only digits.",creditcard:"Please enter a valid credit card number.",equalTo:"Please enter the same value again.",maxlength:e.validator.format("Please enter no more than {0} characters."),minlength:e.validator.format("Please enter at least {0} characters."),rangelength:e.validator.format("Please enter a value between {0} and {1} characters long."),range:e.validator.format("Please enter a value between {0} and {1}."),max:e.validator.format("Please enter a value less than or equal to {0}."),min:e.validator.format("Please enter a value greater than or equal to {0}.")},autoCreateRanges:!1,prototype:{init:function(){function r(t){var n=e.data(this[0].form,"validator"),r="on"+t.type.replace(/^validate/,"");n.settings[r]&&n.settings[r].call(n,this[0],t)}this.labelContainer=e(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||e(this.currentForm),this.containers=e(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var t=this.groups={};e.each(this.settings.groups,function(n,r){typeof r=="string"&&(r=r.split(/\s/)),e.each(r,function(e,r){t[r]=n})});var n=this.settings.rules;e.each(n,function(t,r){n[t]=e.validator.normalizeRule(r)}),e(this.currentForm).validateDelegate(":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'] ,[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'] ","focusin focusout keyup",r).validateDelegate("[type='radio'], [type='checkbox'], select, option","click",r),this.settings.invalidHandler&&e(this.currentForm).bind("invalid-form.validate",this.settings.invalidHandler)},form:function(){return this.checkForm(),e.extend(this.submitted,this.errorMap),this.invalid=e.extend({},this.errorMap),this.valid()||e(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var e=0,t=this.currentElements=this.elements();t[e];e++)this.check(t[e]);return this.valid()},element:function(t){t=this.validationTargetFor(this.clean(t)),this.lastElement=t,this.prepareElement(t),this.currentElements=e(t);var n=this.check(t)!==!1;return n?delete this.invalid[t.name]:this.invalid[t.name]=!0,this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),n},showErrors:function(t){if(t){e.extend(this.errorMap,t),this.errorList=[];for(var n in t)this.errorList.push({message:t[n],element:this.findByName(n)[0]});this.successList=e.grep(this.successList,function(e){return!(e.name in t)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){e.fn.resetForm&&e(this.currentForm).resetForm(),this.submitted={},this.lastElement=null,this.prepareForm(),this.hideErrors(),this.elements().removeClass(this.settings.errorClass).removeData("previousValue")},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(e){var t=0;for(var n in e)t++;return t},hideErrors:function(){this.addWrapper(this.toHide).hide()},valid:function(){return this.size()===0},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{e(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(t){}},findLastActive:function(){var t=this.lastActive;return t&&e.grep(this.errorList,function(e){return e.element.name===t.name}).length===1&&t},elements:function(){var t=this,n={};return e(this.currentForm).find("input, select, textarea").not(":submit, :reset, :image, [disabled]").not(this.settings.ignore).filter(function(){return!this.name&&t.settings.debug&&window.console&&console.error("%o has no name assigned",this),this.name in n||!t.objectLength(e(this).rules())?!1:(n[this.name]=!0,!0)})},clean:function(t){return e(t)[0]},errors:function(){var t=this.settings.errorClass.replace(" ",".");return e(this.settings.errorElement+"."+t,this.errorContext)},reset:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=e([]),this.toHide=e([]),this.currentElements=e([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(e){this.reset(),this.toHide=this.errorsFor(e)},elementValue:function(t){var n=e(t).attr("type"),r=e(t).val();return n==="radio"||n==="checkbox"?e("input[name='"+e(t).attr("name")+"']:checked").val():typeof r=="string"?r.replace(/\r/g,""):r},check:function(t){t=this.validationTargetFor(this.clean(t));var n=e(t).rules(),r=!1,i=this.elementValue(t),s;for(var o in n){var u={method:o,parameters:n[o]};try{s=e.validator.methods[o].call(this,i,t,u.parameters);if(s==="dependency-mismatch"){r=!0;continue}r=!1;if(s==="pending"){this.toHide=this.toHide.not(this.errorsFor(t));return}if(!s)return this.formatAndAdd(t,u),!1}catch(a){throw this.settings.debug&&window.console&&console.log("Exception occured when checking element "+t.id+", check the '"+u.method+"' method.",a),a}}if(r)return;return this.objectLength(n)&&this.successList.push(t),!0},customDataMessage:function(t,n){return e(t).data("msg-"+n.toLowerCase())||t.attributes&&e(t).attr("data-msg-"+n.toLowerCase())},customMessage:function(e,t){var n=this.settings.messages[e];return n&&(n.constructor===String?n:n[t])},findDefined:function(){for(var e=0;e<arguments.length;e++)if(arguments[e]!==undefined)return arguments[e];return undefined},defaultMessage:function(t,n){return this.findDefined(this.customMessage(t.name,n),this.customDataMessage(t,n),!this.settings.ignoreTitle&&t.title||undefined,e.validator.messages[n],"<strong>Warning: No message defined for "+t.name+"</strong>")},formatAndAdd:function(t,n){var r=this.defaultMessage(t,n.method),i=/\$?\{(\d+)\}/g;typeof r=="function"?r=r.call(this,n.parameters,t):i.test(r)&&(r=e.validator.format(r.replace(i,"{$1}"),n.parameters)),this.errorList.push({message:r,element:t}),this.errorMap[t.name]=r,this.submitted[t.name]=r},addWrapper:function(e){return this.settings.wrapper&&(e=e.add(e.parent(this.settings.wrapper))),e},defaultShowErrors:function(){var e,t;for(e=0;this.errorList[e];e++){var n=this.errorList[e];this.settings.highlight&&this.settings.highlight.call(this,n.element,this.settings.errorClass,this.settings.validClass),this.showLabel(n.element,n.message)}this.errorList.length&&(this.toShow=this.toShow.add(this.containers));if(this.settings.success)for(e=0;this.successList[e];e++)this.showLabel(this.successList[e]);if(this.settings.unhighlight)for(e=0,t=this.validElements();t[e];e++)this.settings.unhighlight.call(this,t[e],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return e(this.errorList).map(function(){return this.element})},showLabel:function(t,n){var r=this.errorsFor(t);r.length?(r.removeClass(this.settings.validClass).addClass(this.settings.errorClass),r.html(n)):(r=e("<"+this.settings.errorElement+">").attr("for",this.idOrName(t)).addClass(this.settings.errorClass).html(n||""),this.settings.wrapper&&(r=r.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.append(r).length||(this.settings.errorPlacement?this.settings.errorPlacement(r,e(t)):r.insertAfter(t))),!n&&this.settings.success&&(r.text(""),typeof this.settings.success=="string"?r.addClass(this.settings.success):this.settings.success(r,t)),this.toShow=this.toShow.add(r)},errorsFor:function(t){var n=this.idOrName(t);return this.errors().filter(function(){return e(this).attr("for")===n})},idOrName:function(e){return this.groups[e.name]||(this.checkable(e)?e.name:e.id||e.name)},validationTargetFor:function(e){return this.checkable(e)&&(e=this.findByName(e.name).not(this.settings.ignore)[0]),e},checkable:function(e){return/radio|checkbox/i.test(e.type)},findByName:function(t){return e(this.currentForm).find("[name='"+t+"']")},getLength:function(t,n){switch(n.nodeName.toLowerCase()){case"select":return e("option:selected",n).length;case"input":if(this.checkable(n))return this.findByName(n.name).filter(":checked").length}return t.length},depend:function(e,t){return this.dependTypes[typeof e]?this.dependTypes[typeof e](e,t):!0},dependTypes:{"boolean":function(e,t){return e},string:function(t,n){return!!e(t,n.form).length},"function":function(e,t){return e(t)}},optional:function(t){var n=this.elementValue(t);return!e.validator.methods.required.call(this,n,t)&&"dependency-mismatch"},startRequest:function(e){this.pending[e.name]||(this.pendingRequest++,this.pending[e.name]=!0)},stopRequest:function(t,n){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[t.name],n&&this.pendingRequest===0&&this.formSubmitted&&this.form()?(e(this.currentForm).submit(),this.formSubmitted=!1):!n&&this.pendingRequest===0&&this.formSubmitted&&(e(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(t){return e.data(t,"previousValue")||e.data(t,"previousValue",{old:null,valid:!0,message:this.defaultMessage(t,"remote")})}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(t,n){t.constructor===String?this.classRuleSettings[t]=n:e.extend(this.classRuleSettings,t)},classRules:function(t){var n={},r=e(t).attr("class");return r&&e.each(r.split(" "),function(){this in e.validator.classRuleSettings&&e.extend(n,e.validator.classRuleSettings[this])}),n},attributeRules:function(t){var n={},r=e(t);for(var i in e.validator.methods){var s;i==="required"?(s=r.get(0).getAttribute(i),s===""&&(s=!0),s=!!s):s=r.attr(i),s?n[i]=s:r[0].getAttribute("type")===i&&(n[i]=!0)}return n.maxlength&&/-1|2147483647|524288/.test(n.maxlength)&&delete n.maxlength,n},dataRules:function(t){var n,r,i={},s=e(t);for(n in e.validator.methods)r=s.data("rule-"+n.toLowerCase()),r!==undefined&&(i[n]=r);return i},staticRules:function(t){var n={},r=e.data(t.form,"validator");return r.settings.rules&&(n=e.validator.normalizeRule(r.settings.rules[t.name])||{}),n},normalizeRules:function(t,n){return e.each(t,function(r,i){if(i===!1){delete t[r];return}if(i.param||i.depends){var s=!0;switch(typeof i.depends){case"string":s=!!e(i.depends,n.form).length;break;case"function":s=i.depends.call(n,n)}s?t[r]=i.param!==undefined?i.param:!0:delete t[r]}}),e.each(t,function(r,i){t[r]=e.isFunction(i)?i(n):i}),e.each(["minlength","maxlength"],function(){t[this]&&(t[this]=Number(t[this]))}),e.each(["rangelength"],function(){var n;t[this]&&(e.isArray(t[this])?t[this]=[Number(t[this][0]),Number(t[this][1])]:typeof t[this]=="string"&&(n=t[this].split(/[\s,]+/),t[this]=[Number(n[0]),Number(n[1])]))}),e.validator.autoCreateRanges&&(t.min&&t.max&&(t.range=[t.min,t.max],delete t.min,delete t.max),t.minlength&&t.maxlength&&(t.rangelength=[t.minlength,t.maxlength],delete t.minlength,delete t.maxlength)),t},normalizeRule:function(t){if(typeof t=="string"){var n={};e.each(t.split(/\s/),function(){n[this]=!0}),t=n}return t},addMethod:function(t,n,r){e.validator.methods[t]=n,e.validator.messages[t]=r!==undefined?r:e.validator.messages[t],n.length<3&&e.validator.addClassRules(t,e.validator.normalizeRule(t))},methods:{required:function(t,n,r){if(!this.depend(r,n))return"dependency-mismatch";if(n.nodeName.toLowerCase()==="select"){var i=e(n).val();return i&&i.length>0}return this.checkable(n)?this.getLength(t,n)>0:e.trim(t).length>0},remote:function(t,n,r){if(this.optional(n))return"dependency-mismatch";var i=this.previousValue(n);this.settings.messages[n.name]||(this.settings.messages[n.name]={}),i.originalMessage=this.settings.messages[n.name].remote,this.settings.messages[n.name].remote=i.message,r=typeof r=="string"&&{url:r}||r;if(i.old===t)return i.valid;i.old=t;var s=this;this.startRequest(n);var o={};return o[n.name]=t,e.ajax(e.extend(!0,{url:r,mode:"abort",port:"validate"+n.name,dataType:"json",data:o,success:function(r){s.settings.messages[n.name].remote=i.originalMessage;var o=r===!0||r==="true";if(o){var u=s.formSubmitted;s.prepareElement(n),s.formSubmitted=u,s.successList.push(n),delete s.invalid[n.name],s.showErrors()}else{var a={},f=r||s.defaultMessage(n,"remote");a[n.name]=i.message=e.isFunction(f)?f(t):f,s.invalid[n.name]=!0,s.showErrors(a)}i.valid=o,s.stopRequest(n,o)}},r)),"pending"},minlength:function(t,n,r){var i=e.isArray(t)?t.length:this.getLength(e.trim(t),n);return this.optional(n)||i>=r},maxlength:function(t,n,r){var i=e.isArray(t)?t.length:this.getLength(e.trim(t),n);return this.optional(n)||i<=r},rangelength:function(t,n,r){var i=e.isArray(t)?t.length:this.getLength(e.trim(t),n);return this.optional(n)||i>=r[0]&&i<=r[1]},min:function(e,t,n){return this.optional(t)||e>=n},max:function(e,t,n){return this.optional(t)||e<=n},range:function(e,t,n){return this.optional(t)||e>=n[0]&&e<=n[1]},email:function(e,t){return this.optional(t)||/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(e)},url:function(e,t){return this.optional(t)||/^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(e)},date:function(e,t){return this.optional(t)||!/Invalid|NaN/.test((new Date(e)).toString())},dateISO:function(e,t){return this.optional(t)||/^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(e)},number:function(e,t){return this.optional(t)||/^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(e)},digits:function(e,t){return this.optional(t)||/^\d+$/.test(e)},creditcard:function(e,t){if(this.optional(t))return"dependency-mismatch";if(/[^0-9 \-]+/.test(e))return!1;var n=0,r=0,i=!1;e=e.replace(/\D/g,"");for(var s=e.length-1;s>=0;s--){var o=e.charAt(s);r=parseInt(o,10),i&&(r*=2)>9&&(r-=9),n+=r,i=!i}return n%10===0},equalTo:function(t,n,r){var i=e(r);return this.settings.onfocusout&&i.unbind(".validate-equalTo").bind("blur.validate-equalTo",function(){e(n).valid()}),t===i.val()}}}),e.format=e.validator.format})(jQuery),function(e){var t={};if(e.ajaxPrefilter)e.ajaxPrefilter(function(e,n,r){var i=e.port;e.mode==="abort"&&(t[i]&&t[i].abort(),t[i]=r)});else{var n=e.ajax;e.ajax=function(r){var i=("mode"in r?r:e.ajaxSettings).mode,s=("port"in r?r:e.ajaxSettings).port;return i==="abort"?(t[s]&&t[s].abort(),t[s]=n.apply(this,arguments)):n.apply(this,arguments)}}}(jQuery),function(e){e.extend(e.fn,{validateDelegate:function(t,n,r){return this.bind(n,function(n){var i=e(n.target);if(i.is(t))return r.apply(i,arguments)})}})}(jQuery);
readme.txt CHANGED
@@ -6,28 +6,28 @@ License URI: http://www.gnu.org/licenses/gpl.html
6
  Tags: simple, contact, form, contact button, contact form, contact form plugin, contacts, contacts form plugin, contact me, feedback form, bootstrap, twitter, google, reCAPTCHA, ajax, secure
7
  Requires at least: 3.3
8
  Tested up to: 3.5
9
- Stable tag: 4.1.2
10
 
11
- A clean and simple contact form with Google reCAPTCHA and Twitter Bootstrap markup.
12
 
13
  == Description ==
14
  A clean and simple contact form with Google reCAPTCHA and Twitter Bootstrap markup.
15
 
16
  * **Clean**: all user inputs are stripped in order to avoid cross-site scripting (XSS) vulnerabilities.
17
 
18
- * **Simple**: Ajax enabled validation for immediate response and guidance for your users (can be switched off).
19
 
20
  * **Stylish**: Use the included stylesheet or switch it off and use your own for seamless integration with your website.
21
  Uses **Twitter Bootstrap** classes.
22
 
23
  This is a straightforward contact form for your WordPress site. There is very minimal set-up
24
- required. Simply install, activate, and then place the short code [cscf-contact-form] on your web page.
25
 
26
  A standard set of input boxes are provided, these include Email Address, Name, Message and a nice big ‘Send Message’ button.
27
 
28
  When your user has completed the form an email will be sent to you containing your user’s message. To reply simply click the ‘reply’ button on your email client. The email address used is the one you have set up in WordPress under ‘Settings’ -> ‘General’, so do check this is correct.
29
 
30
- To help prevent spam, this plugin allows you to add a reCAPTCHA’. This adds a picture of a couple of words to the bottom of the form. Your user must correctly type the words before the form can be submitted, and in so doing, prove that they are human.
31
 
32
  = Why Choose This Plugin? =
33
  Granted there are many plugins of this type in existence already. Why use this one in-particular?
@@ -38,7 +38,7 @@ Here’s why:
38
 
39
  * **Safe**. All input entered by your user is stripped back to minimise as far as possible the likelihood of any malicious user attempting to inject a script into your website. You can turn on reCAPTCHA to avoid your form being abused by bots.
40
 
41
- * **Ajax enabled**. You have the option to turn on ajax (client-side) validation which gives your users immediate guidance when completing the form without having to wait for the page to refresh.
42
 
43
  * The form can **integrate seamlessly into your website**. Turn off the plugin’s default css style sheet so that your theme’s style sheet can be used instead.
44
 
@@ -48,7 +48,7 @@ Here’s why:
48
 
49
  * Works with the **latest version of WordPress**.
50
 
51
- * Written by an **experienced PHP programmer** and rigorously tested as standard practice.
52
 
53
  Hopefully this plugin will fulfil all your needs, if not [get in-touch](http://www.megnicholas.co.uk/contact-me "Get In Touch") and I will customise to your exact requirements.
54
 
@@ -67,18 +67,18 @@ To place the contact form on your page use the shortcode [cscf-contact-form]
67
  [More information on how to use the plugin.](http://www.megnicholas.co.uk/wordpress-plugins/clean-and-simple-contact-form/ "More Information")
68
 
69
  == How to Use ==
70
- Unless you want to change messages or add reCAPTCHA to your contact form then this plugin will work without any additional setup.
71
 
72
  Important: Check that you have an email address set-up in your WordPress ‘Settings’->’General’ page. This is the address that the plugin will use to send the contents of the contact form.
73
 
74
  To add the contact form to your WordPress website simply place the shortcode [cscf-contact-form] on the post or page that you wish the form to appear on.
75
 
76
- **If you have Jetpack plugin installed disable the contact form otherwise the wrong form will display.**
77
 
78
- Goto [other notes](http://wordpress.org/plugins/clean-and-simple-contact-form-by-meg-nicholas/other_notes/ "How To Use") for information on how to use.
79
 
80
  == Additional Settings ==
81
- This plugin will work as is without any additional setup. You have the option to change the default messages that are displayed to your user and to add reCAPTCHA capabilities.
82
 
83
  Go to the settings screen for the contact form plugin.
84
 
@@ -88,13 +88,13 @@ Here is a list of things that you can change
88
 
89
  * **Message**: The message displayed to the user at the top of the contact form.
90
 
91
- * **Message** Sent Heading: The message heading or title displayed to the user after the message has been sent.
92
 
93
  * **Message Sent Content**: The message content or body displayed to the user after the message has been sent.
94
 
95
  * **Use this plugin’s default stylesheet**: The plugin comes with a default style sheet to make the form look nice for your user. Untick this if you want to use your theme’s stylesheet instead. The default stylesheet will simply not be linked in.
96
 
97
- * **Use client side validation (Ajax)**: When ticked the contact form will be validated on the client giving your user instant feedback if they have filled the form in incorrectly. If you wish the form to be validated only on the server then untick this option.
98
 
99
  * **Use reCAPTCHA**: Tick this option if you wish your form to have a reCAPTCHA box. ReCAPTCHA helps to avoid spam bots using your form by checking that the form filler is actually a real person. To use reCAPTCHA you will need to get a some special keys from google https://www.google.com/recaptcha/admin/create. Once you have your keys enter them into the Public key and Private key boxes
100
 
@@ -124,6 +124,12 @@ I am a freelance WordPress Developer.
124
  [Hire me for all your Wordpress needs](http://www.megnicholas.co.uk "Hire Me").
125
 
126
  == Frequently Asked Questions ==
 
 
 
 
 
 
127
  = Why is a different contact form displayed? =
128
 
129
  You may have a conflict with another plugin. Either deactivate the other contact form plugin, if you don't need it, or use
@@ -131,11 +137,17 @@ this alternative short code on your webpage - `[cscf-contact-form]`.
131
  This problem often occurs when Jetpack plugin is installed.
132
 
133
  = How do I display the contact form on my page/post? =
 
134
  To put the contact form on your page, add the text:
135
  `[cscf-contact-form]`
136
 
137
  The contact form will appear when you view the page.
138
 
 
 
 
 
 
139
  = Can I have this plugin in my own language? =
140
 
141
  Yes, I am currently building up translation files for this plugin. If your language is not yet available you are very welcome to translate it.
@@ -143,16 +155,16 @@ If you are not sure how to go about doing this [get in touch](http://www.megnich
143
 
144
  = How do I change the text box sizes? =
145
 
146
- Currently it is not possible to do this.
147
-
148
- = I get a message to say that the message could not be sent =
149
-
150
- If you get this message then you have a general problem with email on your server. This plugin uses Wordpress's send mail function.
151
- So a problem sending mail from this plugin indicates that Wordpress as a whole cannot send email.
152
- Contact your web host provider for help, or use an SMTP plugin to use a third party email service.
153
-
154
 
155
  == Changelog ==
 
 
 
 
 
 
 
156
  = 4.1.2 =
157
  * Added some FAQs
158
  * Added alternative shortcode [cscf-contact-form] for use when conflicts could occur.
@@ -164,6 +176,7 @@ Contact your web host provider for help, or use an SMTP plugin to use a third pa
164
  * Corrected some html seen as invalid by http://validator.w3.org/
165
  * removed '<?=' and replaced with '<?php echo' in cscf_settings, thanks go to andrewbacon
166
  * Added notice to setting screen when JetPack's contact form is active
 
167
  = 4.1.1 =
168
  * Fixed potential conflicts with themes that use bootstrap
169
  * Enabled internationalisation, this plugin will now work with multiple languages
@@ -185,6 +198,8 @@ Contact your web host provider for help, or use an SMTP plugin to use a third pa
185
 
186
 
187
  == Upgrade Notice ==
 
 
188
  = 4.1.2 =
189
  Alternative shortcode, recaptcha internationalisation, Jetpack conflict warning notice
190
  = 4.1.1 =
6
  Tags: simple, contact, form, contact button, contact form, contact form plugin, contacts, contacts form plugin, contact me, feedback form, bootstrap, twitter, google, reCAPTCHA, ajax, secure
7
  Requires at least: 3.3
8
  Tested up to: 3.5
9
+ Stable tag: 4.1.3
10
 
11
+ A clean and simple AJAX contact form with Google reCAPTCHA and Twitter Bootstrap markup.
12
 
13
  == Description ==
14
  A clean and simple contact form with Google reCAPTCHA and Twitter Bootstrap markup.
15
 
16
  * **Clean**: all user inputs are stripped in order to avoid cross-site scripting (XSS) vulnerabilities.
17
 
18
+ * **Simple**: AJAX enabled validation and submission for immediate response and guidance for your users (can be switched off).
19
 
20
  * **Stylish**: Use the included stylesheet or switch it off and use your own for seamless integration with your website.
21
  Uses **Twitter Bootstrap** classes.
22
 
23
  This is a straightforward contact form for your WordPress site. There is very minimal set-up
24
+ required. Simply install, activate, and then place the short code **[cscf-contact-form]** on your web page.
25
 
26
  A standard set of input boxes are provided, these include Email Address, Name, Message and a nice big ‘Send Message’ button.
27
 
28
  When your user has completed the form an email will be sent to you containing your user’s message. To reply simply click the ‘reply’ button on your email client. The email address used is the one you have set up in WordPress under ‘Settings’ -> ‘General’, so do check this is correct.
29
 
30
+ To help prevent spam, this plugin allows you to add a ‘**reCAPTCHA**’. This adds a picture of a couple of words to the bottom of the form. Your user must correctly type the words before the form can be submitted, and in so doing, prove that they are human.
31
 
32
  = Why Choose This Plugin? =
33
  Granted there are many plugins of this type in existence already. Why use this one in-particular?
38
 
39
  * **Safe**. All input entered by your user is stripped back to minimise as far as possible the likelihood of any malicious user attempting to inject a script into your website. You can turn on reCAPTCHA to avoid your form being abused by bots.
40
 
41
+ * **Ajax enabled**. You have the option to turn on AJAX (client-side) validation and submission which gives your users an immediate response when completing the form without having to wait for the page to refresh.
42
 
43
  * The form can **integrate seamlessly into your website**. Turn off the plugin’s default css style sheet so that your theme’s style sheet can be used instead.
44
 
48
 
49
  * Works with the **latest version of WordPress**.
50
 
51
+ * Written by an **experienced PHP programmer**, the code is rock solid, safe, and rigorously tested as standard practice.
52
 
53
  Hopefully this plugin will fulfil all your needs, if not [get in-touch](http://www.megnicholas.co.uk/contact-me "Get In Touch") and I will customise to your exact requirements.
54
 
67
  [More information on how to use the plugin.](http://www.megnicholas.co.uk/wordpress-plugins/clean-and-simple-contact-form/ "More Information")
68
 
69
  == How to Use ==
70
+ Unless you want to change messages or add reCAPTCHA to your contact form then this plugin will work out of the box without any additional setup.
71
 
72
  Important: Check that you have an email address set-up in your WordPress ‘Settings’->’General’ page. This is the address that the plugin will use to send the contents of the contact form.
73
 
74
  To add the contact form to your WordPress website simply place the shortcode [cscf-contact-form] on the post or page that you wish the form to appear on.
75
 
76
+ **If you have Jetpack plugin installed disable the contact form otherwise the wrong form might display.**
77
 
78
+ [More information on how to use the plugin.](http://www.megnicholas.co.uk/wordpress-plugins/clean-and-simple-contact-form/ "More Information")
79
 
80
  == Additional Settings ==
81
+ This plugin will work out of the box without any additional setup. You have the option to change the default messages that are displayed to your user and to add reCAPTCHA capabilities.
82
 
83
  Go to the settings screen for the contact form plugin.
84
 
88
 
89
  * **Message**: The message displayed to the user at the top of the contact form.
90
 
91
+ * **Message Sent Heading**: The message heading or title displayed to the user after the message has been sent.
92
 
93
  * **Message Sent Content**: The message content or body displayed to the user after the message has been sent.
94
 
95
  * **Use this plugin’s default stylesheet**: The plugin comes with a default style sheet to make the form look nice for your user. Untick this if you want to use your theme’s stylesheet instead. The default stylesheet will simply not be linked in.
96
 
97
+ * **Use client side validation (Ajax)**: When ticked the contact form will be validated and submitted on the client giving your user instant feedback if they have filled the form in incorrectly. If you wish the form to be validated and submitted only to the server then untick this option.
98
 
99
  * **Use reCAPTCHA**: Tick this option if you wish your form to have a reCAPTCHA box. ReCAPTCHA helps to avoid spam bots using your form by checking that the form filler is actually a real person. To use reCAPTCHA you will need to get a some special keys from google https://www.google.com/recaptcha/admin/create. Once you have your keys enter them into the Public key and Private key boxes
100
 
124
  [Hire me for all your Wordpress needs](http://www.megnicholas.co.uk "Hire Me").
125
 
126
  == Frequently Asked Questions ==
127
+ = I get a message to say that the message could not be sent =
128
+
129
+ If you get this message then you have a general problem with email on your server. This plugin uses Wordpress's send mail function.
130
+ So a problem sending mail from this plugin indicates that Wordpress as a whole cannot send email.
131
+ Contact your web host provider for help, or use an SMTP plugin to use a third party email service.
132
+
133
  = Why is a different contact form displayed? =
134
 
135
  You may have a conflict with another plugin. Either deactivate the other contact form plugin, if you don't need it, or use
137
  This problem often occurs when Jetpack plugin is installed.
138
 
139
  = How do I display the contact form on my page/post? =
140
+
141
  To put the contact form on your page, add the text:
142
  `[cscf-contact-form]`
143
 
144
  The contact form will appear when you view the page.
145
 
146
+ = When I use the style sheet that comes with the plugin my theme is effected =
147
+
148
+ It is impossible to test this plugin with all themes. Styling incompatibilities can occur. In this case, switch off the default stylesheet on the settings
149
+ screen so you can add your own styles to your theme's stylesheet.
150
+
151
  = Can I have this plugin in my own language? =
152
 
153
  Yes, I am currently building up translation files for this plugin. If your language is not yet available you are very welcome to translate it.
155
 
156
  = How do I change the text box sizes? =
157
 
158
+ To do this you will need to add some css changes to your theme.
 
 
 
 
 
 
 
159
 
160
  == Changelog ==
161
+ = 4.1.3 =
162
+ * Fixed escaped characters.
163
+ * Added more translation files
164
+ * Forms now submit via ajax.
165
+ * Upgraded jquery-validate.js to 1.11. Removed jquery metadata plugin, form validation is now built with data attributes instead of json in classes.
166
+ * Improved view html.
167
+ * Added Dutch and Armenian translations
168
  = 4.1.2 =
169
  * Added some FAQs
170
  * Added alternative shortcode [cscf-contact-form] for use when conflicts could occur.
176
  * Corrected some html seen as invalid by http://validator.w3.org/
177
  * removed '<?=' and replaced with '<?php echo' in cscf_settings, thanks go to andrewbacon
178
  * Added notice to setting screen when JetPack's contact form is active
179
+ * Fixed problem where 'Please enter a valid email address' was not translating in the 'confirm email address' input
180
  = 4.1.1 =
181
  * Fixed potential conflicts with themes that use bootstrap
182
  * Enabled internationalisation, this plugin will now work with multiple languages
198
 
199
 
200
  == Upgrade Notice ==
201
+ = 4.1.3 =
202
+ Form now submits via ajax!
203
  = 4.1.2 =
204
  Alternative shortcode, recaptcha internationalisation, Jetpack conflict warning notice
205
  = 4.1.1 =
shortcodes/contact-form.php CHANGED
@@ -6,18 +6,11 @@ function cscf_ContactForm()
6
  {
7
 
8
  $contact = new cscf_Contact;
9
- $filters = new cscf_Filters;
10
 
11
  if ($contact->IsValid())
12
  {
13
- $filters->fromEmail=$contact->Email;
14
- $filters->fromName=$contact->Name;
15
-
16
- //add filters
17
- $filters->add('wp_mail_from');
18
- $filters->add('wp_mail_from_name');
19
-
20
- if (wp_mail(cscf_PluginSettings::RecipientEmail() , cscf_PluginSettings::Subject(), $contact->Message))
21
  {
22
  $view = new CSCF_View('message-sent');
23
  $view->Set('heading',cscf_PluginSettings::SentMessageHeading());
@@ -28,37 +21,34 @@ function cscf_ContactForm()
28
  $view = new CSCF_View('message-not-sent');
29
  }
30
 
31
- //remove filters (play nice)
32
- $filters->remove('wp_mail_from');
33
- $filters->remove('wp_mail_from_name');
34
-
35
  return $view->Render();
36
  }
37
 
38
  //here we need some jquery scripts and styles, so load them here
39
  if ( cscf_PluginSettings::UseClientValidation() == true) {
40
  wp_enqueue_script('jquery-validate');
41
- wp_enqueue_script('jquery-meta');
42
- wp_enqueue_script('jquery-validate-contact-form');
43
  }
44
 
45
  //only load the stylesheet if required
46
  if ( cscf_PluginSettings::LoadStyleSheet() == true)
47
  wp_enqueue_style('cscf-bootstrap');
48
 
49
- //set-up the view
50
- if ( $contact->RecaptchaPublicKey<>'' && $contact->RecaptchaPrivateKey<>'')
51
- $view = new CSCF_View('contact-form-with-recaptcha');
52
- else
53
- $view = new CSCF_View('contact-form');
54
-
55
  $view->Set('contact',$contact);
56
  $view->Set('message',cscf_PluginSettings::Message());
57
  $view->Set('version', CSCF_VERSION_NUM);
 
 
 
 
58
 
59
  return $view->Render();
60
 
61
  }
62
 
63
 
64
-
6
  {
7
 
8
  $contact = new cscf_Contact;
 
9
 
10
  if ($contact->IsValid())
11
  {
12
+ if ( $contact->SendMail() )
13
+
 
 
 
 
 
 
14
  {
15
  $view = new CSCF_View('message-sent');
16
  $view->Set('heading',cscf_PluginSettings::SentMessageHeading());
21
  $view = new CSCF_View('message-not-sent');
22
  }
23
 
 
 
 
 
24
  return $view->Render();
25
  }
26
 
27
  //here we need some jquery scripts and styles, so load them here
28
  if ( cscf_PluginSettings::UseClientValidation() == true) {
29
  wp_enqueue_script('jquery-validate');
30
+ wp_enqueue_script('cscf-validate');
 
31
  }
32
 
33
  //only load the stylesheet if required
34
  if ( cscf_PluginSettings::LoadStyleSheet() == true)
35
  wp_enqueue_style('cscf-bootstrap');
36
 
37
+ $messageSentView = new CSCF_View('message-sent');
38
+ $messageSentView->Set('heading',cscf_PluginSettings::SentMessageHeading());
39
+ $messageSentView->Set('message',cscf_PluginSettings::SentMessageBody());
40
+
41
+ $view = new CSCF_View('contact-form');
 
42
  $view->Set('contact',$contact);
43
  $view->Set('message',cscf_PluginSettings::Message());
44
  $view->Set('version', CSCF_VERSION_NUM);
45
+
46
+
47
+ $view->Set('messageSentView',$messageSentView);
48
+ $view->Set('messageNotSentView',new CSCF_View('message-not-sent'));
49
 
50
  return $view->Render();
51
 
52
  }
53
 
54
 
 
views/contact-form-with-recaptcha.view.php DELETED
@@ -1,75 +0,0 @@
1
- <script type="text/javascript">
2
- var RecaptchaOptions = {
3
- theme : '<?php echo cscf_PluginSettings::Theme(); ?>'
4
- };
5
- </script>
6
-
7
- <p><?php echo $message; ?></p>
8
-
9
- <form id="frmCSCF" name="frmCSCF" method="post">
10
-
11
- <?php wp_nonce_field('cscf_contact','cscf_nonce'); ?>
12
-
13
- <!-- Clean and Simple Contact Form by megnicholas. Version <?php echo $version; ?> -->
14
-
15
- <div class="control-group">
16
- <div class="controls">
17
- <p class="text-error"><?php if (isset($contact->Errors['recaptcha'])) echo $contact->Errors['recaptcha']; ?></p>
18
- </div>
19
- </div>
20
-
21
-
22
- <!--email address -->
23
- <div class="control-group<?php
24
- if (isset($contact->Errors['email'])) echo ' error'; ?>">
25
- <label class="control-label" for="cscf_email"><?php _e('Email Address:','cleanandsimple');?></label>
26
- <div class="controls">
27
- <input class="input-xlarge {email:true, required:true, messages:{required:'<?php _e('Please give your email address.','cleanandsimple');?>',email:'<?php _e('Please enter a valid email address.','cleanandsimple');?>'}}" type="text" id="cscf_email" name="cscf[email]" value="<?php echo $contact->Email; ?>" placeholder="<?php _e('Your Email Address','cleanandsimple');?>">
28
- <span class="help-inline"><?php if (isset($contact->Errors['email'])) echo $contact->Errors['email']; ?></span>
29
- </div>
30
- </div>
31
-
32
- <!--confirm email address -->
33
- <div class="control-group<?php
34
- if (isset($contact->Errors['confirm-email'])) echo ' error'; ?>">
35
- <label class="control-label" for="cscf_confirm-email"><?php _e('Confirm Email Address:','cleanandsimple');?></label>
36
- <div class="controls">
37
- <input class="input-xlarge {email:true, required:true, equalTo:'#cscf_email', messages:{equalTo:'<?php _e('Please enter the same email address again.','cleanandsimple');?>',required:'<?php _e('Please enter the same email address again.','cleanandsimple');?>',email:'<?php _e('Please enter a valid email address.','cleanandsimple');?>'}}" type="text" id="cscf_confirm-email" name="cscf[confirm-email]" value="<?php echo $contact->ConfirmEmail; ?>" placeholder="<?php _e('Confirm Your Email Address','cleanandsimple');?>">
38
- <span class="help-inline"><?php if (isset($contact->Errors['confirm-email'])) echo $contact->Errors['confirm-email']; ?></span>
39
- </div>
40
- </div>
41
-
42
- <!-- name -->
43
- <div class="control-group<?php
44
- if (isset($contact->Errors['name'])) echo ' error'; ?>">
45
- <label class="control-label" for="cscf_name"><?php _e('Name:','cleanandsimple');?></label>
46
- <div class="controls">
47
- <input class="input-xlarge {required:true, messages:{required:'<?php _e('Please give your name.','cleanandsimple');?>'}}" type="text" id="cscf_name" name="cscf[name]" value="<?php echo $contact->Name; ?>" placeholder="<?php _e('Your Name','cleanandsimple');?>">
48
- <span class="help-inline"><?php if (isset($contact->Errors['name'])) echo $contact->Errors['name']; ?></span>
49
- </div>
50
- </div>
51
-
52
- <!-- message -->
53
- <div class="control-group<?php
54
- if (isset($contact->Errors['message'])) echo ' error'; ?>">
55
- <label class="control-label" for="cscf_message"><?php _e('Message:','cleanandsimple');?></label>
56
- <div class="controls">
57
- <textarea class="input-xlarge {required:true, messages:{required:'<?php _e('Please give a message.','cleanandsimple');?>'}}" id="cscf_message" name="cscf[message]" rows="10" placeholder="<?php _e('Your Message','cleanandsimple');?>"><?php echo $contact->Message; ?></textarea>
58
- <span class="help-inline"><?php if (isset($contact->Errors['message'])) echo $contact->Errors['message']; ?></span>
59
- </div>
60
- </div>
61
-
62
- <div class="control-group<?php
63
- if (isset($contact->Errors['recaptcha'])) echo ' error'; ?>">
64
- <div id="recaptcha_div" class="controls">
65
- <?php echo recaptcha_get_html($contact->RecaptchaPublicKey,null,isset($_SERVER['HTTPS'])); ?>
66
- <span class="help-inline"><?php if (isset($contact->Errors['recaptcha'])) echo $contact->Errors['recaptcha']; ?></span>
67
- </div>
68
- </div>
69
-
70
- <div class="control-group">
71
- <div class="controls">
72
- <button type="submit" class="btn"><?php _e('Send Message','cleanandsimple');?></button>
73
- </div>
74
- </div>
75
- </form>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
views/contact-form.view.php CHANGED
@@ -1,54 +1,106 @@
1
- <p><?php echo $message; ?></p>
2
-
3
- <form id="frmCSCF" name="frmCSCF" method="post">
4
-
5
- <?php wp_nonce_field('cscf_contact','cscf_nonce'); ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
- <!-- Clean and Simple Contact Form by megnicholas. Version <?php echo $version; ?> -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
- <!--email address -->
10
- <div class="control-group<?php
11
- if (isset($contact->Errors['email'])) echo ' error'; ?>">
12
- <label class="control-label" for="cscf_email"><?php _e('Email Address:','cleanandsimple');?></label>
13
- <div class="controls">
14
- <input class="input-xlarge {email:true, required:true, messages:{required:'<?php _e('Please give your email address.','cleanandsimple');?>',email:'<?php _e('Please enter a valid email address.','cleanandsimple');?>'}}" type="text" id="cscf_email" name="cscf[email]" value="<?php echo $contact->Email; ?>" placeholder="<?php _e('Your Email Address','cleanandsimple');?>">
15
- <span class="help-inline"><?php if (isset($contact->Errors['email'])) echo $contact->Errors['email']; ?></span>
16
- </div>
17
- </div>
 
 
 
 
 
 
 
 
18
 
19
- <!--confirm email address -->
20
- <div class="control-group<?php
21
- if (isset($contact->Errors['confirm-email'])) echo ' error'; ?>">
22
- <label class="control-label" for="cscf_confirm-email"><?php _e('Confirm Email Address:','cleanandsimple');?></label>
23
- <div class="controls">
24
- <input class="input-xlarge {email:true, required:true, equalTo:'#cscf_email', messages:{equalTo:'<?php _e('Please enter the same email address again.','cleanandsimple');?>',required:'<?php _e('Please enter the same email address again.','cleanandsimple');?>',email:'<?php _e('Please enter a valid email address.','cleanandsimple');?>'}}" type="text" id="cscf_confirm-email" name="cscf[confirm-email]" value="<?php echo $contact->ConfirmEmail; ?>" placeholder="<?php _e('Confirm Your Email Address','cleanandsimple');?>">
25
- <span class="help-inline"><?php if (isset($contact->Errors['confirm-email'])) echo $contact->Errors['confirm-email']; ?></span>
26
- </div>
27
- </div>
 
 
 
 
28
 
29
- <!-- name -->
30
- <div class="control-group<?php
31
- if (isset($contact->Errors['name'])) echo ' error'; ?>">
32
- <label class="control-label" for="cscf_name"><?php _e('Name:','cleanandsimple');?></label>
33
- <div class="controls">
34
- <input class="input-xlarge {required:true, messages:{required:'<?php _e('Please give your name.','cleanandsimple');?>'}}" type="text" id="cscf_name" name="cscf[name]" value="<?php echo $contact->Name; ?>" placeholder="<?php _e('Your Name','cleanandsimple');?>">
35
- <span class="help-inline"><?php if (isset($contact->Errors['name'])) echo $contact->Errors['name']; ?></span>
36
- </div>
37
- </div>
 
 
 
38
 
39
- <!-- message -->
40
- <div class="control-group<?php
41
- if (isset($contact->Errors['message'])) echo ' error'; ?>">
42
- <label class="control-label" for="cscf_message"><?php _e('Message:','cleanandsimple');?></label>
43
- <div class="controls">
44
- <textarea class="input-xlarge {required:true, messages:{required:'<?php _e('Please give a message.','cleanandsimple');?>'}}" id="cscf_message" name="cscf[message]" rows="10" placeholder="<?php _e('Your Message','cleanandsimple');?>"><?php echo $contact->Message; ?></textarea>
45
- <span class="help-inline"><?php if (isset($contact->Errors['message'])) echo $contact->Errors['message']; ?></span>
46
- </div>
47
- </div>
 
 
 
 
 
 
48
 
49
- <div class="control-group">
50
- <div class="controls">
51
- <button type="submit" class="btn"><?php _e('Send Message','cleanandsimple');?></button>
 
 
 
52
  </div>
53
- </div>
54
- </form>
1
+ <!--Clean and Simple Contact Form by Meg Nicholas Version <?php echo $version; ?>-->
2
+ <div id="cscf" class="cscfBlock">
3
+ <div class="cscfMessageSent" style="display:none;">
4
+ <?php echo $messageSentView->Render(); ?>
5
+ </div>
6
+ <div class="cscfMessageNotSent" style="display:none;">
7
+ <?php echo $messageNotSentView->Render(); ?>
8
+ </div>
9
+ <div class="cscfForm">
10
+ <p><?php echo $message; ?></p>
11
+ <form id="frmCSCF" name="frmCSCF" method="post">
12
+ <?php wp_nonce_field('cscf_contact','cscf_nonce'); ?>
13
+
14
+ <?php if (isset($contact->Errors['recaptcha'])) { ?>
15
+ <div class="control-group">
16
+ <div class="controls">
17
+ <p class="text-error"><?php echo $contact->Errors['recaptcha']; ?></p>
18
+ </div>
19
+ </div>
20
+ <?php } ?>
21
 
22
+ <!--email address -->
23
+ <div class="control-group<?php if (isset($contact->Errors['email'])) echo ' error'; ?>">
24
+ <label class="control-label" for="cscf_email"><?php _e('Email Address:','cleanandsimple');?></label>
25
+ <div class="controls">
26
+ <input class="input-xlarge"
27
+ data-rule-required="true"
28
+ data-rule-email="true"
29
+ data-msg-required="<?php _e('Please give your email address.','cleanandsimple');?>"
30
+ data-msg-email="<?php _e('Please enter a valid email address.','cleanandsimple');?>"
31
+ type="text" id="cscf_email" name="cscf[email]"
32
+ value="<?php echo $contact->Email; ?>"
33
+ placeholder="<?php _e('Your Email Address','cleanandsimple');?>"/>
34
+ <span class="help-inline"><?php if (isset($contact->Errors['email'])) echo $contact->Errors['email']; ?></span>
35
+ </div>
36
+ </div>
37
 
38
+ <!--confirm email address -->
39
+ <div class="control-group<?php if (isset($contact->Errors['confirm-email'])) echo ' error'; ?>">
40
+ <label class="control-label" for="cscf_confirm-email"><?php _e('Confirm Email Address:','cleanandsimple');?></label>
41
+ <div class="controls">
42
+ <input class="input-xlarge"
43
+ data-rule-required="true"
44
+ data-rule-email="true"
45
+ data-rule-equalTo="#cscf_email"
46
+ data-msg-required="<?php _e('Please enter the same email address again.','cleanandsimple');?>"
47
+ data-msg-email="<?php _e('Please enter a valid email address.','cleanandsimple');?>"
48
+ data-msg-equalTo="<?php _e('Please enter the same email address again.','cleanandsimple');?>"
49
+ type="text" id="cscf_confirm-email" name="cscf[confirm-email]"
50
+ value="<?php echo $contact->ConfirmEmail; ?>"
51
+ placeholder="<?php _e('Confirm Your Email Address','cleanandsimple');?>"/>
52
+ <span class="help-inline"><?php if (isset($contact->Errors['confirm-email'])) echo $contact->Errors['confirm-email']; ?></span>
53
+ </div>
54
+ </div>
55
 
56
+ <!-- name -->
57
+ <div class="control-group<?php if (isset($contact->Errors['name'])) echo ' error'; ?>">
58
+ <label class="control-label" for="cscf_name"><?php _e('Name:','cleanandsimple');?></label>
59
+ <div class="controls">
60
+ <input class="input-xlarge"
61
+ data-rule-required="true"
62
+ data-msg-required="<?php _e('Please give your name.','cleanandsimple');?>"
63
+ type="text" id="cscf_name" name="cscf[name]"
64
+ value="<?php echo $contact->Name; ?>"
65
+ placeholder="<?php _e('Your Name','cleanandsimple');?>"/>
66
+ <span class="help-inline"><?php if (isset($contact->Errors['name'])) echo $contact->Errors['name']; ?></span>
67
+ </div>
68
+ </div>
69
 
70
+ <!-- message -->
71
+ <div class="control-group<?php if (isset($contact->Errors['message'])) echo ' error'; ?>">
72
+ <label class="control-label" for="cscf_message"><?php _e('Message:','cleanandsimple');?></label>
73
+ <div class="controls">
74
+ <textarea class="input-xlarge"
75
+ data-rule-required="true"
76
+ data-msg-required="<?php _e('Please give a message.','cleanandsimple');?>"
77
+ id="cscf_message" name="cscf[message]" rows="10"
78
+ placeholder="<?php _e('Your Message','cleanandsimple');?>"><?php echo $contact->Message; ?></textarea>
79
+ <span class="help-inline"><?php if (isset($contact->Errors['message'])) echo $contact->Errors['message']; ?></span>
80
+ </div>
81
+ </div>
82
 
83
+ <!-- recaptcha -->
84
+ <?php if ( $contact->RecaptchaPublicKey<>'' && $contact->RecaptchaPrivateKey<>'') { ?>
85
+ <script type="text/javascript">
86
+ var RecaptchaOptions = {
87
+ theme : '<?php echo cscf_PluginSettings::Theme(); ?>'
88
+ };
89
+ </script>
90
+ <div class="control-group<?php
91
+ if (isset($contact->Errors['recaptcha'])) echo ' error'; ?>">
92
+ <div id="recaptcha_div" class="controls">
93
+ <?php echo recaptcha_get_html($contact->RecaptchaPublicKey,null,isset($_SERVER['HTTPS'])); ?>
94
+ <div for="cscf_recaptcha" class="help-inline"><?php if (isset($contact->Errors['recaptcha'])) echo $contact->Errors['recaptcha']; ?></div>
95
+ </div>
96
+ </div>
97
+ <?php } ?>
98
 
99
+ <div class="control-group">
100
+ <div class="controls">
101
+ <button type="submit" class="btn"><?php _e('Send Message','cleanandsimple');?></button>
102
+ </div>
103
+ </div>
104
+ </form>
105
  </div>
106
+ </div>