Version Description
- Updated santization and escaping to current plugin directory recommendations
- add email header to specify text to improve formatting
- tested up to 5.8 beta 2 and PHP 8.0
Download this release
Release Info
Developer | fullworks |
Plugin | Contact Form Clean and Simple |
Version | 4.7.2 |
Comparing to | |
See all releases |
Code changes from version 4.7.1 to 4.7.2
- ajax.php +17 -15
- class.cscf.php +57 -61
- class.cscf_contact.php +54 -41
- class.cscf_filters.php +43 -40
- class.cscf_pluginsettings.php +7 -9
- class.cscf_settings.php +407 -429
- class.view.php +44 -45
- clean-and-simple-contact-form-by-meg-nicholas.php +99 -79
- images/managewp.png +0 -0
- js/jquery.validate.js +1039 -589
- js/jquery.validate.min.js +4 -4
- languages/clean-and-simple-contact-form-by-meg-nicholas_pl_PL.mo +0 -0
- readme.txt +427 -431
- shortcodes/contact-form.php +47 -52
- views/contact-form.view.php +142 -140
- views/message-not-sent.view.php +1 -1
- views/message-sent.view.php +2 -2
ajax.php
CHANGED
@@ -1,19 +1,21 @@
|
|
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 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
|
|
|
|
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'] ) {
|
15 |
+
$result['sent'] = $contact->SendMail();
|
16 |
+
}
|
17 |
+
|
18 |
+
header( 'Content-type: application/json' );
|
19 |
+
|
20 |
+
wp_send_json( $result );
|
21 |
}
|
class.cscf.php
CHANGED
@@ -2,11 +2,11 @@
|
|
2 |
|
3 |
class cscf
|
4 |
{
|
5 |
-
public
|
6 |
-
function __construct()
|
7 |
{
|
8 |
//add settings link to plugins page
|
9 |
-
add_filter(
|
10 |
$this,
|
11 |
'SettingsLink'
|
12 |
) , 10, 2);
|
@@ -19,79 +19,76 @@ class cscf
|
|
19 |
$this,
|
20 |
'RegisterScripts'
|
21 |
));
|
22 |
-
|
23 |
add_action('admin_enqueue_scripts', array(
|
24 |
$this,
|
25 |
'RegisterAdminScripts'
|
26 |
-
));
|
27 |
-
|
28 |
add_action('plugins_loaded', array(
|
29 |
$this,
|
30 |
'RegisterTextDomain'
|
31 |
));
|
32 |
|
33 |
add_filter('cscf_spamfilter',array($this,'SpamFilter'));
|
34 |
-
|
35 |
//create the settings page
|
36 |
$settings = new cscf_settings();
|
37 |
-
|
38 |
}
|
39 |
-
|
40 |
//load text domain
|
41 |
function RegisterTextDomain()
|
42 |
-
{
|
43 |
//$path = CSCF_PLUGIN_DIR . '/languages';
|
44 |
$path = '/' . CSCF_PLUGIN_NAME . '/languages';
|
45 |
load_plugin_textdomain('clean-and-simple-contact-form-by-meg-nicholas', false, $path );
|
46 |
}
|
47 |
-
|
48 |
-
function RegisterScripts()
|
49 |
{
|
50 |
wp_register_script('jquery-validate', CSCF_PLUGIN_URL . '/js/jquery.validate.min.js', array(
|
51 |
'jquery'
|
52 |
-
) , '1.
|
53 |
-
|
54 |
-
wp_register_script( 'cscf-validate', CSCF_PLUGIN_URL . "/js/jquery.validate.contact.form.js",
|
55 |
-
'jquery',
|
56 |
CSCF_VERSION_NUM, true );
|
57 |
-
|
58 |
-
wp_localize_script( 'cscf-validate', 'cscfvars',
|
59 |
array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
|
60 |
|
61 |
-
wp_register_style('cscf-bootstrap', CSCF_PLUGIN_URL . '/css/bootstrap-forms.min.css',
|
62 |
null, CSCF_VERSION_NUM);
|
63 |
|
64 |
-
// wp_register_script( 'csf-recaptcha2',
|
65 |
-
// 'https://www.google.com/recaptcha/api.js?onload=onLoadRecaptcha2&render=explicit&hl=' . get_locale(), null, null, true );
|
66 |
-
|
67 |
wp_register_script( 'csf-recaptcha2',
|
68 |
'https://www.google.com/recaptcha/api.js?hl=' . get_locale(), null, null, true );
|
69 |
|
70 |
}
|
71 |
-
|
72 |
function RegisterAdminScripts($hook)
|
73 |
{
|
74 |
if ( $hook != 'settings_page_contact-form-settings')
|
75 |
return;
|
76 |
-
|
77 |
-
wp_register_script('cscf-admin-settings', CSCF_PLUGIN_URL . '/js/jquery.admin.settings.js',
|
78 |
array(
|
79 |
'jquery-ui-sortable',
|
80 |
-
) , CSCF_VERSION_NUM, false );
|
81 |
-
|
82 |
wp_enqueue_script('cscf-admin-settings');
|
83 |
}
|
84 |
-
|
85 |
-
function Upgrade($oldVersion)
|
86 |
{
|
87 |
-
|
88 |
//turn on the confirm-email option
|
89 |
if ( $oldVersion <= "4.2.3" ) {
|
90 |
$options = get_option(CSCF_OPTIONS_KEY);
|
91 |
$options['confirm-email'] = true;
|
92 |
update_option(CSCF_OPTIONS_KEY, $options);
|
93 |
}
|
94 |
-
|
95 |
//change namespace of options
|
96 |
if ( get_option('cff_options') != '') {
|
97 |
update_option('cscf_options', get_option('cff_options'));
|
@@ -100,37 +97,37 @@ class cscf
|
|
100 |
if ( get_option('cff_version') != '') {
|
101 |
update_option('cscf_version', get_option('cff_version'));
|
102 |
delete_option('cff_version');
|
103 |
-
}
|
104 |
-
|
105 |
$options = get_option('cscf_options');
|
106 |
$updated = false;
|
107 |
-
|
108 |
-
if (trim(get_option('recaptcha_public_key')) <> '')
|
109 |
{
|
110 |
$options['recaptcha_public_key'] = get_option('recaptcha_public_key');
|
111 |
delete_option('recaptcha_public_key');
|
112 |
$updated = true;
|
113 |
}
|
114 |
-
|
115 |
-
if (trim(get_option('recaptcha_private_key')) <> '')
|
116 |
{
|
117 |
$options['recaptcha_private_key'] = get_option('recaptcha_private_key');
|
118 |
delete_option('recaptcha_private_key');
|
119 |
$updated = true;
|
120 |
}
|
121 |
-
|
122 |
if ($updated) update_option('cscf_options', $options);
|
123 |
-
|
124 |
//delete old array key array_key
|
125 |
if (get_option('array_key') != FALSE) {
|
126 |
$options = get_option('array_key');
|
127 |
-
|
128 |
//check it was this plugin that created it by checking for a few values
|
129 |
if (isset($options['sent_message_heading']) && isset($options['sent_message_body'])) {
|
130 |
delete_option('array_key');
|
131 |
}
|
132 |
}
|
133 |
-
|
134 |
//upgrade to 4.2.3 recipient_email becomes recipient_emails (array) for multiple recipients
|
135 |
$options = get_option(CSCF_OPTIONS_KEY);
|
136 |
if ( isset($options['recipient_email']) ) {
|
@@ -138,43 +135,43 @@ class cscf
|
|
138 |
$options['recipient_emails'][] = $options['recipient_email'];
|
139 |
update_option(CSCF_OPTIONS_KEY,$options);
|
140 |
}
|
141 |
-
|
142 |
}
|
143 |
|
144 |
/*
|
145 |
* Add the settings link to the plugin page
|
146 |
*/
|
147 |
-
|
148 |
-
function SettingsLink($links, $file)
|
149 |
{
|
150 |
-
|
151 |
-
if ($file == CSCF_PLUGIN_NAME . '/' . CSCF_PLUGIN_NAME . '.php')
|
152 |
{
|
153 |
|
154 |
/*
|
155 |
* Insert the link at the beginning
|
156 |
*/
|
157 |
-
$in = '<a href="options-general.php?page=contact-form-settings">' .
|
158 |
array_unshift($links, $in);
|
159 |
|
160 |
/*
|
161 |
* Insert at the end
|
162 |
*/
|
163 |
|
164 |
-
// $links[] = '<a href="options-general.php?page=contact-form-settings">'.
|
165 |
-
|
166 |
}
|
167 |
-
|
168 |
return $links;
|
169 |
}
|
170 |
-
static
|
171 |
-
function Log($message)
|
172 |
{
|
173 |
-
|
174 |
-
if (WP_DEBUG === true)
|
175 |
{
|
176 |
-
|
177 |
-
if (is_array($message) || is_object($message))
|
178 |
{
|
179 |
error_log(print_r($message, true));
|
180 |
}
|
@@ -184,14 +181,13 @@ class cscf
|
|
184 |
}
|
185 |
}
|
186 |
}
|
187 |
-
|
188 |
/*
|
189 |
*This is all we need to do to weed out the spam.
|
190 |
*If akismet plugin is enabled then it will be hooked into these filters.
|
191 |
*/
|
192 |
-
public
|
193 |
-
|
194 |
-
|
195 |
$commentData = apply_filters('preprocess_comment', array(
|
196 |
'comment_post_ID' => $contact->PostID,
|
197 |
'comment_author' => $contact->Name,
|
@@ -212,6 +208,6 @@ class cscf
|
|
212 |
$contact->IsSpam = false;
|
213 |
}
|
214 |
return $contact;
|
215 |
-
}
|
216 |
}
|
217 |
|
2 |
|
3 |
class cscf
|
4 |
{
|
5 |
+
public
|
6 |
+
function __construct()
|
7 |
{
|
8 |
//add settings link to plugins page
|
9 |
+
add_filter('plugin_action_links', array(
|
10 |
$this,
|
11 |
'SettingsLink'
|
12 |
) , 10, 2);
|
19 |
$this,
|
20 |
'RegisterScripts'
|
21 |
));
|
22 |
+
|
23 |
add_action('admin_enqueue_scripts', array(
|
24 |
$this,
|
25 |
'RegisterAdminScripts'
|
26 |
+
));
|
27 |
+
|
28 |
add_action('plugins_loaded', array(
|
29 |
$this,
|
30 |
'RegisterTextDomain'
|
31 |
));
|
32 |
|
33 |
add_filter('cscf_spamfilter',array($this,'SpamFilter'));
|
34 |
+
|
35 |
//create the settings page
|
36 |
$settings = new cscf_settings();
|
37 |
+
|
38 |
}
|
39 |
+
|
40 |
//load text domain
|
41 |
function RegisterTextDomain()
|
42 |
+
{
|
43 |
//$path = CSCF_PLUGIN_DIR . '/languages';
|
44 |
$path = '/' . CSCF_PLUGIN_NAME . '/languages';
|
45 |
load_plugin_textdomain('clean-and-simple-contact-form-by-meg-nicholas', false, $path );
|
46 |
}
|
47 |
+
|
48 |
+
function RegisterScripts()
|
49 |
{
|
50 |
wp_register_script('jquery-validate', CSCF_PLUGIN_URL . '/js/jquery.validate.min.js', array(
|
51 |
'jquery'
|
52 |
+
) , '1.19.3', true);
|
53 |
+
|
54 |
+
wp_register_script( 'cscf-validate', CSCF_PLUGIN_URL . "/js/jquery.validate.contact.form.js",
|
55 |
+
'jquery',
|
56 |
CSCF_VERSION_NUM, true );
|
57 |
+
|
58 |
+
wp_localize_script( 'cscf-validate', 'cscfvars',
|
59 |
array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
|
60 |
|
61 |
+
wp_register_style('cscf-bootstrap', CSCF_PLUGIN_URL . '/css/bootstrap-forms.min.css',
|
62 |
null, CSCF_VERSION_NUM);
|
63 |
|
|
|
|
|
|
|
64 |
wp_register_script( 'csf-recaptcha2',
|
65 |
'https://www.google.com/recaptcha/api.js?hl=' . get_locale(), null, null, true );
|
66 |
|
67 |
}
|
68 |
+
|
69 |
function RegisterAdminScripts($hook)
|
70 |
{
|
71 |
if ( $hook != 'settings_page_contact-form-settings')
|
72 |
return;
|
73 |
+
|
74 |
+
wp_register_script('cscf-admin-settings', CSCF_PLUGIN_URL . '/js/jquery.admin.settings.js',
|
75 |
array(
|
76 |
'jquery-ui-sortable',
|
77 |
+
) , CSCF_VERSION_NUM, false );
|
78 |
+
|
79 |
wp_enqueue_script('cscf-admin-settings');
|
80 |
}
|
81 |
+
|
82 |
+
function Upgrade($oldVersion)
|
83 |
{
|
84 |
+
|
85 |
//turn on the confirm-email option
|
86 |
if ( $oldVersion <= "4.2.3" ) {
|
87 |
$options = get_option(CSCF_OPTIONS_KEY);
|
88 |
$options['confirm-email'] = true;
|
89 |
update_option(CSCF_OPTIONS_KEY, $options);
|
90 |
}
|
91 |
+
|
92 |
//change namespace of options
|
93 |
if ( get_option('cff_options') != '') {
|
94 |
update_option('cscf_options', get_option('cff_options'));
|
97 |
if ( get_option('cff_version') != '') {
|
98 |
update_option('cscf_version', get_option('cff_version'));
|
99 |
delete_option('cff_version');
|
100 |
+
}
|
101 |
+
|
102 |
$options = get_option('cscf_options');
|
103 |
$updated = false;
|
104 |
+
|
105 |
+
if (trim(get_option('recaptcha_public_key')) <> '')
|
106 |
{
|
107 |
$options['recaptcha_public_key'] = get_option('recaptcha_public_key');
|
108 |
delete_option('recaptcha_public_key');
|
109 |
$updated = true;
|
110 |
}
|
111 |
+
|
112 |
+
if (trim(get_option('recaptcha_private_key')) <> '')
|
113 |
{
|
114 |
$options['recaptcha_private_key'] = get_option('recaptcha_private_key');
|
115 |
delete_option('recaptcha_private_key');
|
116 |
$updated = true;
|
117 |
}
|
118 |
+
|
119 |
if ($updated) update_option('cscf_options', $options);
|
120 |
+
|
121 |
//delete old array key array_key
|
122 |
if (get_option('array_key') != FALSE) {
|
123 |
$options = get_option('array_key');
|
124 |
+
|
125 |
//check it was this plugin that created it by checking for a few values
|
126 |
if (isset($options['sent_message_heading']) && isset($options['sent_message_body'])) {
|
127 |
delete_option('array_key');
|
128 |
}
|
129 |
}
|
130 |
+
|
131 |
//upgrade to 4.2.3 recipient_email becomes recipient_emails (array) for multiple recipients
|
132 |
$options = get_option(CSCF_OPTIONS_KEY);
|
133 |
if ( isset($options['recipient_email']) ) {
|
135 |
$options['recipient_emails'][] = $options['recipient_email'];
|
136 |
update_option(CSCF_OPTIONS_KEY,$options);
|
137 |
}
|
138 |
+
|
139 |
}
|
140 |
|
141 |
/*
|
142 |
* Add the settings link to the plugin page
|
143 |
*/
|
144 |
+
|
145 |
+
function SettingsLink($links, $file)
|
146 |
{
|
147 |
+
|
148 |
+
if ($file == CSCF_PLUGIN_NAME . '/' . CSCF_PLUGIN_NAME . '.php')
|
149 |
{
|
150 |
|
151 |
/*
|
152 |
* Insert the link at the beginning
|
153 |
*/
|
154 |
+
$in = '<a href="options-general.php?page=contact-form-settings">' . esc_html__('Settings', 'clean-and-simple-contact-form-by-meg-nicholas') . '</a>';
|
155 |
array_unshift($links, $in);
|
156 |
|
157 |
/*
|
158 |
* Insert at the end
|
159 |
*/
|
160 |
|
161 |
+
// $links[] = '<a href="options-general.php?page=contact-form-settings">'.esc_html__('Settings','contact-form').'</a>';
|
162 |
+
|
163 |
}
|
164 |
+
|
165 |
return $links;
|
166 |
}
|
167 |
+
static
|
168 |
+
function Log($message)
|
169 |
{
|
170 |
+
|
171 |
+
if (WP_DEBUG === true)
|
172 |
{
|
173 |
+
|
174 |
+
if (is_array($message) || is_object($message))
|
175 |
{
|
176 |
error_log(print_r($message, true));
|
177 |
}
|
181 |
}
|
182 |
}
|
183 |
}
|
184 |
+
|
185 |
/*
|
186 |
*This is all we need to do to weed out the spam.
|
187 |
*If akismet plugin is enabled then it will be hooked into these filters.
|
188 |
*/
|
189 |
+
public function SpamFilter($contact) {
|
190 |
+
|
|
|
191 |
$commentData = apply_filters('preprocess_comment', array(
|
192 |
'comment_post_ID' => $contact->PostID,
|
193 |
'comment_author' => $contact->Name,
|
208 |
$contact->IsSpam = false;
|
209 |
}
|
210 |
return $contact;
|
211 |
+
}
|
212 |
}
|
213 |
|
class.cscf_contact.php
CHANGED
@@ -26,34 +26,48 @@ class cscf_Contact {
|
|
26 |
$this->RecaptchaPrivateKey = cscf_PluginSettings::PrivateKey();
|
27 |
}
|
28 |
|
29 |
-
if ( $_SERVER['REQUEST_METHOD'] == 'POST'
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
}
|
44 |
-
|
45 |
-
if ( cscf_PluginSettings::ContactConsent() ) {
|
46 |
-
$this->ContactConsent = isset( $cscf['contact-consent'] );
|
47 |
-
}
|
48 |
-
|
49 |
-
unset( $_POST['cscf'] );
|
50 |
}
|
51 |
|
52 |
$this->IsSpam = false;
|
53 |
}
|
54 |
|
55 |
-
public
|
56 |
-
function IsValid() {
|
57 |
$this->Errors = array();
|
58 |
|
59 |
if ( $_SERVER['REQUEST_METHOD'] != 'POST' ) {
|
@@ -68,41 +82,41 @@ class cscf_Contact {
|
|
68 |
// email and confirm email are the same
|
69 |
if ( cscf_PluginSettings::ConfirmEmail() ) {
|
70 |
if ( $this->Email != $this->ConfirmEmail ) {
|
71 |
-
$this->Errors['confirm-email'] =
|
72 |
}
|
73 |
}
|
74 |
|
75 |
//email
|
76 |
if ( strlen( $this->Email ) == 0 ) {
|
77 |
-
$this->Errors['email'] =
|
78 |
}
|
79 |
|
80 |
//confirm email
|
81 |
if ( cscf_PluginSettings::ConfirmEmail() ) {
|
82 |
if ( strlen( $this->ConfirmEmail ) == 0 ) {
|
83 |
-
$this->Errors['confirm-email'] =
|
84 |
}
|
85 |
}
|
86 |
|
87 |
//name
|
88 |
if ( strlen( $this->Name ) == 0 ) {
|
89 |
-
$this->Errors['name'] =
|
90 |
}
|
91 |
|
92 |
//message
|
93 |
if ( strlen( $this->Message ) == 0 ) {
|
94 |
-
$this->Errors['message'] =
|
95 |
}
|
96 |
|
97 |
//email invalid address
|
98 |
if ( strlen( $this->Email ) > 0 && ! filter_var( $this->Email, FILTER_VALIDATE_EMAIL ) ) {
|
99 |
-
$this->Errors['email'] =
|
100 |
}
|
101 |
|
102 |
//contact consent
|
103 |
if ( cscf_PluginSettings::ContactConsent() ) {
|
104 |
if ( ! $this->ContactConsent ) {
|
105 |
-
$this->Errors['contact-consent'] =
|
106 |
}
|
107 |
}
|
108 |
|
@@ -111,15 +125,14 @@ class cscf_Contact {
|
|
111 |
$resp = csf_RecaptchaV2::VerifyResponse( $_SERVER["REMOTE_ADDR"], $this->RecaptchaPrivateKey, $_POST["g-recaptcha-response"] );
|
112 |
|
113 |
if ( ! $resp->success ) {
|
114 |
-
$this->Errors['recaptcha'] =
|
115 |
}
|
116 |
}
|
117 |
|
118 |
return count( $this->Errors ) == 0;
|
119 |
}
|
120 |
|
121 |
-
public
|
122 |
-
function SendMail() {
|
123 |
apply_filters( 'cscf_spamfilter', $this );
|
124 |
|
125 |
if ( $this->IsSpam === true ) {
|
@@ -134,21 +147,21 @@ class cscf_Contact {
|
|
134 |
$filters->fromEmail = $this->Email;
|
135 |
}
|
136 |
|
137 |
-
$filters->
|
138 |
|
139 |
//add filters
|
140 |
$filters->add( 'wp_mail_from' );
|
141 |
$filters->add( 'wp_mail_from_name' );
|
142 |
|
143 |
//headers
|
144 |
-
$header = "
|
145 |
|
146 |
//message
|
147 |
-
$message =
|
148 |
-
$message .=
|
149 |
-
$message .=
|
150 |
-
$message .=
|
151 |
-
$message .= cscf_PluginSettings::ContactConsentMsg() . ': ' . ( $this->ContactConsent ?
|
152 |
|
153 |
|
154 |
$result = ( wp_mail( cscf_PluginSettings::RecipientEmails(), cscf_PluginSettings::Subject(), stripslashes( $message ), $header ) );
|
@@ -167,7 +180,7 @@ class cscf_Contact {
|
|
167 |
$filters->fromEmail = $recipients[0];
|
168 |
}
|
169 |
|
170 |
-
$filters->
|
171 |
|
172 |
//add filters
|
173 |
$filters->add( 'wp_mail_from' );
|
@@ -175,7 +188,7 @@ class cscf_Contact {
|
|
175 |
|
176 |
$header = "";
|
177 |
$message = cscf_PluginSettings::SentMessageBody() . "\n\n";
|
178 |
-
$message .=
|
179 |
$message .= $this->Message;
|
180 |
|
181 |
$result = ( wp_mail( $this->Email, cscf_PluginSettings::Subject(), stripslashes( $message ), $header ) );
|
26 |
$this->RecaptchaPrivateKey = cscf_PluginSettings::PrivateKey();
|
27 |
}
|
28 |
|
29 |
+
if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
|
30 |
+
if ( isset( $_POST['cscf'] ) ) {
|
31 |
+
$cscf = (array) $_POST['cscf'];
|
32 |
+
foreach ( $cscf as $key => $value ) {
|
33 |
+
switch ( $key ) {
|
34 |
+
case 'name':
|
35 |
+
$this->Name = sanitize_text_field( $value );
|
36 |
+
break;
|
37 |
+
case 'email':
|
38 |
+
$this->Email = sanitize_email( $value );
|
39 |
+
break;
|
40 |
+
case 'confirm-email':
|
41 |
+
$this->ConfirmEmail = sanitize_email( $value );
|
42 |
+
break;
|
43 |
+
case 'email-sender':
|
44 |
+
$this->EmailToSender = sanitize_text_field( $value );
|
45 |
+
break;
|
46 |
+
case 'message':
|
47 |
+
$this->Message = sanitize_textarea_field( $value );
|
48 |
+
break;
|
49 |
+
case 'contact-consent':
|
50 |
+
if ( cscf_PluginSettings::ContactConsent() ) {
|
51 |
+
$this->ContactConsent = sanitize_text_field( $value );
|
52 |
+
}
|
53 |
+
break;
|
54 |
+
default:
|
55 |
+
$cscf[ $key ] = null; // should never get this but just in case.
|
56 |
+
}
|
57 |
+
}
|
58 |
+
|
59 |
+
if ( isset( $_POST['post-id'] ) ) {
|
60 |
+
$this->PostID = sanitize_text_field( $_POST['post-id'] );
|
61 |
+
}
|
62 |
+
|
63 |
+
unset( $_POST['cscf'] );
|
64 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
}
|
66 |
|
67 |
$this->IsSpam = false;
|
68 |
}
|
69 |
|
70 |
+
public function IsValid() {
|
|
|
71 |
$this->Errors = array();
|
72 |
|
73 |
if ( $_SERVER['REQUEST_METHOD'] != 'POST' ) {
|
82 |
// email and confirm email are the same
|
83 |
if ( cscf_PluginSettings::ConfirmEmail() ) {
|
84 |
if ( $this->Email != $this->ConfirmEmail ) {
|
85 |
+
$this->Errors['confirm-email'] = esc_html__( 'Sorry the email addresses do not match.', 'clean-and-simple-contact-form-by-meg-nicholas' );
|
86 |
}
|
87 |
}
|
88 |
|
89 |
//email
|
90 |
if ( strlen( $this->Email ) == 0 ) {
|
91 |
+
$this->Errors['email'] = esc_html__( 'Please give your email address.', 'clean-and-simple-contact-form-by-meg-nicholas' );
|
92 |
}
|
93 |
|
94 |
//confirm email
|
95 |
if ( cscf_PluginSettings::ConfirmEmail() ) {
|
96 |
if ( strlen( $this->ConfirmEmail ) == 0 ) {
|
97 |
+
$this->Errors['confirm-email'] = esc_html__( 'Please confirm your email address.', 'clean-and-simple-contact-form-by-meg-nicholas' );
|
98 |
}
|
99 |
}
|
100 |
|
101 |
//name
|
102 |
if ( strlen( $this->Name ) == 0 ) {
|
103 |
+
$this->Errors['name'] = esc_html__( 'Please give your name.', 'clean-and-simple-contact-form-by-meg-nicholas' );
|
104 |
}
|
105 |
|
106 |
//message
|
107 |
if ( strlen( $this->Message ) == 0 ) {
|
108 |
+
$this->Errors['message'] = esc_html__( 'Please enter a message.', 'clean-and-simple-contact-form-by-meg-nicholas' );
|
109 |
}
|
110 |
|
111 |
//email invalid address
|
112 |
if ( strlen( $this->Email ) > 0 && ! filter_var( $this->Email, FILTER_VALIDATE_EMAIL ) ) {
|
113 |
+
$this->Errors['email'] = esc_html__( 'Please enter a valid email address.', 'clean-and-simple-contact-form-by-meg-nicholas' );
|
114 |
}
|
115 |
|
116 |
//contact consent
|
117 |
if ( cscf_PluginSettings::ContactConsent() ) {
|
118 |
if ( ! $this->ContactConsent ) {
|
119 |
+
$this->Errors['contact-consent'] = esc_html__( 'Please give your consent.', 'clean-and-simple-contact-form-by-meg-nicholas' );
|
120 |
}
|
121 |
}
|
122 |
|
125 |
$resp = csf_RecaptchaV2::VerifyResponse( $_SERVER["REMOTE_ADDR"], $this->RecaptchaPrivateKey, $_POST["g-recaptcha-response"] );
|
126 |
|
127 |
if ( ! $resp->success ) {
|
128 |
+
$this->Errors['recaptcha'] = esc_html__( 'Please solve the recaptcha to continue.', 'clean-and-simple-contact-form-by-meg-nicholas' );
|
129 |
}
|
130 |
}
|
131 |
|
132 |
return count( $this->Errors ) == 0;
|
133 |
}
|
134 |
|
135 |
+
public function SendMail() {
|
|
|
136 |
apply_filters( 'cscf_spamfilter', $this );
|
137 |
|
138 |
if ( $this->IsSpam === true ) {
|
147 |
$filters->fromEmail = $this->Email;
|
148 |
}
|
149 |
|
150 |
+
$filters->from_name = $this->Name;
|
151 |
|
152 |
//add filters
|
153 |
$filters->add( 'wp_mail_from' );
|
154 |
$filters->add( 'wp_mail_from_name' );
|
155 |
|
156 |
//headers
|
157 |
+
$header = "Content-Type: text/plain\r\nReply-To: " . $this->Email . "\r\n";
|
158 |
|
159 |
//message
|
160 |
+
$message = esc_html__( 'From: ', 'clean-and-simple-contact-form-by-meg-nicholas' ) . esc_attr( $this->Name ) . "\r\n";
|
161 |
+
$message .= esc_html__( 'Email: ', 'clean-and-simple-contact-form-by-meg-nicholas' ) . esc_attr( $this->Email ) . "\r\n";
|
162 |
+
$message .= esc_html__( 'Page URL: ', 'clean-and-simple-contact-form-by-meg-nicholas' ) . get_permalink( $this->PostID ) . "\r\n";
|
163 |
+
$message .= esc_html__( 'Message:', 'clean-and-simple-contact-form-by-meg-nicholas' ) . "\n\n" . esc_html( $this->Message ) . "\r\n";
|
164 |
+
$message .= cscf_PluginSettings::ContactConsentMsg() . ': ' . ( $this->ContactConsent ? esc_html__( 'yes', 'clean-and-simple-contact-form-by-meg-nicholas' ) : esc_html__( 'no', 'clean-and-simple-contact-form-by-meg-nicholas' ) );
|
165 |
|
166 |
|
167 |
$result = ( wp_mail( cscf_PluginSettings::RecipientEmails(), cscf_PluginSettings::Subject(), stripslashes( $message ), $header ) );
|
180 |
$filters->fromEmail = $recipients[0];
|
181 |
}
|
182 |
|
183 |
+
$filters->from_name = get_bloginfo( 'name' );
|
184 |
|
185 |
//add filters
|
186 |
$filters->add( 'wp_mail_from' );
|
188 |
|
189 |
$header = "";
|
190 |
$message = cscf_PluginSettings::SentMessageBody() . "\n\n";
|
191 |
+
$message .= esc_html__( "Here is a copy of your message :", "clean-and-simple-contact-form" ) . "\n\n";
|
192 |
$message .= $this->Message;
|
193 |
|
194 |
$result = ( wp_mail( $this->Email, cscf_PluginSettings::Subject(), stripslashes( $message ), $header ) );
|
class.cscf_filters.php
CHANGED
@@ -5,46 +5,49 @@
|
|
5 |
*/
|
6 |
|
7 |
class cscf_Filters {
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
}
|
22 |
|
23 |
-
$default_from = 'wordpress@' . $sitename;
|
24 |
-
// End of copied code
|
25 |
-
|
26 |
-
// If the from email is not the default, return it unchanged
|
27 |
-
if ( $orig != $default_from ) {
|
28 |
-
return $orig;
|
29 |
-
}
|
30 |
-
return $this->fromEmail;
|
31 |
-
}
|
32 |
-
|
33 |
-
//strip slashes from the name
|
34 |
-
function wp_mail_from_name ($orig) {
|
35 |
-
|
36 |
-
if ( $orig != 'WordPress') {
|
37 |
-
return $orig;
|
38 |
-
}
|
39 |
-
return stripslashes($this->fromName);
|
40 |
-
}
|
41 |
-
|
42 |
-
function add($filter, $priority = 10, $args = 1) {
|
43 |
-
add_filter ($filter, array($this,$filter),$priority,$args);
|
44 |
-
}
|
45 |
-
|
46 |
-
function remove($filter, $priority = 10, $args = 1) {
|
47 |
-
remove_filter ($filter, array($this,$filter),$priority,$args);
|
48 |
-
}
|
49 |
-
|
50 |
}
|
5 |
*/
|
6 |
|
7 |
class cscf_Filters {
|
8 |
+
|
9 |
+
|
10 |
+
var $from_email;
|
11 |
+
var $from_name;
|
12 |
+
|
13 |
+
function wp_mail_from( $orig ) {
|
14 |
+
|
15 |
+
// This is copied from pluggable.php lines 348-354 as at revision 10150
|
16 |
+
// http://trac.wordpress.org/browser/branches/2.7/wp-includes/pluggable.php#L348
|
17 |
+
|
18 |
+
// Get the site domain and get rid of www.
|
19 |
+
$sitename = strtolower( $_SERVER['SERVER_NAME'] );
|
20 |
+
if ( substr( $sitename, 0, 4 ) == 'www.' ) {
|
21 |
+
$sitename = substr( $sitename, 4 );
|
22 |
+
}
|
23 |
+
|
24 |
+
$default_from = 'wordpress@' . $sitename;
|
25 |
+
// End of copied code
|
26 |
+
|
27 |
+
// If the from email is not the default, return it unchanged
|
28 |
+
if ( $orig != $default_from ) {
|
29 |
+
return $orig;
|
30 |
+
}
|
31 |
+
|
32 |
+
return $this->from_email;
|
33 |
+
}
|
34 |
+
|
35 |
+
//strip slashes from the name
|
36 |
+
function wp_mail_from_name( $orig ) {
|
37 |
+
|
38 |
+
if ( $orig != 'WordPress' ) {
|
39 |
+
return $orig;
|
40 |
+
}
|
41 |
+
|
42 |
+
return stripslashes( $this->from_name );
|
43 |
+
}
|
44 |
+
|
45 |
+
function add( $filter, $priority = 10, $args = 1 ) {
|
46 |
+
add_filter( $filter, array( $this, $filter ), $priority, $args );
|
47 |
+
}
|
48 |
+
|
49 |
+
function remove( $filter, $priority = 10, $args = 1 ) {
|
50 |
+
remove_filter( $filter, array( $this, $filter ), $priority, $args );
|
51 |
}
|
52 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
}
|
class.cscf_pluginsettings.php
CHANGED
@@ -41,7 +41,7 @@ class cscf_PluginSettings
|
|
41 |
{
|
42 |
$options = get_option(CSCF_OPTIONS_KEY);
|
43 |
|
44 |
-
return isset($options['sent_message_heading']) ?
|
45 |
}
|
46 |
|
47 |
static
|
@@ -49,7 +49,7 @@ class cscf_PluginSettings
|
|
49 |
{
|
50 |
$options = get_option(CSCF_OPTIONS_KEY);
|
51 |
|
52 |
-
return isset($options['sent_message_body']) ?
|
53 |
}
|
54 |
|
55 |
static
|
@@ -57,7 +57,7 @@ class cscf_PluginSettings
|
|
57 |
{
|
58 |
$options = get_option(CSCF_OPTIONS_KEY);
|
59 |
|
60 |
-
return isset($options['message'])
|
61 |
}
|
62 |
|
63 |
static
|
@@ -91,7 +91,7 @@ class cscf_PluginSettings
|
|
91 |
{
|
92 |
$options = get_option(CSCF_OPTIONS_KEY);
|
93 |
|
94 |
-
return isset($options['subject']) ?
|
95 |
}
|
96 |
|
97 |
static
|
@@ -139,7 +139,7 @@ class cscf_PluginSettings
|
|
139 |
|
140 |
$options = get_option(CSCF_OPTIONS_KEY);
|
141 |
|
142 |
-
return isset( $options['contact-consent-msg'] ) ? $options['contact-consent-msg'] :
|
143 |
|
144 |
}
|
145 |
|
@@ -159,14 +159,12 @@ class cscf_PluginSettings
|
|
159 |
|
160 |
}
|
161 |
|
162 |
-
static
|
163 |
-
function InputIcons()
|
164 |
{
|
165 |
return false;
|
166 |
}
|
167 |
|
168 |
-
static
|
169 |
-
function ConfirmEmail()
|
170 |
{
|
171 |
$options = get_option(CSCF_OPTIONS_KEY);
|
172 |
return isset($options['confirm-email']) ? true : false;
|
41 |
{
|
42 |
$options = get_option(CSCF_OPTIONS_KEY);
|
43 |
|
44 |
+
return isset($options['sent_message_heading']) ? $options['sent_message_heading'] : esc_html__('Message Sent', 'clean-and-simple-contact-form-by-meg-nicholas');
|
45 |
}
|
46 |
|
47 |
static
|
49 |
{
|
50 |
$options = get_option(CSCF_OPTIONS_KEY);
|
51 |
|
52 |
+
return isset($options['sent_message_body']) ? $options['sent_message_body'] : esc_html__('Thank you for your message, we will be in touch very shortly.', 'clean-and-simple-contact-form-by-meg-nicholas');
|
53 |
}
|
54 |
|
55 |
static
|
57 |
{
|
58 |
$options = get_option(CSCF_OPTIONS_KEY);
|
59 |
|
60 |
+
return isset($options['message'])? $options['message'] : esc_html__('Please enter your contact details and a short message below and I will try to answer your query as soon as possible.', 'clean-and-simple-contact-form-by-meg-nicholas');
|
61 |
}
|
62 |
|
63 |
static
|
91 |
{
|
92 |
$options = get_option(CSCF_OPTIONS_KEY);
|
93 |
|
94 |
+
return isset($options['subject']) ? $options['subject']: get_bloginfo('name') . esc_html__(' - Web Enquiry', 'clean-and-simple-contact-form-by-meg-nicholas');
|
95 |
}
|
96 |
|
97 |
static
|
139 |
|
140 |
$options = get_option(CSCF_OPTIONS_KEY);
|
141 |
|
142 |
+
return isset( $options['contact-consent-msg'] ) ? $options['contact-consent-msg'] : esc_html__( 'I consent to my contact details being stored', 'clean-and-simple-contact-form-by-meg-nicholas' );
|
143 |
|
144 |
}
|
145 |
|
159 |
|
160 |
}
|
161 |
|
162 |
+
static function InputIcons()
|
|
|
163 |
{
|
164 |
return false;
|
165 |
}
|
166 |
|
167 |
+
static function ConfirmEmail()
|
|
|
168 |
{
|
169 |
$options = get_option(CSCF_OPTIONS_KEY);
|
170 |
return isset($options['confirm-email']) ? true : false;
|
class.cscf_settings.php
CHANGED
@@ -1,429 +1,407 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/*
|
4 |
-
* creates the settings page for the plugin
|
5 |
-
*/
|
6 |
-
|
7 |
-
class cscf_settings
|
8 |
-
{
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
<
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
$theme = cscf_PluginSettings::Theme();
|
409 |
-
$disabled = cscf_PluginSettings::UseRecaptcha() == false ? "disabled" : "";
|
410 |
-
?>
|
411 |
-
<select <?php echo $disabled; ?> id="theme" name="<?php echo CSCF_OPTIONS_KEY; ?>[theme]">
|
412 |
-
<option <?php echo $theme == "light" ? "selected" : ""; ?>
|
413 |
-
value="light"><?php _e('Light', 'clean-and-simple-contact-form-by-meg-nicholas'); ?></option>
|
414 |
-
<option <?php echo $theme == "dark" ? "selected" : ""; ?>
|
415 |
-
value="dark"><?php _e('Dark', 'clean-and-simple-contact-form-by-meg-nicholas'); ?></option>
|
416 |
-
</select>
|
417 |
-
<?php
|
418 |
-
break;
|
419 |
-
case 'use_client_validation':
|
420 |
-
$checked = cscf_PluginSettings::UseClientValidation() == true ? "checked" : "";
|
421 |
-
?><input type="checkbox" <?php echo $checked; ?> id="use_client_validation"
|
422 |
-
name="<?php echo CSCF_OPTIONS_KEY; ?>[use_client_validation]"><?php
|
423 |
-
break;
|
424 |
-
default:
|
425 |
-
break;
|
426 |
-
}
|
427 |
-
}
|
428 |
-
}
|
429 |
-
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* creates the settings page for the plugin
|
5 |
+
*/
|
6 |
+
|
7 |
+
class cscf_settings {
|
8 |
+
public function __construct() {
|
9 |
+
|
10 |
+
if ( is_admin() ) {
|
11 |
+
add_action( 'admin_menu', array(
|
12 |
+
$this,
|
13 |
+
'add_plugin_page'
|
14 |
+
) );
|
15 |
+
add_action( 'admin_init', array(
|
16 |
+
$this,
|
17 |
+
'page_init'
|
18 |
+
) );
|
19 |
+
}
|
20 |
+
}
|
21 |
+
|
22 |
+
public function add_plugin_page() {
|
23 |
+
|
24 |
+
// This page will be under "Settings".
|
25 |
+
add_options_page(
|
26 |
+
esc_html__( 'Contact Form Settings', 'clean-and-simple-contact-form-by-meg-nicholas' ),
|
27 |
+
esc_html__( 'Contact Form', 'clean-and-simple-contact-form-by-meg-nicholas' ),
|
28 |
+
'manage_options',
|
29 |
+
'contact-form-settings',
|
30 |
+
array(
|
31 |
+
$this,
|
32 |
+
'create_admin_page',
|
33 |
+
)
|
34 |
+
);
|
35 |
+
}
|
36 |
+
|
37 |
+
public function create_admin_page() {
|
38 |
+
?>
|
39 |
+
<h2><?php esc_html_e( 'Clean and Simple Contact Form Settings', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?></h2>
|
40 |
+
<hr/>
|
41 |
+
<div style="float:left;">
|
42 |
+
<p><?php esc_html_e( 'You are using version', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?><?php echo esc_attr(CSCF_VERSION_NUM); ?></p>
|
43 |
+
|
44 |
+
<p><?php esc_html_e( 'If you find this plugin useful please consider', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>
|
45 |
+
<a target="_blank"
|
46 |
+
href="http://wordpress.org/support/view/plugin-reviews/<?php echo esc_attr(CSCF_PLUGIN_NAME); ?>">
|
47 |
+
<?php esc_html_e( 'leaving a review', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>
|
48 |
+
</a>
|
49 |
+
. <?php esc_html_e( 'Thank you!', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>
|
50 |
+
</p>
|
51 |
+
|
52 |
+
<?php if ( cscf_PluginSettings::IsJetPackContactFormEnabled() ) { ?>
|
53 |
+
<p class="highlight">
|
54 |
+
<?php esc_html_e( 'NOTICE: You have JetPack\'s Contact Form enabled please deactivate it or use the shortcode [cscf-contact-form] instead.', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>
|
55 |
+
</p>
|
56 |
+
<?php } ?>
|
57 |
+
|
58 |
+
<p class="howto"><?php esc_html_e( "Please Note: To add the contact form to your page please add the text", "clean-and-simple-contact-form" ); ?>
|
59 |
+
<code>[cscf-contact-form]</code> <?php esc_html_e( "to your post or page.", "clean-and-simple-contact-form" ); ?>
|
60 |
+
</p>
|
61 |
+
|
62 |
+
<form method="post" action="options.php">
|
63 |
+
<?php
|
64 |
+
submit_button();
|
65 |
+
/* This prints out all hidden setting fields*/
|
66 |
+
settings_fields( 'test_option_group' );
|
67 |
+
do_settings_sections( 'contact-form-settings' );
|
68 |
+
submit_button();
|
69 |
+
?>
|
70 |
+
</form>
|
71 |
+
</div>
|
72 |
+
<?php
|
73 |
+
}
|
74 |
+
|
75 |
+
public function page_init() {
|
76 |
+
add_settings_section(
|
77 |
+
'section_recaptcha',
|
78 |
+
'<h3>' . esc_html__( 'ReCAPTCHA Settings', 'clean-and-simple-contact-form-by-meg-nicholas' ) . '</h3>',
|
79 |
+
array(
|
80 |
+
$this,
|
81 |
+
'print_section_info_recaptcha',
|
82 |
+
),
|
83 |
+
'contact-form-settings'
|
84 |
+
);
|
85 |
+
register_setting( 'test_option_group', CSCF_OPTIONS_KEY, array(
|
86 |
+
$this,
|
87 |
+
'check_form'
|
88 |
+
) );
|
89 |
+
add_settings_field( 'use_recaptcha', esc_html__( 'Use reCAPTCHA :', 'clean-and-simple-contact-form-by-meg-nicholas' ), array(
|
90 |
+
$this,
|
91 |
+
'create_fields'
|
92 |
+
), 'contact-form-settings', 'section_recaptcha', array(
|
93 |
+
'use_recaptcha'
|
94 |
+
) );
|
95 |
+
add_settings_field( 'theme', esc_html__( 'reCAPTCHA Theme :', 'clean-and-simple-contact-form-by-meg-nicholas' ), array(
|
96 |
+
$this,
|
97 |
+
'create_fields'
|
98 |
+
), 'contact-form-settings', 'section_recaptcha', array(
|
99 |
+
'theme'
|
100 |
+
) );
|
101 |
+
add_settings_field( 'recaptcha_public_key', esc_html__( 'reCAPTCHA Public Key :', 'clean-and-simple-contact-form-by-meg-nicholas' ), array(
|
102 |
+
$this,
|
103 |
+
'create_fields'
|
104 |
+
), 'contact-form-settings', 'section_recaptcha', array(
|
105 |
+
'recaptcha_public_key'
|
106 |
+
) );
|
107 |
+
add_settings_field( 'recaptcha_private_key', esc_html__( 'reCAPTCHA Private Key :', 'clean-and-simple-contact-form-by-meg-nicholas' ), array(
|
108 |
+
$this,
|
109 |
+
'create_fields'
|
110 |
+
), 'contact-form-settings', 'section_recaptcha', array(
|
111 |
+
'recaptcha_private_key'
|
112 |
+
) );
|
113 |
+
add_settings_section( 'section_message', '<h3>' . esc_html__( 'Message Settings', 'clean-and-simple-contact-form-by-meg-nicholas' ) . '</h3>', array(
|
114 |
+
$this,
|
115 |
+
'print_section_info_message'
|
116 |
+
), 'contact-form-settings' );
|
117 |
+
add_settings_field( 'recipient_emails', esc_html__( 'Recipient Emails :', 'clean-and-simple-contact-form-by-meg-nicholas' ), array(
|
118 |
+
$this,
|
119 |
+
'create_fields'
|
120 |
+
), 'contact-form-settings', 'section_message', array(
|
121 |
+
'recipient_emails'
|
122 |
+
) );
|
123 |
+
add_settings_field( 'confirm-email', esc_html__( 'Confirm Email Address :', 'clean-and-simple-contact-form-by-meg-nicholas' ), array(
|
124 |
+
$this,
|
125 |
+
'create_fields'
|
126 |
+
), 'contact-form-settings', 'section_message', array(
|
127 |
+
'confirm-email'
|
128 |
+
) );
|
129 |
+
add_settings_field( 'email-sender', esc_html__( 'Allow users to email themselves a copy :', 'clean-and-simple-contact-form-by-meg-nicholas' ), array(
|
130 |
+
$this,
|
131 |
+
'create_fields'
|
132 |
+
), 'contact-form-settings', 'section_message', array(
|
133 |
+
'email-sender'
|
134 |
+
) );
|
135 |
+
add_settings_field( 'contact-consent', '<span style="color:red;">' . esc_html__( '*New*', 'clean-and-simple-contact-form-by-meg-nicholas' ) . '</span> ' . esc_html__( 'Add a consent checkbox :', 'clean-and-simple-contact-form-by-meg-nicholas' ), array(
|
136 |
+
$this,
|
137 |
+
'create_fields'
|
138 |
+
), 'contact-form-settings', 'section_message', array(
|
139 |
+
'contact-consent'
|
140 |
+
) );
|
141 |
+
add_settings_field( 'contact-consent-msg', '<span style="color:red;">' . esc_html__( '*New*', 'clean-and-simple-contact-form-by-meg-nicholas' ) . '</span> ' . esc_html__( 'Consent message :', 'clean-and-simple-contact-form-by-meg-nicholas' ), array(
|
142 |
+
$this,
|
143 |
+
'create_fields'
|
144 |
+
), 'contact-form-settings', 'section_message', array(
|
145 |
+
'contact-consent-msg'
|
146 |
+
) );
|
147 |
+
add_settings_field( 'override-from', esc_html__( 'Override \'From\' Address :', 'clean-and-simple-contact-form-by-meg-nicholas' ), array(
|
148 |
+
$this,
|
149 |
+
'create_fields'
|
150 |
+
), 'contact-form-settings', 'section_message', array(
|
151 |
+
'override-from'
|
152 |
+
) );
|
153 |
+
add_settings_field( 'from-email', esc_html__( '\'From\' Email Address :', 'clean-and-simple-contact-form-by-meg-nicholas' ), array(
|
154 |
+
$this,
|
155 |
+
'create_fields'
|
156 |
+
), 'contact-form-settings', 'section_message', array(
|
157 |
+
'from-email'
|
158 |
+
) );
|
159 |
+
add_settings_field( 'subject', esc_html__( 'Email Subject :', 'clean-and-simple-contact-form-by-meg-nicholas' ), array(
|
160 |
+
$this,
|
161 |
+
'create_fields'
|
162 |
+
), 'contact-form-settings', 'section_message', array(
|
163 |
+
'subject'
|
164 |
+
) );
|
165 |
+
add_settings_field( 'message', esc_html__( 'Message :', 'clean-and-simple-contact-form-by-meg-nicholas' ), array(
|
166 |
+
$this,
|
167 |
+
'create_fields'
|
168 |
+
), 'contact-form-settings', 'section_message', array(
|
169 |
+
'message'
|
170 |
+
) );
|
171 |
+
add_settings_field( 'sent_message_heading', esc_html__( 'Message Sent Heading :', 'clean-and-simple-contact-form-by-meg-nicholas' ), array(
|
172 |
+
$this,
|
173 |
+
'create_fields'
|
174 |
+
), 'contact-form-settings', 'section_message', array(
|
175 |
+
'sent_message_heading'
|
176 |
+
) );
|
177 |
+
add_settings_field( 'sent_message_body', esc_html__( 'Message Sent Content :', 'clean-and-simple-contact-form-by-meg-nicholas' ), array(
|
178 |
+
$this,
|
179 |
+
'create_fields'
|
180 |
+
), 'contact-form-settings', 'section_message', array(
|
181 |
+
'sent_message_body'
|
182 |
+
) );
|
183 |
+
add_settings_section( 'section_styling', '<h3>' . esc_html__( 'Styling and Validation', 'clean-and-simple-contact-form-by-meg-nicholas' ) . '</h3>', array(
|
184 |
+
$this,
|
185 |
+
'print_section_info_styling'
|
186 |
+
), 'contact-form-settings' );
|
187 |
+
add_settings_field( 'load_stylesheet', esc_html__( 'Use the plugin default stylesheet (un-tick to use your theme style sheet instead) :', 'clean-and-simple-contact-form-by-meg-nicholas' ), array(
|
188 |
+
$this,
|
189 |
+
'create_fields'
|
190 |
+
), 'contact-form-settings', 'section_styling', array(
|
191 |
+
'load_stylesheet'
|
192 |
+
) );
|
193 |
+
add_settings_field( 'use_client_validation', esc_html__( 'Use client side validation (AJAX) :', 'clean-and-simple-contact-form-by-meg-nicholas' ), array(
|
194 |
+
$this,
|
195 |
+
'create_fields'
|
196 |
+
), 'contact-form-settings', 'section_styling', array(
|
197 |
+
'use_client_validation'
|
198 |
+
) );
|
199 |
+
}
|
200 |
+
|
201 |
+
public function check_form(
|
202 |
+
$input
|
203 |
+
) {
|
204 |
+
|
205 |
+
//recaptcha theme
|
206 |
+
if ( isset( $input['theme'] ) ) {
|
207 |
+
$input['theme'] = sanitize_text_field( $input['theme'] );
|
208 |
+
}
|
209 |
+
|
210 |
+
//recaptcha_public_key
|
211 |
+
if ( isset( $input['recaptcha_public_key'] ) ) {
|
212 |
+
$input['recaptcha_public_key'] = sanitize_text_field( $input['recaptcha_public_key'] );
|
213 |
+
}
|
214 |
+
|
215 |
+
//recaptcha_private_key
|
216 |
+
if ( isset( $input['recaptcha_private_key'] ) ) {
|
217 |
+
$input['recaptcha_private_key'] = sanitize_text_field( $input['recaptcha_private_key'] );
|
218 |
+
}
|
219 |
+
|
220 |
+
//sent_message_heading
|
221 |
+
$input['sent_message_heading'] = sanitize_text_field( $input['sent_message_heading'] );
|
222 |
+
|
223 |
+
//sent_message_body
|
224 |
+
$input['sent_message_body'] = sanitize_text_field( $input['sent_message_body'] );
|
225 |
+
|
226 |
+
//message
|
227 |
+
$input['message'] = sanitize_textarea_field( $input['message'] );
|
228 |
+
|
229 |
+
|
230 |
+
//consent message
|
231 |
+
$input['contact-consent-msg'] = sanitize_text_field( $input['contact-consent-msg'] );
|
232 |
+
|
233 |
+
//recipient_emails
|
234 |
+
foreach ( $input['recipient_emails'] as $key => $recipient ) {
|
235 |
+
if ( ! filter_var( $input['recipient_emails'][ $key ] ) ) {
|
236 |
+
unset( $input['recipient_emails'][ $key ] );
|
237 |
+
} else {
|
238 |
+
$input['recipient_emails'][ $key ] = sanitize_email( $input['recipient_emails'][ $key ] );
|
239 |
+
}
|
240 |
+
}
|
241 |
+
|
242 |
+
//from
|
243 |
+
if ( ! filter_var( $input['from-email'], FILTER_VALIDATE_EMAIL ) ) {
|
244 |
+
unset( $input['from-email'] );
|
245 |
+
} else {
|
246 |
+
$input['from-email'] = sanitize_email( $input['from-email'] );
|
247 |
+
}
|
248 |
+
|
249 |
+
//subject
|
250 |
+
$input['subject'] = trim( sanitize_text_field( $input['subject'] ) );
|
251 |
+
if ( empty( $input['subject'] ) ) {
|
252 |
+
unset( $input['subject'] );
|
253 |
+
}
|
254 |
+
|
255 |
+
if ( isset( $_POST['add_recipient'] ) ) {
|
256 |
+
$input['recipient_emails'][] = "";
|
257 |
+
}
|
258 |
+
|
259 |
+
if ( isset( $_POST['remove_recipient'] ) ) {
|
260 |
+
foreach ( $_POST['remove_recipient'] as $key => $element ) {
|
261 |
+
unset( $input['recipient_emails'][ $key ] );
|
262 |
+
}
|
263 |
+
}
|
264 |
+
|
265 |
+
//tidy up the keys
|
266 |
+
$tidiedRecipients = array();
|
267 |
+
foreach ( $input['recipient_emails'] as $recipient ) {
|
268 |
+
$tidiedRecipients[] = $recipient;
|
269 |
+
}
|
270 |
+
$input['recipient_emails'] = $tidiedRecipients;
|
271 |
+
|
272 |
+
|
273 |
+
return $input;
|
274 |
+
}
|
275 |
+
|
276 |
+
public function print_section_info_recaptcha() {
|
277 |
+
print esc_html__( 'Enter your reCAPTCHA settings below :', 'clean-and-simple-contact-form-by-meg-nicholas' );
|
278 |
+
print "<p>" . esc_html__( 'To use reCAPTCHA you must get an API key from', 'clean-and-simple-contact-form-by-meg-nicholas' ) . " <a target='_blank' href='" . csf_RecaptchaV2::$signUpUrl . "'>Google reCAPTCHA</a></p>";
|
279 |
+
}
|
280 |
+
|
281 |
+
public function print_section_info_message() {
|
282 |
+
print esc_html__( 'Enter your message settings below :', 'clean-and-simple-contact-form-by-meg-nicholas' );
|
283 |
+
}
|
284 |
+
|
285 |
+
public function print_section_info_styling() {
|
286 |
+
|
287 |
+
//print 'Enter your styling settings below:';
|
288 |
+
|
289 |
+
}
|
290 |
+
|
291 |
+
public function create_fields(
|
292 |
+
$args
|
293 |
+
) {
|
294 |
+
$fieldname = $args[0];
|
295 |
+
|
296 |
+
switch ( $fieldname ) {
|
297 |
+
case 'use_recaptcha':
|
298 |
+
$checked = cscf_PluginSettings::UseRecaptcha() === true ? 'checked' : '';
|
299 |
+
?><input type="checkbox" <?php echo esc_attr( $checked ); ?> id="use_recaptcha"
|
300 |
+
name="<?php echo esc_attr( CSCF_OPTIONS_KEY ); ?>[use_recaptcha]"><?php
|
301 |
+
break;
|
302 |
+
case 'load_stylesheet':
|
303 |
+
$checked = cscf_PluginSettings::LoadStyleSheet() === true ? 'checked' : '';
|
304 |
+
?><input type="checkbox" <?php echo esc_attr( $checked ); ?> id="load_stylesheet"
|
305 |
+
name="<?php echo esc_attr( CSCF_OPTIONS_KEY ); ?>[load_stylesheet]"><?php
|
306 |
+
break;
|
307 |
+
case 'recaptcha_public_key':
|
308 |
+
$disabled = cscf_PluginSettings::UseRecaptcha() === false ? 'readonly' : '';
|
309 |
+
?><input <?php echo esc_attr( $disabled ); ?> type="text" size="60" id="recaptcha_public_key"
|
310 |
+
name="<?php echo esc_attr( CSCF_OPTIONS_KEY ); ?>[recaptcha_public_key]"
|
311 |
+
value="<?php echo esc_attr( cscf_PluginSettings::PublicKey() ); ?>" /><?php
|
312 |
+
break;
|
313 |
+
case 'recaptcha_private_key':
|
314 |
+
$disabled = cscf_PluginSettings::UseRecaptcha() === false ? 'readonly' : '';
|
315 |
+
?><input <?php echo esc_attr( $disabled ); ?> type="text" size="60" id="recaptcha_private_key"
|
316 |
+
name="<?php echo esc_attr( CSCF_OPTIONS_KEY ); ?>[recaptcha_private_key]"
|
317 |
+
value="<?php echo esc_attr( cscf_PluginSettings::PrivateKey() ); ?>" /><?php
|
318 |
+
break;
|
319 |
+
case 'recipient_emails':
|
320 |
+
?>
|
321 |
+
<ul id="recipients"><?php
|
322 |
+
foreach ( cscf_PluginSettings::RecipientEmails() as $key => $recipientEmail ) {
|
323 |
+
?>
|
324 |
+
<li class="recipient_email" data-element="<?php echo esc_attr($key); ?>">
|
325 |
+
<input class="enter_recipient" type="email" size="50"
|
326 |
+
name="<?php echo esc_attr( CSCF_OPTIONS_KEY ); ?>[recipient_emails][<?php echo esc_attr($key) ?>]"
|
327 |
+
value="<?php echo esc_attr( $recipientEmail ); ?>"/>
|
328 |
+
<input class="add_recipient" title="Add New Recipient" type="submit" name="add_recipient"
|
329 |
+
value="+">
|
330 |
+
<input class="remove_recipient" title="Remove This Recipient" type="submit"
|
331 |
+
name="remove_recipient[<?php echo esc_attr( $key ); ?>]" value="-">
|
332 |
+
</li>
|
333 |
+
|
334 |
+
<?php
|
335 |
+
}
|
336 |
+
?></ul><?php
|
337 |
+
break;
|
338 |
+
case 'confirm-email':
|
339 |
+
$checked = cscf_PluginSettings::ConfirmEmail() == true ? "checked" : "";
|
340 |
+
?><input type="checkbox" <?php echo esc_attr( $checked ); ?> id="confirm-email"
|
341 |
+
name="<?php echo esc_attr( CSCF_OPTIONS_KEY ); ?>[confirm-email]"><?php
|
342 |
+
break;
|
343 |
+
case 'override-from':
|
344 |
+
$checked = cscf_PluginSettings::OverrideFrom() == true ? "checked" : "";
|
345 |
+
?><input type="checkbox" <?php echo esc_attr( $checked ); ?> id="override-from"
|
346 |
+
name="<?php echo esc_attr( CSCF_OPTIONS_KEY ); ?>[override-from]"><?php
|
347 |
+
break;
|
348 |
+
case 'email-sender':
|
349 |
+
$checked = cscf_PluginSettings::EmailToSender() == true ? "checked" : "";
|
350 |
+
?><input type="checkbox" <?php echo esc_attr( $checked ); ?> id="email-sender"
|
351 |
+
name="<?php echo esc_attr( CSCF_OPTIONS_KEY ); ?>[email-sender]"><?php
|
352 |
+
break;
|
353 |
+
case 'contact-consent':
|
354 |
+
$checked = cscf_PluginSettings::ContactConsent() == true ? "checked" : "";
|
355 |
+
?><input type="checkbox" <?php echo esc_attr( $checked ); ?> id="contact-consent"
|
356 |
+
name="<?php echo esc_attr( CSCF_OPTIONS_KEY ); ?>[contact-consent]"><?php
|
357 |
+
break;
|
358 |
+
case 'contact-consent-msg':
|
359 |
+
?><input type="text" size="60" id="contact-consent-msg"
|
360 |
+
name="<?php echo esc_attr( CSCF_OPTIONS_KEY ); ?>[contact-consent-msg]"
|
361 |
+
value="<?php echo esc_attr( cscf_PluginSettings::ContactConsentMsg() ); ?>"><?php
|
362 |
+
break;
|
363 |
+
case 'from-email':
|
364 |
+
$disabled = cscf_PluginSettings::OverrideFrom() === false ? "readonly" : "";
|
365 |
+
?><input <?php echo esc_attr($disabled); ?> type="text" size="60" id="from-email"
|
366 |
+
name="<?php echo esc_attr( CSCF_OPTIONS_KEY ); ?>[from-email]"
|
367 |
+
value="<?php echo esc_attr( cscf_PluginSettings::FromEmail() ); ?>" /><?php
|
368 |
+
break;
|
369 |
+
case 'subject':
|
370 |
+
?><input type="text" size="60" id="subject" name="<?php echo esc_attr( CSCF_OPTIONS_KEY ); ?>[subject]"
|
371 |
+
value="<?php echo esc_attr( cscf_PluginSettings::Subject() ); ?>" /><?php
|
372 |
+
break;
|
373 |
+
case 'sent_message_heading':
|
374 |
+
?><input type="text" size="60" id="sent_message_heading"
|
375 |
+
name="<?php echo esc_attr( CSCF_OPTIONS_KEY ); ?>[sent_message_heading]"
|
376 |
+
value="<?php echo esc_attr( cscf_PluginSettings::SentMessageHeading() ); ?>" /><?php
|
377 |
+
break;
|
378 |
+
case 'sent_message_body':
|
379 |
+
?><textarea cols="63" rows="8"
|
380 |
+
name="<?php echo esc_attr( CSCF_OPTIONS_KEY ); ?>[sent_message_body]"><?php echo esc_attr( cscf_PluginSettings::SentMessageBody() ); ?></textarea><?php
|
381 |
+
break;
|
382 |
+
case 'message':
|
383 |
+
?><textarea cols="63" rows="8"
|
384 |
+
name="<?php echo esc_attr( CSCF_OPTIONS_KEY ); ?>[message]"><?php echo esc_attr( cscf_PluginSettings::Message() ); ?></textarea><?php
|
385 |
+
break;
|
386 |
+
case 'theme':
|
387 |
+
$theme = cscf_PluginSettings::Theme();
|
388 |
+
$disabled = cscf_PluginSettings::UseRecaptcha() == false ? "disabled" : "";
|
389 |
+
?>
|
390 |
+
<select <?php echo esc_attr($disabled); ?> id="theme" name="<?php echo esc_attr( CSCF_OPTIONS_KEY ); ?>[theme]">
|
391 |
+
<option <?php echo ( 'light' == $theme ) ? 'selected' : ''; ?>
|
392 |
+
value="light"><?php esc_html_e( 'Light', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?></option>
|
393 |
+
<option <?php echo ( 'dark' == $theme ) ? 'selected' : ''; ?>
|
394 |
+
value="dark"><?php esc_html_e( 'Dark', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?></option>
|
395 |
+
</select>
|
396 |
+
<?php
|
397 |
+
break;
|
398 |
+
case 'use_client_validation':
|
399 |
+
$checked = cscf_PluginSettings::UseClientValidation() == true ? "checked" : "";
|
400 |
+
?><input type="checkbox" <?php echo esc_attr( $checked ); ?> id="use_client_validation"
|
401 |
+
name="<?php echo esc_attr( CSCF_OPTIONS_KEY ); ?>[use_client_validation]"><?php
|
402 |
+
break;
|
403 |
+
default:
|
404 |
+
break;
|
405 |
+
}
|
406 |
+
}
|
407 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class.view.php
CHANGED
@@ -1,49 +1,48 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
class CSCF_View
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
}
|
48 |
}
|
49 |
|
1 |
<?php
|
2 |
|
3 |
+
class CSCF_View {
|
4 |
+
/**
|
5 |
+
* Path of the view to render
|
6 |
+
*/
|
7 |
+
var $view = '';
|
8 |
+
/**
|
9 |
+
* Variables for the view
|
10 |
+
*/
|
11 |
+
var $vars = array();
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Construct a view from a file in the
|
15 |
+
*/
|
16 |
+
public
|
17 |
+
function __construct(
|
18 |
+
$view
|
19 |
+
) {
|
20 |
+
|
21 |
+
if ( file_exists( CSCF_PLUGIN_DIR . '/views/' . $view . '.view.php' ) ) {
|
22 |
+
$this->view = CSCF_PLUGIN_DIR . '/views/' . $view . '.view.php';
|
23 |
+
} else {
|
24 |
+
wp_die( esc_html__( 'View ' . CSCF_PLUGIN_URL . '/views/' . $view . '.view.php' . ' not found' ) );
|
25 |
+
}
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* set a variable which gets rendered in the view
|
30 |
+
*/
|
31 |
+
public function Set(
|
32 |
+
$name, $value
|
33 |
+
) {
|
34 |
+
$this->vars[ $name ] = $value;
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* render the view
|
39 |
+
*/
|
40 |
+
public function Render() {
|
41 |
+
extract( $this->vars, EXTR_SKIP );
|
42 |
+
ob_start();
|
43 |
+
include $this->view;
|
44 |
+
|
45 |
+
return str_replace( array( '\n', '\r' ), '', ob_get_clean() );
|
46 |
+
}
|
|
|
47 |
}
|
48 |
|
clean-and-simple-contact-form-by-meg-nicholas.php
CHANGED
@@ -1,79 +1,99 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Clean and Simple Contact Form
|
4 |
-
*/
|
5 |
-
|
6 |
-
/*
|
7 |
-
Plugin Name: Clean and Simple Contact Form
|
8 |
-
Plugin URI:
|
9 |
-
Description: A clean and simple contact form with Google reCAPTCHA and Twitter Bootstrap markup.
|
10 |
-
Version: 4.7.
|
11 |
-
Author:
|
12 |
-
Author URI:
|
13 |
-
License: GPLv2 or later
|
14 |
-
Text Domain: clean-and-simple-contact-form
|
15 |
-
Domain Path: /languages
|
16 |
-
*/
|
17 |
-
|
18 |
-
/*
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
if (!defined(
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
if (!defined('
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
if (
|
78 |
-
|
79 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Clean and Simple Contact Form
|
4 |
+
*/
|
5 |
+
|
6 |
+
/*
|
7 |
+
Plugin Name: Clean and Simple Contact Form
|
8 |
+
Plugin URI: https://fullworks.net/productsclean-and-simple-contact-form
|
9 |
+
Description: A clean and simple contact form with Google reCAPTCHA and Twitter Bootstrap markup.
|
10 |
+
Version: 4.7.2
|
11 |
+
Author: Fullworks
|
12 |
+
Author URI: https://fullworks.net
|
13 |
+
License: GPLv2 or later
|
14 |
+
Text Domain: clean-and-simple-contact-form
|
15 |
+
Domain Path: /languages
|
16 |
+
*/
|
17 |
+
|
18 |
+
/*
|
19 |
+
All code up to version 4.7.1 is attributed to
|
20 |
+
Author: Meghan Nicholas
|
21 |
+
Author URI: http://www.megnicholas.com
|
22 |
+
*/
|
23 |
+
|
24 |
+
/*
|
25 |
+
This program is free software; you can redistribute it and/or
|
26 |
+
modify it under the terms of the GNU General Public License
|
27 |
+
as published by the Free Software Foundation; either version 2
|
28 |
+
of the License, or (at your option) any later version.
|
29 |
+
|
30 |
+
This program is distributed in the hope that it will be useful,
|
31 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
32 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
33 |
+
GNU General Public License for more details.
|
34 |
+
|
35 |
+
You should have received a copy of the GNU General Public License
|
36 |
+
along with this program; if not, write to the Free Software
|
37 |
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
38 |
+
*/
|
39 |
+
|
40 |
+
/*
|
41 |
+
* @package Main
|
42 |
+
*/
|
43 |
+
require 'shortcodes/contact-form.php';
|
44 |
+
require 'class.cscf.php';
|
45 |
+
require 'class.cscf_pluginsettings.php';
|
46 |
+
require 'class.cscf_settings.php';
|
47 |
+
require 'class.cscf_contact.php';
|
48 |
+
require 'class.view.php';
|
49 |
+
require 'class.cscf_filters.php';
|
50 |
+
require 'ajax.php';
|
51 |
+
require 'recaptchav2.php';
|
52 |
+
|
53 |
+
if ( ! defined( 'CSCF_THEME_DIR' ) ) {
|
54 |
+
define( 'CSCF_THEME_DIR', ABSPATH . 'wp-content/themes/' . get_template() );
|
55 |
+
}
|
56 |
+
|
57 |
+
if ( ! defined( 'CSCF_PLUGIN_NAME' ) ) {
|
58 |
+
define( 'CSCF_PLUGIN_NAME', 'clean-and-simple-contact-form-by-meg-nicholas' );
|
59 |
+
}
|
60 |
+
|
61 |
+
if ( ! defined( 'CSCF_PLUGIN_DIR' ) ) {
|
62 |
+
define( 'CSCF_PLUGIN_DIR', WP_PLUGIN_DIR . '/' . CSCF_PLUGIN_NAME );
|
63 |
+
}
|
64 |
+
|
65 |
+
if ( ! defined( 'CSCF_PLUGIN_URL' ) ) {
|
66 |
+
define( 'CSCF_PLUGIN_URL', WP_PLUGIN_URL . '/' . CSCF_PLUGIN_NAME );
|
67 |
+
}
|
68 |
+
|
69 |
+
if ( ! defined( 'CSCF_VERSION_KEY' ) ) {
|
70 |
+
define( 'CSCF_VERSION_KEY', 'cscf_version' );
|
71 |
+
}
|
72 |
+
|
73 |
+
if ( ! defined( 'CSCF_VERSION_NUM' ) ) {
|
74 |
+
define( 'CSCF_VERSION_NUM', '4.7.2' );
|
75 |
+
}
|
76 |
+
|
77 |
+
if ( ! defined( 'CSCF_OPTIONS_KEY' ) ) {
|
78 |
+
define( 'CSCF_OPTIONS_KEY', 'cscf_options' );
|
79 |
+
}
|
80 |
+
|
81 |
+
$cscf = new cscf();
|
82 |
+
|
83 |
+
/*get the current version and update options to the new option*/
|
84 |
+
$old_version = get_option( CSCF_VERSION_KEY );
|
85 |
+
update_option( CSCF_VERSION_KEY, CSCF_VERSION_NUM );
|
86 |
+
|
87 |
+
/*If this is a new installation then set some defaults*/
|
88 |
+
if ( false == $old_version ) {
|
89 |
+
$options = get_option( CSCF_OPTIONS_KEY );
|
90 |
+
$options['use_client_validation'] = true;
|
91 |
+
$options['load_stylesheet'] = true;
|
92 |
+
$options['confirm-email'] = true;
|
93 |
+
update_option( CSCF_OPTIONS_KEY, $options );
|
94 |
+
}
|
95 |
+
|
96 |
+
/*if necessary do an upgrade*/
|
97 |
+
if ( $old_version < CSCF_VERSION_NUM ) {
|
98 |
+
$cscf->Upgrade( $old_version );
|
99 |
+
}
|
images/managewp.png
DELETED
Binary file
|
js/jquery.validate.js
CHANGED
@@ -1,14 +1,27 @@
|
|
1 |
-
/*!
|
2 |
-
*
|
3 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
|
5 |
-
(
|
6 |
|
7 |
-
|
8 |
-
// http://docs.jquery.com/Plugins/Validation/validate
|
9 |
validate: function( options ) {
|
10 |
|
11 |
-
//
|
12 |
if ( !this.length ) {
|
13 |
if ( options && options.debug && window.console ) {
|
14 |
console.warn( "Nothing selected, can't validate, returning nothing." );
|
@@ -16,8 +29,8 @@ $.extend($.fn, {
|
|
16 |
return;
|
17 |
}
|
18 |
|
19 |
-
//
|
20 |
-
var validator = $.data( this[0], "validator" );
|
21 |
if ( validator ) {
|
22 |
return validator;
|
23 |
}
|
@@ -25,45 +38,67 @@ $.extend($.fn, {
|
|
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.
|
34 |
-
|
35 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
}
|
37 |
-
|
38 |
-
|
|
|
39 |
validator.cancelSubmit = true;
|
40 |
}
|
41 |
-
});
|
42 |
|
43 |
-
//
|
44 |
-
this.
|
45 |
if ( validator.settings.debug ) {
|
46 |
-
|
|
|
47 |
event.preventDefault();
|
48 |
}
|
|
|
49 |
function handle() {
|
50 |
-
var hidden;
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
hidden.remove();
|
60 |
}
|
|
|
|
|
|
|
61 |
return false;
|
62 |
}
|
63 |
return true;
|
64 |
}
|
65 |
|
66 |
-
//
|
67 |
if ( validator.cancelSubmit ) {
|
68 |
validator.cancelSubmit = false;
|
69 |
return handle();
|
@@ -78,188 +113,257 @@ $.extend($.fn, {
|
|
78 |
validator.focusInvalid();
|
79 |
return false;
|
80 |
}
|
81 |
-
});
|
82 |
}
|
83 |
|
84 |
return validator;
|
85 |
},
|
86 |
-
|
|
|
87 |
valid: function() {
|
88 |
-
|
89 |
-
|
|
|
|
|
90 |
} else {
|
91 |
-
|
92 |
-
|
93 |
-
this.
|
94 |
-
|
95 |
-
|
96 |
-
|
|
|
|
|
|
|
|
|
97 |
}
|
|
|
98 |
},
|
99 |
-
|
100 |
-
|
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 |
-
|
115 |
-
|
116 |
-
|
117 |
-
switch(command) {
|
118 |
case "add":
|
119 |
-
$.extend(existingRules, $.validator.normalizeRule(argument));
|
120 |
-
|
|
|
|
|
|
|
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 |
-
|
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 |
-
|
140 |
$.extend(
|
141 |
{},
|
142 |
-
$.validator.classRules(element),
|
143 |
-
$.validator.attributeRules(element),
|
144 |
-
$.validator.dataRules(element),
|
145 |
-
$.validator.staticRules(element)
|
146 |
-
), element);
|
147 |
|
148 |
-
//
|
149 |
if ( data.required ) {
|
150 |
-
|
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 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
214 |
this.lastActive = element;
|
215 |
|
216 |
-
//
|
217 |
-
if ( this.settings.focusCleanup
|
218 |
if ( this.settings.unhighlight ) {
|
219 |
this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
|
220 |
}
|
221 |
-
this.
|
222 |
}
|
223 |
},
|
224 |
-
onfocusout: function( element
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
231 |
return;
|
232 |
-
} else if ( element.name in this.submitted || element
|
233 |
-
this.element(element);
|
234 |
}
|
235 |
},
|
236 |
-
onclick: function( element
|
237 |
-
|
|
|
238 |
if ( element.name in this.submitted ) {
|
239 |
-
this.element(element);
|
240 |
-
|
241 |
-
//
|
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 |
-
//
|
263 |
setDefaults: function( settings ) {
|
264 |
$.extend( $.validator.defaults, settings );
|
265 |
},
|
@@ -273,14 +377,14 @@ $.extend($.validator, {
|
|
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,
|
@@ -288,9 +392,9 @@ $.extend($.validator, {
|
|
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;
|
@@ -298,48 +402,68 @@ $.extend($.validator, {
|
|
298 |
this.invalid = {};
|
299 |
this.reset();
|
300 |
|
301 |
-
var
|
302 |
-
|
|
|
|
|
303 |
if ( typeof value === "string" ) {
|
304 |
-
value = value.split(/\s/);
|
305 |
}
|
306 |
-
$.each(value, function( index, name ) {
|
307 |
-
groups[name] = key;
|
308 |
-
});
|
309 |
-
});
|
310 |
-
|
311 |
-
$.each(rules, function( key, value ) {
|
312 |
-
rules[key] = $.validator.normalizeRule(value);
|
313 |
-
});
|
314 |
-
|
315 |
-
function delegate(event) {
|
316 |
-
var
|
317 |
-
|
318 |
-
|
319 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
320 |
}
|
321 |
}
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
"[type='
|
326 |
-
"[type='
|
327 |
-
"[type='range'], [type='color'] "
|
328 |
-
"
|
329 |
-
|
|
|
|
|
|
|
330 |
|
331 |
if ( this.settings.invalidHandler ) {
|
332 |
-
$(this.currentForm).
|
333 |
}
|
334 |
},
|
335 |
|
336 |
-
//
|
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();
|
@@ -347,48 +471,81 @@ $.extend($.validator, {
|
|
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 |
-
//
|
357 |
element: function( element ) {
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
|
|
365 |
} else {
|
366 |
-
this.
|
367 |
-
|
368 |
-
|
369 |
-
//
|
370 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
371 |
}
|
372 |
-
|
373 |
return result;
|
374 |
},
|
375 |
|
376 |
-
//
|
377 |
showErrors: function( errors ) {
|
378 |
if ( errors ) {
|
379 |
-
|
|
|
|
|
380 |
$.extend( this.errorMap, errors );
|
381 |
-
this.errorList =
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
//
|
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 );
|
@@ -397,32 +554,64 @@ $.extend($.validator, {
|
|
397 |
}
|
398 |
},
|
399 |
|
400 |
-
//
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
410 |
},
|
411 |
|
412 |
numberOfInvalids: function() {
|
413 |
-
return this.objectLength(this.invalid);
|
414 |
},
|
415 |
|
416 |
objectLength: function( obj ) {
|
417 |
-
|
418 |
-
|
419 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
420 |
}
|
421 |
return count;
|
422 |
},
|
423 |
|
424 |
hideErrors: function() {
|
425 |
-
this.
|
|
|
|
|
|
|
|
|
|
|
426 |
},
|
427 |
|
428 |
valid: function() {
|
@@ -436,64 +625,84 @@ $.extend($.validator, {
|
|
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 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
|
|
|
|
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 |
-
//
|
462 |
-
return $(this.currentForm)
|
463 |
-
.find("input, select, textarea")
|
464 |
-
.not(":submit, :reset, :image,
|
465 |
.not( this.settings.ignore )
|
466 |
-
.filter(function() {
|
467 |
-
|
468 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
469 |
}
|
470 |
|
471 |
-
//
|
472 |
-
if (
|
473 |
return false;
|
474 |
}
|
475 |
|
476 |
-
rulesCache[
|
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.
|
487 |
-
return $(this.settings.errorElement + "." + errorClass, this.errorContext);
|
488 |
},
|
489 |
|
490 |
-
|
491 |
this.successList = [];
|
492 |
this.errorList = [];
|
493 |
this.errorMap = {};
|
494 |
-
this.toShow = $([]);
|
495 |
-
this.toHide = $([]);
|
496 |
-
|
|
|
|
|
|
|
|
|
497 |
},
|
498 |
|
499 |
prepareForm: function() {
|
@@ -503,19 +712,53 @@ $.extend($.validator, {
|
|
503 |
|
504 |
prepareElement: function( element ) {
|
505 |
this.reset();
|
506 |
-
this.toHide = this.errorsFor(element);
|
507 |
},
|
508 |
|
509 |
elementValue: function( element ) {
|
510 |
-
var
|
511 |
-
|
|
|
|
|
512 |
|
513 |
if ( type === "radio" || type === "checkbox" ) {
|
514 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
515 |
}
|
516 |
|
517 |
if ( typeof val === "string" ) {
|
518 |
-
return val.replace(/\r/g, "");
|
519 |
}
|
520 |
return val;
|
521 |
},
|
@@ -523,27 +766,47 @@ $.extend($.validator, {
|
|
523 |
check: function( element ) {
|
524 |
element = this.validationTargetFor( this.clean( element ) );
|
525 |
|
526 |
-
var rules = $(element).rules()
|
527 |
-
|
528 |
-
|
529 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
530 |
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
|
535 |
-
|
|
|
|
|
|
|
536 |
|
537 |
-
//
|
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 |
|
@@ -551,70 +814,94 @@ $.extend($.validator, {
|
|
551 |
this.formatAndAdd( element, rule );
|
552 |
return false;
|
553 |
}
|
554 |
-
} catch(e) {
|
555 |
if ( this.settings.debug && window.console ) {
|
556 |
-
console.log( "Exception
|
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 |
-
//
|
571 |
// specified in the element's HTML5 data attribute
|
|
|
572 |
customDataMessage: function( element, method ) {
|
573 |
-
return $(element).data("msg
|
|
|
574 |
},
|
575 |
|
576 |
-
//
|
577 |
customMessage: function( name, method ) {
|
578 |
-
var m = this.settings.messages[name];
|
579 |
-
return m && (m.constructor === String ? m : m[method]);
|
580 |
},
|
581 |
|
582 |
-
//
|
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 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
|
|
|
|
|
|
602 |
|
603 |
-
|
604 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 ) {
|
@@ -625,9 +912,9 @@ $.extend($.validator, {
|
|
625 |
},
|
626 |
|
627 |
defaultShowErrors: function() {
|
628 |
-
var i, elements;
|
629 |
-
for ( i = 0; this.errorList[i]; i++ ) {
|
630 |
-
|
631 |
if ( this.settings.highlight ) {
|
632 |
this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
|
633 |
}
|
@@ -637,13 +924,13 @@ $.extend($.validator, {
|
|
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 );
|
@@ -652,207 +939,332 @@ $.extend($.validator, {
|
|
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
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
671 |
} else {
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
.
|
676 |
-
.
|
|
|
|
|
|
|
|
|
677 |
if ( this.settings.wrapper ) {
|
678 |
-
|
|
|
679 |
// actually showing the wrapped element is handled elsewhere
|
680 |
-
|
681 |
}
|
682 |
-
if (
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
687 |
}
|
688 |
}
|
689 |
}
|
690 |
if ( !message && this.settings.success ) {
|
691 |
-
|
692 |
if ( typeof this.settings.success === "string" ) {
|
693 |
-
|
694 |
} else {
|
695 |
-
this.settings.success(
|
696 |
}
|
697 |
}
|
698 |
-
this.toShow = this.toShow.add(
|
699 |
},
|
700 |
|
701 |
errorsFor: function( element ) {
|
702 |
-
var name = this.idOrName(element)
|
703 |
-
|
704 |
-
|
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 |
-
|
714 |
-
|
715 |
-
|
|
|
716 |
}
|
717 |
-
|
|
|
|
|
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
|
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.
|
|
|
765 |
}
|
766 |
},
|
767 |
|
768 |
stopRequest: function( element, valid ) {
|
769 |
this.pendingRequest--;
|
770 |
-
|
|
|
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 |
-
|
|
|
|
|
786 |
old: null,
|
787 |
valid: true,
|
788 |
-
message: this.defaultMessage( element,
|
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 |
-
|
|
|
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 |
-
|
|
|
|
|
829 |
|
830 |
-
for (
|
831 |
-
var value;
|
832 |
|
833 |
-
//
|
834 |
if ( method === "required" ) {
|
835 |
-
value =
|
|
|
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 |
-
|
|
|
842 |
value = !!value;
|
843 |
} else {
|
844 |
-
value = $element.attr(method);
|
845 |
}
|
846 |
|
847 |
-
|
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 |
|
@@ -860,84 +1272,96 @@ $.extend($.validator, {
|
|
860 |
},
|
861 |
|
862 |
dataRules: function( element ) {
|
863 |
-
var
|
864 |
-
|
865 |
-
|
866 |
-
value
|
867 |
-
|
868 |
-
|
|
|
|
|
|
|
|
|
|
|
869 |
}
|
|
|
|
|
870 |
}
|
871 |
return rules;
|
872 |
},
|
873 |
|
874 |
staticRules: function( element ) {
|
875 |
-
var rules = {}
|
876 |
-
|
|
|
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 |
-
|
885 |
-
|
886 |
-
|
|
|
|
|
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 |
-
|
|
|
905 |
}
|
906 |
}
|
907 |
-
});
|
908 |
|
909 |
-
//
|
910 |
-
$.each(rules, function( rule, parameter ) {
|
911 |
-
rules[rule] =
|
912 |
-
});
|
913 |
|
914 |
-
//
|
915 |
-
$.each([
|
916 |
-
if ( rules[this] ) {
|
917 |
-
rules[this] = Number(rules[this]);
|
918 |
}
|
919 |
-
});
|
920 |
-
$.each([
|
921 |
var parts;
|
922 |
-
if ( rules[this] ) {
|
923 |
-
if (
|
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 |
-
|
934 |
-
|
935 |
-
|
|
|
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 |
}
|
@@ -950,258 +1374,284 @@ $.extend($.validator, {
|
|
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 |
-
//
|
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 |
-
//
|
973 |
required: function( value, element, param ) {
|
974 |
-
|
975 |
-
|
|
|
976 |
return "dependency-mismatch";
|
977 |
}
|
978 |
if ( element.nodeName.toLowerCase() === "select" ) {
|
979 |
-
|
980 |
-
|
|
|
981 |
return val && val.length > 0;
|
982 |
}
|
983 |
-
if ( this.checkable(element) ) {
|
984 |
-
return this.getLength(value, element) > 0;
|
985 |
}
|
986 |
-
return
|
987 |
},
|
988 |
|
989 |
-
//
|
990 |
-
|
991 |
-
if ( this.optional(element) ) {
|
992 |
-
return "dependency-mismatch";
|
993 |
-
}
|
994 |
|
995 |
-
|
996 |
-
|
997 |
-
|
998 |
-
|
999 |
-
|
1000 |
-
|
1001 |
|
1002 |
-
|
|
|
1003 |
|
1004 |
-
|
1005 |
-
|
1006 |
-
|
|
|
|
|
|
|
1007 |
|
1008 |
-
|
1009 |
-
|
1010 |
-
|
1011 |
-
|
1012 |
-
|
1013 |
-
|
1014 |
-
|
1015 |
-
|
1016 |
-
|
1017 |
-
|
1018 |
-
|
1019 |
-
|
1020 |
-
|
1021 |
-
|
1022 |
-
|
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 |
-
|
1040 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1041 |
},
|
1042 |
|
1043 |
-
//
|
1044 |
minlength: function( value, element, param ) {
|
1045 |
-
var length =
|
1046 |
-
return this.optional(element) || length >= param;
|
1047 |
},
|
1048 |
|
1049 |
-
//
|
1050 |
maxlength: function( value, element, param ) {
|
1051 |
-
var length =
|
1052 |
-
return this.optional(element) || length <= param;
|
1053 |
},
|
1054 |
|
1055 |
-
//
|
1056 |
rangelength: function( value, element, param ) {
|
1057 |
-
var length =
|
1058 |
-
return this.optional(element) || ( length >= param[0] && length <= param[1] );
|
1059 |
},
|
1060 |
|
1061 |
-
//
|
1062 |
min: function( value, element, param ) {
|
1063 |
-
return this.optional(element) || value >= param;
|
1064 |
},
|
1065 |
|
1066 |
-
//
|
1067 |
max: function( value, element, param ) {
|
1068 |
-
return this.optional(element) || value <= param;
|
1069 |
},
|
1070 |
|
1071 |
-
//
|
1072 |
range: function( value, element, param ) {
|
1073 |
-
return this.optional(element) || ( value >= param[0] && value <= param[1] );
|
1074 |
},
|
1075 |
|
1076 |
-
//
|
1077 |
-
|
1078 |
-
|
1079 |
-
|
1080 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1081 |
|
1082 |
-
|
1083 |
-
|
1084 |
-
|
1085 |
-
|
1086 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1087 |
|
1088 |
-
|
1089 |
-
date: function( value, element ) {
|
1090 |
-
return this.optional(element) || !/Invalid|NaN/.test(new Date(value).toString());
|
1091 |
-
},
|
1092 |
|
1093 |
-
|
1094 |
-
|
1095 |
-
|
1096 |
-
|
1097 |
|
1098 |
-
|
1099 |
-
number: function( value, element ) {
|
1100 |
-
return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value);
|
1101 |
},
|
1102 |
|
1103 |
-
//
|
1104 |
-
|
1105 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1106 |
},
|
1107 |
|
1108 |
-
//
|
1109 |
-
|
1110 |
-
|
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 |
-
|
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 |
-
|
1137 |
-
|
1138 |
|
1139 |
-
|
1140 |
-
|
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 |
-
|
1150 |
-
|
1151 |
|
1152 |
-
|
|
|
|
|
|
|
|
|
1153 |
|
1154 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1155 |
|
1156 |
-
|
1157 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1158 |
|
1159 |
-
}
|
1160 |
|
1161 |
-
//
|
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 |
-
|
1165 |
-
|
1166 |
-
|
1167 |
-
|
1168 |
-
|
1169 |
-
|
1170 |
-
|
1171 |
-
|
1172 |
-
|
1173 |
-
|
1174 |
-
pendingRequests[port]
|
1175 |
}
|
1176 |
-
|
1177 |
-
|
1178 |
-
|
1179 |
-
|
1180 |
-
|
1181 |
-
|
1182 |
-
|
1183 |
-
|
1184 |
-
|
1185 |
-
|
1186 |
-
|
1187 |
-
|
|
|
1188 |
}
|
1189 |
-
|
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 |
-
}
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* jQuery Validation Plugin v1.19.3
|
3 |
+
*
|
4 |
+
* https://jqueryvalidation.org/
|
5 |
+
*
|
6 |
+
* Copyright (c) 2021 Jörn Zaefferer
|
7 |
+
* Released under the MIT license
|
8 |
+
*/
|
9 |
+
(function( factory ) {
|
10 |
+
if ( typeof define === "function" && define.amd ) {
|
11 |
+
define( ["jquery"], factory );
|
12 |
+
} else if (typeof module === "object" && module.exports) {
|
13 |
+
module.exports = factory( require( "jquery" ) );
|
14 |
+
} else {
|
15 |
+
factory( jQuery );
|
16 |
+
}
|
17 |
+
}(function( $ ) {
|
18 |
|
19 |
+
$.extend( $.fn, {
|
20 |
|
21 |
+
// https://jqueryvalidation.org/validate/
|
|
|
22 |
validate: function( options ) {
|
23 |
|
24 |
+
// If nothing is selected, return nothing; can't chain anyway
|
25 |
if ( !this.length ) {
|
26 |
if ( options && options.debug && window.console ) {
|
27 |
console.warn( "Nothing selected, can't validate, returning nothing." );
|
29 |
return;
|
30 |
}
|
31 |
|
32 |
+
// Check if a validator for this form was already created
|
33 |
+
var validator = $.data( this[ 0 ], "validator" );
|
34 |
if ( validator ) {
|
35 |
return validator;
|
36 |
}
|
38 |
// Add novalidate tag if HTML5.
|
39 |
this.attr( "novalidate", "novalidate" );
|
40 |
|
41 |
+
validator = new $.validator( options, this[ 0 ] );
|
42 |
+
$.data( this[ 0 ], "validator", validator );
|
43 |
|
44 |
if ( validator.settings.onsubmit ) {
|
45 |
|
46 |
+
this.on( "click.validate", ":submit", function( event ) {
|
47 |
+
|
48 |
+
// Track the used submit button to properly handle scripted
|
49 |
+
// submits later.
|
50 |
+
validator.submitButton = event.currentTarget;
|
51 |
+
|
52 |
+
// Allow suppressing validation by adding a cancel class to the submit button
|
53 |
+
if ( $( this ).hasClass( "cancel" ) ) {
|
54 |
+
validator.cancelSubmit = true;
|
55 |
}
|
56 |
+
|
57 |
+
// Allow suppressing validation by adding the html5 formnovalidate attribute to the submit button
|
58 |
+
if ( $( this ).attr( "formnovalidate" ) !== undefined ) {
|
59 |
validator.cancelSubmit = true;
|
60 |
}
|
61 |
+
} );
|
62 |
|
63 |
+
// Validate the form on submit
|
64 |
+
this.on( "submit.validate", function( event ) {
|
65 |
if ( validator.settings.debug ) {
|
66 |
+
|
67 |
+
// Prevent form submit to be able to see console output
|
68 |
event.preventDefault();
|
69 |
}
|
70 |
+
|
71 |
function handle() {
|
72 |
+
var hidden, result;
|
73 |
+
|
74 |
+
// Insert a hidden input as a replacement for the missing submit button
|
75 |
+
// The hidden input is inserted in two cases:
|
76 |
+
// - A user defined a `submitHandler`
|
77 |
+
// - There was a pending request due to `remote` method and `stopRequest()`
|
78 |
+
// was called to submit the form in case it's valid
|
79 |
+
if ( validator.submitButton && ( validator.settings.submitHandler || validator.formSubmitted ) ) {
|
80 |
+
hidden = $( "<input type='hidden'/>" )
|
81 |
+
.attr( "name", validator.submitButton.name )
|
82 |
+
.val( $( validator.submitButton ).val() )
|
83 |
+
.appendTo( validator.currentForm );
|
84 |
+
}
|
85 |
+
|
86 |
+
if ( validator.settings.submitHandler && !validator.settings.debug ) {
|
87 |
+
result = validator.settings.submitHandler.call( validator, validator.currentForm, event );
|
88 |
+
if ( hidden ) {
|
89 |
+
|
90 |
+
// And clean up afterwards; thanks to no-block-scope, hidden can be referenced
|
91 |
hidden.remove();
|
92 |
}
|
93 |
+
if ( result !== undefined ) {
|
94 |
+
return result;
|
95 |
+
}
|
96 |
return false;
|
97 |
}
|
98 |
return true;
|
99 |
}
|
100 |
|
101 |
+
// Prevent submit for invalid forms or custom submit handlers
|
102 |
if ( validator.cancelSubmit ) {
|
103 |
validator.cancelSubmit = false;
|
104 |
return handle();
|
113 |
validator.focusInvalid();
|
114 |
return false;
|
115 |
}
|
116 |
+
} );
|
117 |
}
|
118 |
|
119 |
return validator;
|
120 |
},
|
121 |
+
|
122 |
+
// https://jqueryvalidation.org/valid/
|
123 |
valid: function() {
|
124 |
+
var valid, validator, errorList;
|
125 |
+
|
126 |
+
if ( $( this[ 0 ] ).is( "form" ) ) {
|
127 |
+
valid = this.validate().form();
|
128 |
} else {
|
129 |
+
errorList = [];
|
130 |
+
valid = true;
|
131 |
+
validator = $( this[ 0 ].form ).validate();
|
132 |
+
this.each( function() {
|
133 |
+
valid = validator.element( this ) && valid;
|
134 |
+
if ( !valid ) {
|
135 |
+
errorList = errorList.concat( validator.errorList );
|
136 |
+
}
|
137 |
+
} );
|
138 |
+
validator.errorList = errorList;
|
139 |
}
|
140 |
+
return valid;
|
141 |
},
|
142 |
+
|
143 |
+
// https://jqueryvalidation.org/rules/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
144 |
rules: function( command, argument ) {
|
145 |
+
var element = this[ 0 ],
|
146 |
+
isContentEditable = typeof this.attr( "contenteditable" ) !== "undefined" && this.attr( "contenteditable" ) !== "false",
|
147 |
+
settings, staticRules, existingRules, data, param, filtered;
|
148 |
+
|
149 |
+
// If nothing is selected, return empty object; can't chain anyway
|
150 |
+
if ( element == null ) {
|
151 |
+
return;
|
152 |
+
}
|
153 |
+
|
154 |
+
if ( !element.form && isContentEditable ) {
|
155 |
+
element.form = this.closest( "form" )[ 0 ];
|
156 |
+
element.name = this.attr( "name" );
|
157 |
+
}
|
158 |
+
|
159 |
+
if ( element.form == null ) {
|
160 |
+
return;
|
161 |
+
}
|
162 |
|
163 |
if ( command ) {
|
164 |
+
settings = $.data( element.form, "validator" ).settings;
|
165 |
+
staticRules = settings.rules;
|
166 |
+
existingRules = $.validator.staticRules( element );
|
167 |
+
switch ( command ) {
|
168 |
case "add":
|
169 |
+
$.extend( existingRules, $.validator.normalizeRule( argument ) );
|
170 |
+
|
171 |
+
// Remove messages from rules, but allow them to be set separately
|
172 |
+
delete existingRules.messages;
|
173 |
+
staticRules[ element.name ] = existingRules;
|
174 |
if ( argument.messages ) {
|
175 |
+
settings.messages[ element.name ] = $.extend( settings.messages[ element.name ], argument.messages );
|
176 |
}
|
177 |
break;
|
178 |
case "remove":
|
179 |
if ( !argument ) {
|
180 |
+
delete staticRules[ element.name ];
|
181 |
return existingRules;
|
182 |
}
|
183 |
+
filtered = {};
|
184 |
+
$.each( argument.split( /\s/ ), function( index, method ) {
|
185 |
+
filtered[ method ] = existingRules[ method ];
|
186 |
+
delete existingRules[ method ];
|
187 |
+
} );
|
188 |
return filtered;
|
189 |
}
|
190 |
}
|
191 |
|
192 |
+
data = $.validator.normalizeRules(
|
193 |
$.extend(
|
194 |
{},
|
195 |
+
$.validator.classRules( element ),
|
196 |
+
$.validator.attributeRules( element ),
|
197 |
+
$.validator.dataRules( element ),
|
198 |
+
$.validator.staticRules( element )
|
199 |
+
), element );
|
200 |
|
201 |
+
// Make sure required is at front
|
202 |
if ( data.required ) {
|
203 |
+
param = data.required;
|
204 |
delete data.required;
|
205 |
+
data = $.extend( { required: param }, data );
|
206 |
+
}
|
207 |
+
|
208 |
+
// Make sure remote is at back
|
209 |
+
if ( data.remote ) {
|
210 |
+
param = data.remote;
|
211 |
+
delete data.remote;
|
212 |
+
data = $.extend( data, { remote: param } );
|
213 |
}
|
214 |
|
215 |
return data;
|
216 |
}
|
217 |
+
} );
|
218 |
+
|
219 |
+
// JQuery trim is deprecated, provide a trim method based on String.prototype.trim
|
220 |
+
var trim = function( str ) {
|
221 |
+
|
222 |
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trim#Polyfill
|
223 |
+
return str.replace( /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, "" );
|
224 |
+
};
|
225 |
|
226 |
// Custom selectors
|
227 |
+
$.extend( $.expr.pseudos || $.expr[ ":" ], { // '|| $.expr[ ":" ]' here enables backwards compatibility to jQuery 1.7. Can be removed when dropping jQ 1.7.x support
|
228 |
+
|
229 |
+
// https://jqueryvalidation.org/blank-selector/
|
230 |
+
blank: function( a ) {
|
231 |
+
return !trim( "" + $( a ).val() );
|
232 |
+
},
|
233 |
+
|
234 |
+
// https://jqueryvalidation.org/filled-selector/
|
235 |
+
filled: function( a ) {
|
236 |
+
var val = $( a ).val();
|
237 |
+
return val !== null && !!trim( "" + val );
|
238 |
+
},
|
239 |
+
|
240 |
+
// https://jqueryvalidation.org/unchecked-selector/
|
241 |
+
unchecked: function( a ) {
|
242 |
+
return !$( a ).prop( "checked" );
|
243 |
+
}
|
244 |
+
} );
|
245 |
+
|
246 |
+
// Constructor for validator
|
247 |
$.validator = function( options, form ) {
|
248 |
this.settings = $.extend( true, {}, $.validator.defaults, options );
|
249 |
this.currentForm = form;
|
250 |
this.init();
|
251 |
};
|
252 |
|
253 |
+
// https://jqueryvalidation.org/jQuery.validator.format/
|
254 |
$.validator.format = function( source, params ) {
|
255 |
if ( arguments.length === 1 ) {
|
256 |
return function() {
|
257 |
+
var args = $.makeArray( arguments );
|
258 |
+
args.unshift( source );
|
259 |
return $.validator.format.apply( this, args );
|
260 |
};
|
261 |
}
|
262 |
+
if ( params === undefined ) {
|
263 |
+
return source;
|
264 |
+
}
|
265 |
if ( arguments.length > 2 && params.constructor !== Array ) {
|
266 |
+
params = $.makeArray( arguments ).slice( 1 );
|
267 |
}
|
268 |
if ( params.constructor !== Array ) {
|
269 |
params = [ params ];
|
270 |
}
|
271 |
+
$.each( params, function( i, n ) {
|
272 |
+
source = source.replace( new RegExp( "\\{" + i + "\\}", "g" ), function() {
|
273 |
return n;
|
274 |
+
} );
|
275 |
+
} );
|
276 |
return source;
|
277 |
};
|
278 |
|
279 |
+
$.extend( $.validator, {
|
280 |
|
281 |
defaults: {
|
282 |
messages: {},
|
283 |
groups: {},
|
284 |
rules: {},
|
285 |
errorClass: "error",
|
286 |
+
pendingClass: "pending",
|
287 |
validClass: "valid",
|
288 |
errorElement: "label",
|
289 |
+
focusCleanup: false,
|
290 |
focusInvalid: true,
|
291 |
+
errorContainer: $( [] ),
|
292 |
+
errorLabelContainer: $( [] ),
|
293 |
onsubmit: true,
|
294 |
ignore: ":hidden",
|
295 |
ignoreTitle: false,
|
296 |
+
onfocusin: function( element ) {
|
297 |
this.lastActive = element;
|
298 |
|
299 |
+
// Hide error label and remove error class on focus if enabled
|
300 |
+
if ( this.settings.focusCleanup ) {
|
301 |
if ( this.settings.unhighlight ) {
|
302 |
this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
|
303 |
}
|
304 |
+
this.hideThese( this.errorsFor( element ) );
|
305 |
}
|
306 |
},
|
307 |
+
onfocusout: function( element ) {
|
308 |
+
if ( !this.checkable( element ) && ( element.name in this.submitted || !this.optional( element ) ) ) {
|
309 |
+
this.element( element );
|
310 |
}
|
311 |
},
|
312 |
onkeyup: function( element, event ) {
|
313 |
+
|
314 |
+
// Avoid revalidate the field when pressing one of the following keys
|
315 |
+
// Shift => 16
|
316 |
+
// Ctrl => 17
|
317 |
+
// Alt => 18
|
318 |
+
// Caps lock => 20
|
319 |
+
// End => 35
|
320 |
+
// Home => 36
|
321 |
+
// Left arrow => 37
|
322 |
+
// Up arrow => 38
|
323 |
+
// Right arrow => 39
|
324 |
+
// Down arrow => 40
|
325 |
+
// Insert => 45
|
326 |
+
// Num lock => 144
|
327 |
+
// AltGr key => 225
|
328 |
+
var excludedKeys = [
|
329 |
+
16, 17, 18, 20, 35, 36, 37,
|
330 |
+
38, 39, 40, 45, 144, 225
|
331 |
+
];
|
332 |
+
|
333 |
+
if ( event.which === 9 && this.elementValue( element ) === "" || $.inArray( event.keyCode, excludedKeys ) !== -1 ) {
|
334 |
return;
|
335 |
+
} else if ( element.name in this.submitted || element.name in this.invalid ) {
|
336 |
+
this.element( element );
|
337 |
}
|
338 |
},
|
339 |
+
onclick: function( element ) {
|
340 |
+
|
341 |
+
// Click on selects, radiobuttons and checkboxes
|
342 |
if ( element.name in this.submitted ) {
|
343 |
+
this.element( element );
|
344 |
+
|
345 |
+
// Or option elements, check parent select in that case
|
346 |
+
} else if ( element.parentNode.name in this.submitted ) {
|
347 |
+
this.element( element.parentNode );
|
348 |
}
|
349 |
},
|
350 |
highlight: function( element, errorClass, validClass ) {
|
351 |
if ( element.type === "radio" ) {
|
352 |
+
this.findByName( element.name ).addClass( errorClass ).removeClass( validClass );
|
353 |
} else {
|
354 |
+
$( element ).addClass( errorClass ).removeClass( validClass );
|
355 |
}
|
356 |
},
|
357 |
unhighlight: function( element, errorClass, validClass ) {
|
358 |
if ( element.type === "radio" ) {
|
359 |
+
this.findByName( element.name ).removeClass( errorClass ).addClass( validClass );
|
360 |
} else {
|
361 |
+
$( element ).removeClass( errorClass ).addClass( validClass );
|
362 |
}
|
363 |
}
|
364 |
},
|
365 |
|
366 |
+
// https://jqueryvalidation.org/jQuery.validator.setDefaults/
|
367 |
setDefaults: function( settings ) {
|
368 |
$.extend( $.validator.defaults, settings );
|
369 |
},
|
377 |
dateISO: "Please enter a valid date (ISO).",
|
378 |
number: "Please enter a valid number.",
|
379 |
digits: "Please enter only digits.",
|
|
|
380 |
equalTo: "Please enter the same value again.",
|
381 |
+
maxlength: $.validator.format( "Please enter no more than {0} characters." ),
|
382 |
+
minlength: $.validator.format( "Please enter at least {0} characters." ),
|
383 |
+
rangelength: $.validator.format( "Please enter a value between {0} and {1} characters long." ),
|
384 |
+
range: $.validator.format( "Please enter a value between {0} and {1}." ),
|
385 |
+
max: $.validator.format( "Please enter a value less than or equal to {0}." ),
|
386 |
+
min: $.validator.format( "Please enter a value greater than or equal to {0}." ),
|
387 |
+
step: $.validator.format( "Please enter a multiple of {0}." )
|
388 |
},
|
389 |
|
390 |
autoCreateRanges: false,
|
392 |
prototype: {
|
393 |
|
394 |
init: function() {
|
395 |
+
this.labelContainer = $( this.settings.errorLabelContainer );
|
396 |
+
this.errorContext = this.labelContainer.length && this.labelContainer || $( this.currentForm );
|
397 |
+
this.containers = $( this.settings.errorContainer ).add( this.settings.errorLabelContainer );
|
398 |
this.submitted = {};
|
399 |
this.valueCache = {};
|
400 |
this.pendingRequest = 0;
|
402 |
this.invalid = {};
|
403 |
this.reset();
|
404 |
|
405 |
+
var currentForm = this.currentForm,
|
406 |
+
groups = ( this.groups = {} ),
|
407 |
+
rules;
|
408 |
+
$.each( this.settings.groups, function( key, value ) {
|
409 |
if ( typeof value === "string" ) {
|
410 |
+
value = value.split( /\s/ );
|
411 |
}
|
412 |
+
$.each( value, function( index, name ) {
|
413 |
+
groups[ name ] = key;
|
414 |
+
} );
|
415 |
+
} );
|
416 |
+
rules = this.settings.rules;
|
417 |
+
$.each( rules, function( key, value ) {
|
418 |
+
rules[ key ] = $.validator.normalizeRule( value );
|
419 |
+
} );
|
420 |
+
|
421 |
+
function delegate( event ) {
|
422 |
+
var isContentEditable = typeof $( this ).attr( "contenteditable" ) !== "undefined" && $( this ).attr( "contenteditable" ) !== "false";
|
423 |
+
|
424 |
+
// Set form expando on contenteditable
|
425 |
+
if ( !this.form && isContentEditable ) {
|
426 |
+
this.form = $( this ).closest( "form" )[ 0 ];
|
427 |
+
this.name = $( this ).attr( "name" );
|
428 |
+
}
|
429 |
+
|
430 |
+
// Ignore the element if it belongs to another form. This will happen mainly
|
431 |
+
// when setting the `form` attribute of an input to the id of another form.
|
432 |
+
if ( currentForm !== this.form ) {
|
433 |
+
return;
|
434 |
+
}
|
435 |
+
|
436 |
+
var validator = $.data( this.form, "validator" ),
|
437 |
+
eventType = "on" + event.type.replace( /^validate/, "" ),
|
438 |
+
settings = validator.settings;
|
439 |
+
if ( settings[ eventType ] && !$( this ).is( settings.ignore ) ) {
|
440 |
+
settings[ eventType ].call( validator, this, event );
|
441 |
}
|
442 |
}
|
443 |
+
|
444 |
+
$( this.currentForm )
|
445 |
+
.on( "focusin.validate focusout.validate keyup.validate",
|
446 |
+
":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], " +
|
447 |
+
"[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], " +
|
448 |
+
"[type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], " +
|
449 |
+
"[type='radio'], [type='checkbox'], [contenteditable], [type='button']", delegate )
|
450 |
+
|
451 |
+
// Support: Chrome, oldIE
|
452 |
+
// "select" is provided as event.target when clicking a option
|
453 |
+
.on( "click.validate", "select, option, [type='radio'], [type='checkbox']", delegate );
|
454 |
|
455 |
if ( this.settings.invalidHandler ) {
|
456 |
+
$( this.currentForm ).on( "invalid-form.validate", this.settings.invalidHandler );
|
457 |
}
|
458 |
},
|
459 |
|
460 |
+
// https://jqueryvalidation.org/Validator.form/
|
461 |
form: function() {
|
462 |
this.checkForm();
|
463 |
+
$.extend( this.submitted, this.errorMap );
|
464 |
+
this.invalid = $.extend( {}, this.errorMap );
|
465 |
if ( !this.valid() ) {
|
466 |
+
$( this.currentForm ).triggerHandler( "invalid-form", [ this ] );
|
467 |
}
|
468 |
this.showErrors();
|
469 |
return this.valid();
|
471 |
|
472 |
checkForm: function() {
|
473 |
this.prepareForm();
|
474 |
+
for ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) {
|
475 |
+
this.check( elements[ i ] );
|
476 |
}
|
477 |
return this.valid();
|
478 |
},
|
479 |
|
480 |
+
// https://jqueryvalidation.org/Validator.element/
|
481 |
element: function( element ) {
|
482 |
+
var cleanElement = this.clean( element ),
|
483 |
+
checkElement = this.validationTargetFor( cleanElement ),
|
484 |
+
v = this,
|
485 |
+
result = true,
|
486 |
+
rs, group;
|
487 |
+
|
488 |
+
if ( checkElement === undefined ) {
|
489 |
+
delete this.invalid[ cleanElement.name ];
|
490 |
} else {
|
491 |
+
this.prepareElement( checkElement );
|
492 |
+
this.currentElements = $( checkElement );
|
493 |
+
|
494 |
+
// If this element is grouped, then validate all group elements already
|
495 |
+
// containing a value
|
496 |
+
group = this.groups[ checkElement.name ];
|
497 |
+
if ( group ) {
|
498 |
+
$.each( this.groups, function( name, testgroup ) {
|
499 |
+
if ( testgroup === group && name !== checkElement.name ) {
|
500 |
+
cleanElement = v.validationTargetFor( v.clean( v.findByName( name ) ) );
|
501 |
+
if ( cleanElement && cleanElement.name in v.invalid ) {
|
502 |
+
v.currentElements.push( cleanElement );
|
503 |
+
result = v.check( cleanElement ) && result;
|
504 |
+
}
|
505 |
+
}
|
506 |
+
} );
|
507 |
+
}
|
508 |
+
|
509 |
+
rs = this.check( checkElement ) !== false;
|
510 |
+
result = result && rs;
|
511 |
+
if ( rs ) {
|
512 |
+
this.invalid[ checkElement.name ] = false;
|
513 |
+
} else {
|
514 |
+
this.invalid[ checkElement.name ] = true;
|
515 |
+
}
|
516 |
+
|
517 |
+
if ( !this.numberOfInvalids() ) {
|
518 |
+
|
519 |
+
// Hide error containers on last error
|
520 |
+
this.toHide = this.toHide.add( this.containers );
|
521 |
+
}
|
522 |
+
this.showErrors();
|
523 |
+
|
524 |
+
// Add aria-invalid status for screen readers
|
525 |
+
$( element ).attr( "aria-invalid", !rs );
|
526 |
}
|
527 |
+
|
528 |
return result;
|
529 |
},
|
530 |
|
531 |
+
// https://jqueryvalidation.org/Validator.showErrors/
|
532 |
showErrors: function( errors ) {
|
533 |
if ( errors ) {
|
534 |
+
var validator = this;
|
535 |
+
|
536 |
+
// Add items to error list and map
|
537 |
$.extend( this.errorMap, errors );
|
538 |
+
this.errorList = $.map( this.errorMap, function( message, name ) {
|
539 |
+
return {
|
540 |
+
message: message,
|
541 |
+
element: validator.findByName( name )[ 0 ]
|
542 |
+
};
|
543 |
+
} );
|
544 |
+
|
545 |
+
// Remove items from success list
|
546 |
this.successList = $.grep( this.successList, function( element ) {
|
547 |
+
return !( element.name in errors );
|
548 |
+
} );
|
549 |
}
|
550 |
if ( this.settings.showErrors ) {
|
551 |
this.settings.showErrors.call( this, this.errorMap, this.errorList );
|
554 |
}
|
555 |
},
|
556 |
|
557 |
+
// https://jqueryvalidation.org/Validator.resetForm/
|
558 |
resetForm: function() {
|
559 |
if ( $.fn.resetForm ) {
|
560 |
+
$( this.currentForm ).resetForm();
|
561 |
}
|
562 |
+
this.invalid = {};
|
563 |
this.submitted = {};
|
|
|
564 |
this.prepareForm();
|
565 |
this.hideErrors();
|
566 |
+
var elements = this.elements()
|
567 |
+
.removeData( "previousValue" )
|
568 |
+
.removeAttr( "aria-invalid" );
|
569 |
+
|
570 |
+
this.resetElements( elements );
|
571 |
+
},
|
572 |
+
|
573 |
+
resetElements: function( elements ) {
|
574 |
+
var i;
|
575 |
+
|
576 |
+
if ( this.settings.unhighlight ) {
|
577 |
+
for ( i = 0; elements[ i ]; i++ ) {
|
578 |
+
this.settings.unhighlight.call( this, elements[ i ],
|
579 |
+
this.settings.errorClass, "" );
|
580 |
+
this.findByName( elements[ i ].name ).removeClass( this.settings.validClass );
|
581 |
+
}
|
582 |
+
} else {
|
583 |
+
elements
|
584 |
+
.removeClass( this.settings.errorClass )
|
585 |
+
.removeClass( this.settings.validClass );
|
586 |
+
}
|
587 |
},
|
588 |
|
589 |
numberOfInvalids: function() {
|
590 |
+
return this.objectLength( this.invalid );
|
591 |
},
|
592 |
|
593 |
objectLength: function( obj ) {
|
594 |
+
/* jshint unused: false */
|
595 |
+
var count = 0,
|
596 |
+
i;
|
597 |
+
for ( i in obj ) {
|
598 |
+
|
599 |
+
// This check allows counting elements with empty error
|
600 |
+
// message as invalid elements
|
601 |
+
if ( obj[ i ] !== undefined && obj[ i ] !== null && obj[ i ] !== false ) {
|
602 |
+
count++;
|
603 |
+
}
|
604 |
}
|
605 |
return count;
|
606 |
},
|
607 |
|
608 |
hideErrors: function() {
|
609 |
+
this.hideThese( this.toHide );
|
610 |
+
},
|
611 |
+
|
612 |
+
hideThese: function( errors ) {
|
613 |
+
errors.not( this.containers ).text( "" );
|
614 |
+
this.addWrapper( errors ).hide();
|
615 |
},
|
616 |
|
617 |
valid: function() {
|
625 |
focusInvalid: function() {
|
626 |
if ( this.settings.focusInvalid ) {
|
627 |
try {
|
628 |
+
$( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || [] )
|
629 |
+
.filter( ":visible" )
|
630 |
+
.trigger( "focus" )
|
631 |
+
|
632 |
+
// Manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
|
633 |
+
.trigger( "focusin" );
|
634 |
+
} catch ( e ) {
|
635 |
+
|
636 |
+
// Ignore IE throwing errors when focusing hidden elements
|
637 |
}
|
638 |
}
|
639 |
},
|
640 |
|
641 |
findLastActive: function() {
|
642 |
var lastActive = this.lastActive;
|
643 |
+
return lastActive && $.grep( this.errorList, function( n ) {
|
644 |
return n.element.name === lastActive.name;
|
645 |
+
} ).length === 1 && lastActive;
|
646 |
},
|
647 |
|
648 |
elements: function() {
|
649 |
var validator = this,
|
650 |
rulesCache = {};
|
651 |
|
652 |
+
// Select all valid inputs inside the form (no submit or reset buttons)
|
653 |
+
return $( this.currentForm )
|
654 |
+
.find( "input, select, textarea, [contenteditable]" )
|
655 |
+
.not( ":submit, :reset, :image, :disabled" )
|
656 |
.not( this.settings.ignore )
|
657 |
+
.filter( function() {
|
658 |
+
var name = this.name || $( this ).attr( "name" ); // For contenteditable
|
659 |
+
var isContentEditable = typeof $( this ).attr( "contenteditable" ) !== "undefined" && $( this ).attr( "contenteditable" ) !== "false";
|
660 |
+
|
661 |
+
if ( !name && validator.settings.debug && window.console ) {
|
662 |
+
console.error( "%o has no name assigned", this );
|
663 |
+
}
|
664 |
+
|
665 |
+
// Set form expando on contenteditable
|
666 |
+
if ( isContentEditable ) {
|
667 |
+
this.form = $( this ).closest( "form" )[ 0 ];
|
668 |
+
this.name = name;
|
669 |
+
}
|
670 |
+
|
671 |
+
// Ignore elements that belong to other/nested forms
|
672 |
+
if ( this.form !== validator.currentForm ) {
|
673 |
+
return false;
|
674 |
}
|
675 |
|
676 |
+
// Select only the first element for each name, and only those with rules specified
|
677 |
+
if ( name in rulesCache || !validator.objectLength( $( this ).rules() ) ) {
|
678 |
return false;
|
679 |
}
|
680 |
|
681 |
+
rulesCache[ name ] = true;
|
682 |
return true;
|
683 |
+
} );
|
684 |
},
|
685 |
|
686 |
clean: function( selector ) {
|
687 |
+
return $( selector )[ 0 ];
|
688 |
},
|
689 |
|
690 |
errors: function() {
|
691 |
+
var errorClass = this.settings.errorClass.split( " " ).join( "." );
|
692 |
+
return $( this.settings.errorElement + "." + errorClass, this.errorContext );
|
693 |
},
|
694 |
|
695 |
+
resetInternals: function() {
|
696 |
this.successList = [];
|
697 |
this.errorList = [];
|
698 |
this.errorMap = {};
|
699 |
+
this.toShow = $( [] );
|
700 |
+
this.toHide = $( [] );
|
701 |
+
},
|
702 |
+
|
703 |
+
reset: function() {
|
704 |
+
this.resetInternals();
|
705 |
+
this.currentElements = $( [] );
|
706 |
},
|
707 |
|
708 |
prepareForm: function() {
|
712 |
|
713 |
prepareElement: function( element ) {
|
714 |
this.reset();
|
715 |
+
this.toHide = this.errorsFor( element );
|
716 |
},
|
717 |
|
718 |
elementValue: function( element ) {
|
719 |
+
var $element = $( element ),
|
720 |
+
type = element.type,
|
721 |
+
isContentEditable = typeof $element.attr( "contenteditable" ) !== "undefined" && $element.attr( "contenteditable" ) !== "false",
|
722 |
+
val, idx;
|
723 |
|
724 |
if ( type === "radio" || type === "checkbox" ) {
|
725 |
+
return this.findByName( element.name ).filter( ":checked" ).val();
|
726 |
+
} else if ( type === "number" && typeof element.validity !== "undefined" ) {
|
727 |
+
return element.validity.badInput ? "NaN" : $element.val();
|
728 |
+
}
|
729 |
+
|
730 |
+
if ( isContentEditable ) {
|
731 |
+
val = $element.text();
|
732 |
+
} else {
|
733 |
+
val = $element.val();
|
734 |
+
}
|
735 |
+
|
736 |
+
if ( type === "file" ) {
|
737 |
+
|
738 |
+
// Modern browser (chrome & safari)
|
739 |
+
if ( val.substr( 0, 12 ) === "C:\\fakepath\\" ) {
|
740 |
+
return val.substr( 12 );
|
741 |
+
}
|
742 |
+
|
743 |
+
// Legacy browsers
|
744 |
+
// Unix-based path
|
745 |
+
idx = val.lastIndexOf( "/" );
|
746 |
+
if ( idx >= 0 ) {
|
747 |
+
return val.substr( idx + 1 );
|
748 |
+
}
|
749 |
+
|
750 |
+
// Windows-based path
|
751 |
+
idx = val.lastIndexOf( "\\" );
|
752 |
+
if ( idx >= 0 ) {
|
753 |
+
return val.substr( idx + 1 );
|
754 |
+
}
|
755 |
+
|
756 |
+
// Just the file name
|
757 |
+
return val;
|
758 |
}
|
759 |
|
760 |
if ( typeof val === "string" ) {
|
761 |
+
return val.replace( /\r/g, "" );
|
762 |
}
|
763 |
return val;
|
764 |
},
|
766 |
check: function( element ) {
|
767 |
element = this.validationTargetFor( this.clean( element ) );
|
768 |
|
769 |
+
var rules = $( element ).rules(),
|
770 |
+
rulesCount = $.map( rules, function( n, i ) {
|
771 |
+
return i;
|
772 |
+
} ).length,
|
773 |
+
dependencyMismatch = false,
|
774 |
+
val = this.elementValue( element ),
|
775 |
+
result, method, rule, normalizer;
|
776 |
+
|
777 |
+
// Prioritize the local normalizer defined for this element over the global one
|
778 |
+
// if the former exists, otherwise user the global one in case it exists.
|
779 |
+
if ( typeof rules.normalizer === "function" ) {
|
780 |
+
normalizer = rules.normalizer;
|
781 |
+
} else if ( typeof this.settings.normalizer === "function" ) {
|
782 |
+
normalizer = this.settings.normalizer;
|
783 |
+
}
|
784 |
+
|
785 |
+
// If normalizer is defined, then call it to retreive the changed value instead
|
786 |
+
// of using the real one.
|
787 |
+
// Note that `this` in the normalizer is `element`.
|
788 |
+
if ( normalizer ) {
|
789 |
+
val = normalizer.call( element, val );
|
790 |
|
791 |
+
// Delete the normalizer from rules to avoid treating it as a pre-defined method.
|
792 |
+
delete rules.normalizer;
|
793 |
+
}
|
794 |
|
795 |
+
for ( method in rules ) {
|
796 |
+
rule = { method: method, parameters: rules[ method ] };
|
797 |
+
try {
|
798 |
+
result = $.validator.methods[ method ].call( this, val, element, rule.parameters );
|
799 |
|
800 |
+
// If a method indicates that the field is optional and therefore valid,
|
801 |
// don't mark it as valid when there are no other rules
|
802 |
+
if ( result === "dependency-mismatch" && rulesCount === 1 ) {
|
803 |
dependencyMismatch = true;
|
804 |
continue;
|
805 |
}
|
806 |
dependencyMismatch = false;
|
807 |
|
808 |
if ( result === "pending" ) {
|
809 |
+
this.toHide = this.toHide.not( this.errorsFor( element ) );
|
810 |
return;
|
811 |
}
|
812 |
|
814 |
this.formatAndAdd( element, rule );
|
815 |
return false;
|
816 |
}
|
817 |
+
} catch ( e ) {
|
818 |
if ( this.settings.debug && window.console ) {
|
819 |
+
console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e );
|
820 |
}
|
821 |
+
if ( e instanceof TypeError ) {
|
822 |
+
e.message += ". Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.";
|
823 |
+
}
|
824 |
+
|
825 |
throw e;
|
826 |
}
|
827 |
}
|
828 |
if ( dependencyMismatch ) {
|
829 |
return;
|
830 |
}
|
831 |
+
if ( this.objectLength( rules ) ) {
|
832 |
+
this.successList.push( element );
|
833 |
}
|
834 |
return true;
|
835 |
},
|
836 |
|
837 |
+
// Return the custom message for the given element and validation method
|
838 |
// specified in the element's HTML5 data attribute
|
839 |
+
// return the generic message if present and no method specific message is present
|
840 |
customDataMessage: function( element, method ) {
|
841 |
+
return $( element ).data( "msg" + method.charAt( 0 ).toUpperCase() +
|
842 |
+
method.substring( 1 ).toLowerCase() ) || $( element ).data( "msg" );
|
843 |
},
|
844 |
|
845 |
+
// Return the custom message for the given element name and validation method
|
846 |
customMessage: function( name, method ) {
|
847 |
+
var m = this.settings.messages[ name ];
|
848 |
+
return m && ( m.constructor === String ? m : m[ method ] );
|
849 |
},
|
850 |
|
851 |
+
// Return the first defined argument, allowing empty strings
|
852 |
findDefined: function() {
|
853 |
+
for ( var i = 0; i < arguments.length; i++ ) {
|
854 |
+
if ( arguments[ i ] !== undefined ) {
|
855 |
+
return arguments[ i ];
|
856 |
}
|
857 |
}
|
858 |
return undefined;
|
859 |
},
|
860 |
|
861 |
+
// The second parameter 'rule' used to be a string, and extended to an object literal
|
862 |
+
// of the following form:
|
863 |
+
// rule = {
|
864 |
+
// method: "method name",
|
865 |
+
// parameters: "the given method parameters"
|
866 |
+
// }
|
867 |
+
//
|
868 |
+
// The old behavior still supported, kept to maintain backward compatibility with
|
869 |
+
// old code, and will be removed in the next major release.
|
870 |
+
defaultMessage: function( element, rule ) {
|
871 |
+
if ( typeof rule === "string" ) {
|
872 |
+
rule = { method: rule };
|
873 |
+
}
|
874 |
|
875 |
+
var message = this.findDefined(
|
876 |
+
this.customMessage( element.name, rule.method ),
|
877 |
+
this.customDataMessage( element, rule.method ),
|
878 |
+
|
879 |
+
// 'title' is never undefined, so handle empty string as undefined
|
880 |
+
!this.settings.ignoreTitle && element.title || undefined,
|
881 |
+
$.validator.messages[ rule.method ],
|
882 |
+
"<strong>Warning: No message defined for " + element.name + "</strong>"
|
883 |
+
),
|
884 |
theregex = /\$?\{(\d+)\}/g;
|
885 |
if ( typeof message === "function" ) {
|
886 |
+
message = message.call( this, rule.parameters, element );
|
887 |
+
} else if ( theregex.test( message ) ) {
|
888 |
+
message = $.validator.format( message.replace( theregex, "{$1}" ), rule.parameters );
|
889 |
}
|
890 |
+
|
891 |
+
return message;
|
892 |
+
},
|
893 |
+
|
894 |
+
formatAndAdd: function( element, rule ) {
|
895 |
+
var message = this.defaultMessage( element, rule );
|
896 |
+
|
897 |
+
this.errorList.push( {
|
898 |
message: message,
|
899 |
+
element: element,
|
900 |
+
method: rule.method
|
901 |
+
} );
|
902 |
|
903 |
+
this.errorMap[ element.name ] = message;
|
904 |
+
this.submitted[ element.name ] = message;
|
905 |
},
|
906 |
|
907 |
addWrapper: function( toToggle ) {
|
912 |
},
|
913 |
|
914 |
defaultShowErrors: function() {
|
915 |
+
var i, elements, error;
|
916 |
+
for ( i = 0; this.errorList[ i ]; i++ ) {
|
917 |
+
error = this.errorList[ i ];
|
918 |
if ( this.settings.highlight ) {
|
919 |
this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
|
920 |
}
|
924 |
this.toShow = this.toShow.add( this.containers );
|
925 |
}
|
926 |
if ( this.settings.success ) {
|
927 |
+
for ( i = 0; this.successList[ i ]; i++ ) {
|
928 |
+
this.showLabel( this.successList[ i ] );
|
929 |
}
|
930 |
}
|
931 |
if ( this.settings.unhighlight ) {
|
932 |
+
for ( i = 0, elements = this.validElements(); elements[ i ]; i++ ) {
|
933 |
+
this.settings.unhighlight.call( this, elements[ i ], this.settings.errorClass, this.settings.validClass );
|
934 |
}
|
935 |
}
|
936 |
this.toHide = this.toHide.not( this.toShow );
|
939 |
},
|
940 |
|
941 |
validElements: function() {
|
942 |
+
return this.currentElements.not( this.invalidElements() );
|
943 |
},
|
944 |
|
945 |
invalidElements: function() {
|
946 |
+
return $( this.errorList ).map( function() {
|
947 |
return this.element;
|
948 |
+
} );
|
949 |
},
|
950 |
|
951 |
showLabel: function( element, message ) {
|
952 |
+
var place, group, errorID, v,
|
953 |
+
error = this.errorsFor( element ),
|
954 |
+
elementID = this.idOrName( element ),
|
955 |
+
describedBy = $( element ).attr( "aria-describedby" );
|
956 |
+
|
957 |
+
if ( error.length ) {
|
958 |
+
|
959 |
+
// Refresh error/success class
|
960 |
+
error.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );
|
961 |
+
|
962 |
+
// Replace message on existing label
|
963 |
+
error.html( message );
|
964 |
} else {
|
965 |
+
|
966 |
+
// Create error element
|
967 |
+
error = $( "<" + this.settings.errorElement + ">" )
|
968 |
+
.attr( "id", elementID + "-error" )
|
969 |
+
.addClass( this.settings.errorClass )
|
970 |
+
.html( message || "" );
|
971 |
+
|
972 |
+
// Maintain reference to the element to be placed into the DOM
|
973 |
+
place = error;
|
974 |
if ( this.settings.wrapper ) {
|
975 |
+
|
976 |
+
// Make sure the element is visible, even in IE
|
977 |
// actually showing the wrapped element is handled elsewhere
|
978 |
+
place = error.hide().show().wrap( "<" + this.settings.wrapper + "/>" ).parent();
|
979 |
}
|
980 |
+
if ( this.labelContainer.length ) {
|
981 |
+
this.labelContainer.append( place );
|
982 |
+
} else if ( this.settings.errorPlacement ) {
|
983 |
+
this.settings.errorPlacement.call( this, place, $( element ) );
|
984 |
+
} else {
|
985 |
+
place.insertAfter( element );
|
986 |
+
}
|
987 |
+
|
988 |
+
// Link error back to the element
|
989 |
+
if ( error.is( "label" ) ) {
|
990 |
+
|
991 |
+
// If the error is a label, then associate using 'for'
|
992 |
+
error.attr( "for", elementID );
|
993 |
+
|
994 |
+
// If the element is not a child of an associated label, then it's necessary
|
995 |
+
// to explicitly apply aria-describedby
|
996 |
+
} else if ( error.parents( "label[for='" + this.escapeCssMeta( elementID ) + "']" ).length === 0 ) {
|
997 |
+
errorID = error.attr( "id" );
|
998 |
+
|
999 |
+
// Respect existing non-error aria-describedby
|
1000 |
+
if ( !describedBy ) {
|
1001 |
+
describedBy = errorID;
|
1002 |
+
} else if ( !describedBy.match( new RegExp( "\\b" + this.escapeCssMeta( errorID ) + "\\b" ) ) ) {
|
1003 |
+
|
1004 |
+
// Add to end of list if not already present
|
1005 |
+
describedBy += " " + errorID;
|
1006 |
+
}
|
1007 |
+
$( element ).attr( "aria-describedby", describedBy );
|
1008 |
+
|
1009 |
+
// If this element is grouped, then assign to all elements in the same group
|
1010 |
+
group = this.groups[ element.name ];
|
1011 |
+
if ( group ) {
|
1012 |
+
v = this;
|
1013 |
+
$.each( v.groups, function( name, testgroup ) {
|
1014 |
+
if ( testgroup === group ) {
|
1015 |
+
$( "[name='" + v.escapeCssMeta( name ) + "']", v.currentForm )
|
1016 |
+
.attr( "aria-describedby", error.attr( "id" ) );
|
1017 |
+
}
|
1018 |
+
} );
|
1019 |
}
|
1020 |
}
|
1021 |
}
|
1022 |
if ( !message && this.settings.success ) {
|
1023 |
+
error.text( "" );
|
1024 |
if ( typeof this.settings.success === "string" ) {
|
1025 |
+
error.addClass( this.settings.success );
|
1026 |
} else {
|
1027 |
+
this.settings.success( error, element );
|
1028 |
}
|
1029 |
}
|
1030 |
+
this.toShow = this.toShow.add( error );
|
1031 |
},
|
1032 |
|
1033 |
errorsFor: function( element ) {
|
1034 |
+
var name = this.escapeCssMeta( this.idOrName( element ) ),
|
1035 |
+
describer = $( element ).attr( "aria-describedby" ),
|
1036 |
+
selector = "label[for='" + name + "'], label[for='" + name + "'] *";
|
1037 |
+
|
1038 |
+
// 'aria-describedby' should directly reference the error element
|
1039 |
+
if ( describer ) {
|
1040 |
+
selector = selector + ", #" + this.escapeCssMeta( describer )
|
1041 |
+
.replace( /\s+/g, ", #" );
|
1042 |
+
}
|
1043 |
+
|
1044 |
+
return this
|
1045 |
+
.errors()
|
1046 |
+
.filter( selector );
|
1047 |
+
},
|
1048 |
+
|
1049 |
+
// See https://api.jquery.com/category/selectors/, for CSS
|
1050 |
+
// meta-characters that should be escaped in order to be used with JQuery
|
1051 |
+
// as a literal part of a name/id or any selector.
|
1052 |
+
escapeCssMeta: function( string ) {
|
1053 |
+
return string.replace( /([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g, "\\$1" );
|
1054 |
},
|
1055 |
|
1056 |
idOrName: function( element ) {
|
1057 |
+
return this.groups[ element.name ] || ( this.checkable( element ) ? element.name : element.id || element.name );
|
1058 |
},
|
1059 |
|
1060 |
validationTargetFor: function( element ) {
|
1061 |
+
|
1062 |
+
// If radio/checkbox, validate first element in group instead
|
1063 |
+
if ( this.checkable( element ) ) {
|
1064 |
+
element = this.findByName( element.name );
|
1065 |
}
|
1066 |
+
|
1067 |
+
// Always apply ignore filter
|
1068 |
+
return $( element ).not( this.settings.ignore )[ 0 ];
|
1069 |
},
|
1070 |
|
1071 |
checkable: function( element ) {
|
1072 |
+
return ( /radio|checkbox/i ).test( element.type );
|
1073 |
},
|
1074 |
|
1075 |
findByName: function( name ) {
|
1076 |
+
return $( this.currentForm ).find( "[name='" + this.escapeCssMeta( name ) + "']" );
|
1077 |
},
|
1078 |
|
1079 |
getLength: function( value, element ) {
|
1080 |
+
switch ( element.nodeName.toLowerCase() ) {
|
1081 |
case "select":
|
1082 |
+
return $( "option:selected", element ).length;
|
1083 |
case "input":
|
1084 |
+
if ( this.checkable( element ) ) {
|
1085 |
+
return this.findByName( element.name ).filter( ":checked" ).length;
|
1086 |
}
|
1087 |
}
|
1088 |
return value.length;
|
1089 |
},
|
1090 |
|
1091 |
depend: function( param, element ) {
|
1092 |
+
return this.dependTypes[ typeof param ] ? this.dependTypes[ typeof param ]( param, element ) : true;
|
1093 |
},
|
1094 |
|
1095 |
dependTypes: {
|
1096 |
+
"boolean": function( param ) {
|
1097 |
return param;
|
1098 |
},
|
1099 |
"string": function( param, element ) {
|
1100 |
+
return !!$( param, element.form ).length;
|
1101 |
},
|
1102 |
"function": function( param, element ) {
|
1103 |
+
return param( element );
|
1104 |
}
|
1105 |
},
|
1106 |
|
1107 |
optional: function( element ) {
|
1108 |
+
var val = this.elementValue( element );
|
1109 |
+
return !$.validator.methods.required.call( this, val, element ) && "dependency-mismatch";
|
1110 |
},
|
1111 |
|
1112 |
startRequest: function( element ) {
|
1113 |
+
if ( !this.pending[ element.name ] ) {
|
1114 |
this.pendingRequest++;
|
1115 |
+
$( element ).addClass( this.settings.pendingClass );
|
1116 |
+
this.pending[ element.name ] = true;
|
1117 |
}
|
1118 |
},
|
1119 |
|
1120 |
stopRequest: function( element, valid ) {
|
1121 |
this.pendingRequest--;
|
1122 |
+
|
1123 |
+
// Sometimes synchronization fails, make sure pendingRequest is never < 0
|
1124 |
if ( this.pendingRequest < 0 ) {
|
1125 |
this.pendingRequest = 0;
|
1126 |
}
|
1127 |
+
delete this.pending[ element.name ];
|
1128 |
+
$( element ).removeClass( this.settings.pendingClass );
|
1129 |
if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) {
|
1130 |
+
$( this.currentForm ).submit();
|
1131 |
+
|
1132 |
+
// Remove the hidden input that was used as a replacement for the
|
1133 |
+
// missing submit button. The hidden input is added by `handle()`
|
1134 |
+
// to ensure that the value of the used submit button is passed on
|
1135 |
+
// for scripted submits triggered by this method
|
1136 |
+
if ( this.submitButton ) {
|
1137 |
+
$( "input:hidden[name='" + this.submitButton.name + "']", this.currentForm ).remove();
|
1138 |
+
}
|
1139 |
+
|
1140 |
this.formSubmitted = false;
|
1141 |
+
} else if ( !valid && this.pendingRequest === 0 && this.formSubmitted ) {
|
1142 |
+
$( this.currentForm ).triggerHandler( "invalid-form", [ this ] );
|
1143 |
this.formSubmitted = false;
|
1144 |
}
|
1145 |
},
|
1146 |
|
1147 |
+
previousValue: function( element, method ) {
|
1148 |
+
method = typeof method === "string" && method || "remote";
|
1149 |
+
|
1150 |
+
return $.data( element, "previousValue" ) || $.data( element, "previousValue", {
|
1151 |
old: null,
|
1152 |
valid: true,
|
1153 |
+
message: this.defaultMessage( element, { method: method } )
|
1154 |
+
} );
|
1155 |
+
},
|
1156 |
+
|
1157 |
+
// Cleans up all forms and elements, removes validator-specific events
|
1158 |
+
destroy: function() {
|
1159 |
+
this.resetForm();
|
1160 |
+
|
1161 |
+
$( this.currentForm )
|
1162 |
+
.off( ".validate" )
|
1163 |
+
.removeData( "validator" )
|
1164 |
+
.find( ".validate-equalTo-blur" )
|
1165 |
+
.off( ".validate-equalTo" )
|
1166 |
+
.removeClass( "validate-equalTo-blur" )
|
1167 |
+
.find( ".validate-lessThan-blur" )
|
1168 |
+
.off( ".validate-lessThan" )
|
1169 |
+
.removeClass( "validate-lessThan-blur" )
|
1170 |
+
.find( ".validate-lessThanEqual-blur" )
|
1171 |
+
.off( ".validate-lessThanEqual" )
|
1172 |
+
.removeClass( "validate-lessThanEqual-blur" )
|
1173 |
+
.find( ".validate-greaterThanEqual-blur" )
|
1174 |
+
.off( ".validate-greaterThanEqual" )
|
1175 |
+
.removeClass( "validate-greaterThanEqual-blur" )
|
1176 |
+
.find( ".validate-greaterThan-blur" )
|
1177 |
+
.off( ".validate-greaterThan" )
|
1178 |
+
.removeClass( "validate-greaterThan-blur" );
|
1179 |
}
|
1180 |
|
1181 |
},
|
1182 |
|
1183 |
classRuleSettings: {
|
1184 |
+
required: { required: true },
|
1185 |
+
email: { email: true },
|
1186 |
+
url: { url: true },
|
1187 |
+
date: { date: true },
|
1188 |
+
dateISO: { dateISO: true },
|
1189 |
+
number: { number: true },
|
1190 |
+
digits: { digits: true },
|
1191 |
+
creditcard: { creditcard: true }
|
1192 |
},
|
1193 |
|
1194 |
addClassRules: function( className, rules ) {
|
1195 |
if ( className.constructor === String ) {
|
1196 |
+
this.classRuleSettings[ className ] = rules;
|
1197 |
} else {
|
1198 |
+
$.extend( this.classRuleSettings, className );
|
1199 |
}
|
1200 |
},
|
1201 |
|
1202 |
classRules: function( element ) {
|
1203 |
+
var rules = {},
|
1204 |
+
classes = $( element ).attr( "class" );
|
1205 |
+
|
1206 |
if ( classes ) {
|
1207 |
+
$.each( classes.split( " " ), function() {
|
1208 |
if ( this in $.validator.classRuleSettings ) {
|
1209 |
+
$.extend( rules, $.validator.classRuleSettings[ this ] );
|
1210 |
}
|
1211 |
+
} );
|
1212 |
}
|
1213 |
return rules;
|
1214 |
},
|
1215 |
|
1216 |
+
normalizeAttributeRule: function( rules, type, method, value ) {
|
1217 |
+
|
1218 |
+
// Convert the value to a number for number inputs, and for text for backwards compability
|
1219 |
+
// allows type="date" and others to be compared as strings
|
1220 |
+
if ( /min|max|step/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) {
|
1221 |
+
value = Number( value );
|
1222 |
+
|
1223 |
+
// Support Opera Mini, which returns NaN for undefined minlength
|
1224 |
+
if ( isNaN( value ) ) {
|
1225 |
+
value = undefined;
|
1226 |
+
}
|
1227 |
+
}
|
1228 |
+
|
1229 |
+
if ( value || value === 0 ) {
|
1230 |
+
rules[ method ] = value;
|
1231 |
+
} else if ( type === method && type !== "range" ) {
|
1232 |
+
|
1233 |
+
// Exception: the jquery validate 'range' method
|
1234 |
+
// does not test for the html5 'range' type
|
1235 |
+
rules[ method ] = true;
|
1236 |
+
}
|
1237 |
+
},
|
1238 |
+
|
1239 |
attributeRules: function( element ) {
|
1240 |
+
var rules = {},
|
1241 |
+
$element = $( element ),
|
1242 |
+
type = element.getAttribute( "type" ),
|
1243 |
+
method, value;
|
1244 |
|
1245 |
+
for ( method in $.validator.methods ) {
|
|
|
1246 |
|
1247 |
+
// Support for <input required> in both html5 and older browsers
|
1248 |
if ( method === "required" ) {
|
1249 |
+
value = element.getAttribute( method );
|
1250 |
+
|
1251 |
// Some browsers return an empty string for the required attribute
|
1252 |
// and non-HTML5 browsers might have required="" markup
|
1253 |
if ( value === "" ) {
|
1254 |
value = true;
|
1255 |
}
|
1256 |
+
|
1257 |
+
// Force non-HTML5 browsers to return bool
|
1258 |
value = !!value;
|
1259 |
} else {
|
1260 |
+
value = $element.attr( method );
|
1261 |
}
|
1262 |
|
1263 |
+
this.normalizeAttributeRule( rules, type, method, value );
|
|
|
|
|
|
|
|
|
1264 |
}
|
1265 |
|
1266 |
+
// 'maxlength' may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs
|
1267 |
+
if ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) {
|
1268 |
delete rules.maxlength;
|
1269 |
}
|
1270 |
|
1272 |
},
|
1273 |
|
1274 |
dataRules: function( element ) {
|
1275 |
+
var rules = {},
|
1276 |
+
$element = $( element ),
|
1277 |
+
type = element.getAttribute( "type" ),
|
1278 |
+
method, value;
|
1279 |
+
|
1280 |
+
for ( method in $.validator.methods ) {
|
1281 |
+
value = $element.data( "rule" + method.charAt( 0 ).toUpperCase() + method.substring( 1 ).toLowerCase() );
|
1282 |
+
|
1283 |
+
// Cast empty attributes like `data-rule-required` to `true`
|
1284 |
+
if ( value === "" ) {
|
1285 |
+
value = true;
|
1286 |
}
|
1287 |
+
|
1288 |
+
this.normalizeAttributeRule( rules, type, method, value );
|
1289 |
}
|
1290 |
return rules;
|
1291 |
},
|
1292 |
|
1293 |
staticRules: function( element ) {
|
1294 |
+
var rules = {},
|
1295 |
+
validator = $.data( element.form, "validator" );
|
1296 |
+
|
1297 |
if ( validator.settings.rules ) {
|
1298 |
+
rules = $.validator.normalizeRule( validator.settings.rules[ element.name ] ) || {};
|
1299 |
}
|
1300 |
return rules;
|
1301 |
},
|
1302 |
|
1303 |
normalizeRules: function( rules, element ) {
|
1304 |
+
|
1305 |
+
// Handle dependency check
|
1306 |
+
$.each( rules, function( prop, val ) {
|
1307 |
+
|
1308 |
+
// Ignore rule when param is explicitly false, eg. required:false
|
1309 |
if ( val === false ) {
|
1310 |
+
delete rules[ prop ];
|
1311 |
return;
|
1312 |
}
|
1313 |
if ( val.param || val.depends ) {
|
1314 |
var keepRule = true;
|
1315 |
+
switch ( typeof val.depends ) {
|
1316 |
case "string":
|
1317 |
+
keepRule = !!$( val.depends, element.form ).length;
|
1318 |
break;
|
1319 |
case "function":
|
1320 |
+
keepRule = val.depends.call( element, element );
|
1321 |
break;
|
1322 |
}
|
1323 |
if ( keepRule ) {
|
1324 |
+
rules[ prop ] = val.param !== undefined ? val.param : true;
|
1325 |
} else {
|
1326 |
+
$.data( element.form, "validator" ).resetElements( $( element ) );
|
1327 |
+
delete rules[ prop ];
|
1328 |
}
|
1329 |
}
|
1330 |
+
} );
|
1331 |
|
1332 |
+
// Evaluate parameters
|
1333 |
+
$.each( rules, function( rule, parameter ) {
|
1334 |
+
rules[ rule ] = typeof parameter === "function" && rule !== "normalizer" ? parameter( element ) : parameter;
|
1335 |
+
} );
|
1336 |
|
1337 |
+
// Clean number parameters
|
1338 |
+
$.each( [ "minlength", "maxlength" ], function() {
|
1339 |
+
if ( rules[ this ] ) {
|
1340 |
+
rules[ this ] = Number( rules[ this ] );
|
1341 |
}
|
1342 |
+
} );
|
1343 |
+
$.each( [ "rangelength", "range" ], function() {
|
1344 |
var parts;
|
1345 |
+
if ( rules[ this ] ) {
|
1346 |
+
if ( Array.isArray( rules[ this ] ) ) {
|
1347 |
+
rules[ this ] = [ Number( rules[ this ][ 0 ] ), Number( rules[ this ][ 1 ] ) ];
|
1348 |
+
} else if ( typeof rules[ this ] === "string" ) {
|
1349 |
+
parts = rules[ this ].replace( /[\[\]]/g, "" ).split( /[\s,]+/ );
|
1350 |
+
rules[ this ] = [ Number( parts[ 0 ] ), Number( parts[ 1 ] ) ];
|
1351 |
}
|
1352 |
}
|
1353 |
+
} );
|
1354 |
|
1355 |
if ( $.validator.autoCreateRanges ) {
|
1356 |
+
|
1357 |
+
// Auto-create ranges
|
1358 |
+
if ( rules.min != null && rules.max != null ) {
|
1359 |
+
rules.range = [ rules.min, rules.max ];
|
1360 |
delete rules.min;
|
1361 |
delete rules.max;
|
1362 |
}
|
1363 |
+
if ( rules.minlength != null && rules.maxlength != null ) {
|
1364 |
+
rules.rangelength = [ rules.minlength, rules.maxlength ];
|
1365 |
delete rules.minlength;
|
1366 |
delete rules.maxlength;
|
1367 |
}
|
1374 |
normalizeRule: function( data ) {
|
1375 |
if ( typeof data === "string" ) {
|
1376 |
var transformed = {};
|
1377 |
+
$.each( data.split( /\s/ ), function() {
|
1378 |
+
transformed[ this ] = true;
|
1379 |
+
} );
|
1380 |
data = transformed;
|
1381 |
}
|
1382 |
return data;
|
1383 |
},
|
1384 |
|
1385 |
+
// https://jqueryvalidation.org/jQuery.validator.addMethod/
|
1386 |
addMethod: function( name, method, message ) {
|
1387 |
+
$.validator.methods[ name ] = method;
|
1388 |
+
$.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ];
|
1389 |
if ( method.length < 3 ) {
|
1390 |
+
$.validator.addClassRules( name, $.validator.normalizeRule( name ) );
|
1391 |
}
|
1392 |
},
|
1393 |
|
1394 |
+
// https://jqueryvalidation.org/jQuery.validator.methods/
|
1395 |
methods: {
|
1396 |
|
1397 |
+
// https://jqueryvalidation.org/required-method/
|
1398 |
required: function( value, element, param ) {
|
1399 |
+
|
1400 |
+
// Check if dependency is met
|
1401 |
+
if ( !this.depend( param, element ) ) {
|
1402 |
return "dependency-mismatch";
|
1403 |
}
|
1404 |
if ( element.nodeName.toLowerCase() === "select" ) {
|
1405 |
+
|
1406 |
+
// Could be an array for select-multiple or a string, both are fine this way
|
1407 |
+
var val = $( element ).val();
|
1408 |
return val && val.length > 0;
|
1409 |
}
|
1410 |
+
if ( this.checkable( element ) ) {
|
1411 |
+
return this.getLength( value, element ) > 0;
|
1412 |
}
|
1413 |
+
return value !== undefined && value !== null && value.length > 0;
|
1414 |
},
|
1415 |
|
1416 |
+
// https://jqueryvalidation.org/email-method/
|
1417 |
+
email: function( value, element ) {
|
|
|
|
|
|
|
1418 |
|
1419 |
+
// From https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address
|
1420 |
+
// Retrieved 2014-01-14
|
1421 |
+
// If you have a problem with this implementation, report a bug against the above spec
|
1422 |
+
// Or use custom methods to implement your own email validation
|
1423 |
+
return this.optional( element ) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test( value );
|
1424 |
+
},
|
1425 |
|
1426 |
+
// https://jqueryvalidation.org/url-method/
|
1427 |
+
url: function( value, element ) {
|
1428 |
|
1429 |
+
// Copyright (c) 2010-2013 Diego Perini, MIT licensed
|
1430 |
+
// https://gist.github.com/dperini/729294
|
1431 |
+
// see also https://mathiasbynens.be/demo/url-regex
|
1432 |
+
// modified to allow protocol-relative URLs
|
1433 |
+
return this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff]\.)+(?:[a-z\u00a1-\uffff]{2,}\.?))(?::\d{2,5})?(?:[/?#]\S*)?$/i.test( value );
|
1434 |
+
},
|
1435 |
|
1436 |
+
// https://jqueryvalidation.org/date-method/
|
1437 |
+
date: ( function() {
|
1438 |
+
var called = false;
|
1439 |
+
|
1440 |
+
return function( value, element ) {
|
1441 |
+
if ( !called ) {
|
1442 |
+
called = true;
|
1443 |
+
if ( this.settings.debug && window.console ) {
|
1444 |
+
console.warn(
|
1445 |
+
"The `date` method is deprecated and will be removed in version '2.0.0'.\n" +
|
1446 |
+
"Please don't use it, since it relies on the Date constructor, which\n" +
|
1447 |
+
"behaves very differently across browsers and locales. Use `dateISO`\n" +
|
1448 |
+
"instead or one of the locale specific methods in `localizations/`\n" +
|
1449 |
+
"and `additional-methods.js`."
|
1450 |
+
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1451 |
}
|
|
|
|
|
1452 |
}
|
1453 |
+
|
1454 |
+
return this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() );
|
1455 |
+
};
|
1456 |
+
}() ),
|
1457 |
+
|
1458 |
+
// https://jqueryvalidation.org/dateISO-method/
|
1459 |
+
dateISO: function( value, element ) {
|
1460 |
+
return this.optional( element ) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test( value );
|
1461 |
+
},
|
1462 |
+
|
1463 |
+
// https://jqueryvalidation.org/number-method/
|
1464 |
+
number: function( value, element ) {
|
1465 |
+
return this.optional( element ) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test( value );
|
1466 |
+
},
|
1467 |
+
|
1468 |
+
// https://jqueryvalidation.org/digits-method/
|
1469 |
+
digits: function( value, element ) {
|
1470 |
+
return this.optional( element ) || /^\d+$/.test( value );
|
1471 |
},
|
1472 |
|
1473 |
+
// https://jqueryvalidation.org/minlength-method/
|
1474 |
minlength: function( value, element, param ) {
|
1475 |
+
var length = Array.isArray( value ) ? value.length : this.getLength( value, element );
|
1476 |
+
return this.optional( element ) || length >= param;
|
1477 |
},
|
1478 |
|
1479 |
+
// https://jqueryvalidation.org/maxlength-method/
|
1480 |
maxlength: function( value, element, param ) {
|
1481 |
+
var length = Array.isArray( value ) ? value.length : this.getLength( value, element );
|
1482 |
+
return this.optional( element ) || length <= param;
|
1483 |
},
|
1484 |
|
1485 |
+
// https://jqueryvalidation.org/rangelength-method/
|
1486 |
rangelength: function( value, element, param ) {
|
1487 |
+
var length = Array.isArray( value ) ? value.length : this.getLength( value, element );
|
1488 |
+
return this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] );
|
1489 |
},
|
1490 |
|
1491 |
+
// https://jqueryvalidation.org/min-method/
|
1492 |
min: function( value, element, param ) {
|
1493 |
+
return this.optional( element ) || value >= param;
|
1494 |
},
|
1495 |
|
1496 |
+
// https://jqueryvalidation.org/max-method/
|
1497 |
max: function( value, element, param ) {
|
1498 |
+
return this.optional( element ) || value <= param;
|
1499 |
},
|
1500 |
|
1501 |
+
// https://jqueryvalidation.org/range-method/
|
1502 |
range: function( value, element, param ) {
|
1503 |
+
return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] );
|
1504 |
},
|
1505 |
|
1506 |
+
// https://jqueryvalidation.org/step-method/
|
1507 |
+
step: function( value, element, param ) {
|
1508 |
+
var type = $( element ).attr( "type" ),
|
1509 |
+
errorMessage = "Step attribute on input type " + type + " is not supported.",
|
1510 |
+
supportedTypes = [ "text", "number", "range" ],
|
1511 |
+
re = new RegExp( "\\b" + type + "\\b" ),
|
1512 |
+
notSupported = type && !re.test( supportedTypes.join() ),
|
1513 |
+
decimalPlaces = function( num ) {
|
1514 |
+
var match = ( "" + num ).match( /(?:\.(\d+))?$/ );
|
1515 |
+
if ( !match ) {
|
1516 |
+
return 0;
|
1517 |
+
}
|
1518 |
|
1519 |
+
// Number of digits right of decimal point.
|
1520 |
+
return match[ 1 ] ? match[ 1 ].length : 0;
|
1521 |
+
},
|
1522 |
+
toInt = function( num ) {
|
1523 |
+
return Math.round( num * Math.pow( 10, decimals ) );
|
1524 |
+
},
|
1525 |
+
valid = true,
|
1526 |
+
decimals;
|
1527 |
+
|
1528 |
+
// Works only for text, number and range input types
|
1529 |
+
// TODO find a way to support input types date, datetime, datetime-local, month, time and week
|
1530 |
+
if ( notSupported ) {
|
1531 |
+
throw new Error( errorMessage );
|
1532 |
+
}
|
1533 |
|
1534 |
+
decimals = decimalPlaces( param );
|
|
|
|
|
|
|
1535 |
|
1536 |
+
// Value can't have too many decimals
|
1537 |
+
if ( decimalPlaces( value ) > decimals || toInt( value ) % toInt( param ) !== 0 ) {
|
1538 |
+
valid = false;
|
1539 |
+
}
|
1540 |
|
1541 |
+
return this.optional( element ) || valid;
|
|
|
|
|
1542 |
},
|
1543 |
|
1544 |
+
// https://jqueryvalidation.org/equalTo-method/
|
1545 |
+
equalTo: function( value, element, param ) {
|
1546 |
+
|
1547 |
+
// Bind to the blur event of the target in order to revalidate whenever the target field is updated
|
1548 |
+
var target = $( param );
|
1549 |
+
if ( this.settings.onfocusout && target.not( ".validate-equalTo-blur" ).length ) {
|
1550 |
+
target.addClass( "validate-equalTo-blur" ).on( "blur.validate-equalTo", function() {
|
1551 |
+
$( element ).valid();
|
1552 |
+
} );
|
1553 |
+
}
|
1554 |
+
return value === target.val();
|
1555 |
},
|
1556 |
|
1557 |
+
// https://jqueryvalidation.org/remote-method/
|
1558 |
+
remote: function( value, element, param, method ) {
|
1559 |
+
if ( this.optional( element ) ) {
|
|
|
1560 |
return "dependency-mismatch";
|
1561 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1562 |
|
1563 |
+
method = typeof method === "string" && method || "remote";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1564 |
|
1565 |
+
var previous = this.previousValue( element, method ),
|
1566 |
+
validator, data, optionDataString;
|
1567 |
|
1568 |
+
if ( !this.settings.messages[ element.name ] ) {
|
1569 |
+
this.settings.messages[ element.name ] = {};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1570 |
}
|
1571 |
+
previous.originalMessage = previous.originalMessage || this.settings.messages[ element.name ][ method ];
|
1572 |
+
this.settings.messages[ element.name ][ method ] = previous.message;
|
1573 |
|
1574 |
+
param = typeof param === "string" && { url: param } || param;
|
1575 |
+
optionDataString = $.param( $.extend( { data: value }, param.data ) );
|
1576 |
+
if ( previous.old === optionDataString ) {
|
1577 |
+
return previous.valid;
|
1578 |
+
}
|
1579 |
|
1580 |
+
previous.old = optionDataString;
|
1581 |
+
validator = this;
|
1582 |
+
this.startRequest( element );
|
1583 |
+
data = {};
|
1584 |
+
data[ element.name ] = value;
|
1585 |
+
$.ajax( $.extend( true, {
|
1586 |
+
mode: "abort",
|
1587 |
+
port: "validate" + element.name,
|
1588 |
+
dataType: "json",
|
1589 |
+
data: data,
|
1590 |
+
context: validator.currentForm,
|
1591 |
+
success: function( response ) {
|
1592 |
+
var valid = response === true || response === "true",
|
1593 |
+
errors, message, submitted;
|
1594 |
|
1595 |
+
validator.settings.messages[ element.name ][ method ] = previous.originalMessage;
|
1596 |
+
if ( valid ) {
|
1597 |
+
submitted = validator.formSubmitted;
|
1598 |
+
validator.resetInternals();
|
1599 |
+
validator.toHide = validator.errorsFor( element );
|
1600 |
+
validator.formSubmitted = submitted;
|
1601 |
+
validator.successList.push( element );
|
1602 |
+
validator.invalid[ element.name ] = false;
|
1603 |
+
validator.showErrors();
|
1604 |
+
} else {
|
1605 |
+
errors = {};
|
1606 |
+
message = response || validator.defaultMessage( element, { method: method, parameters: value } );
|
1607 |
+
errors[ element.name ] = previous.message = message;
|
1608 |
+
validator.invalid[ element.name ] = true;
|
1609 |
+
validator.showErrors( errors );
|
1610 |
+
}
|
1611 |
+
previous.valid = valid;
|
1612 |
+
validator.stopRequest( element, valid );
|
1613 |
+
}
|
1614 |
+
}, param ) );
|
1615 |
+
return "pending";
|
1616 |
+
}
|
1617 |
+
}
|
1618 |
|
1619 |
+
} );
|
1620 |
|
1621 |
+
// Ajax mode: abort
|
1622 |
// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
|
1623 |
// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
|
1624 |
+
|
1625 |
+
var pendingRequests = {},
|
1626 |
+
ajax;
|
1627 |
+
|
1628 |
+
// Use a prefilter if available (1.5+)
|
1629 |
+
if ( $.ajaxPrefilter ) {
|
1630 |
+
$.ajaxPrefilter( function( settings, _, xhr ) {
|
1631 |
+
var port = settings.port;
|
1632 |
+
if ( settings.mode === "abort" ) {
|
1633 |
+
if ( pendingRequests[ port ] ) {
|
1634 |
+
pendingRequests[ port ].abort();
|
1635 |
}
|
1636 |
+
pendingRequests[ port ] = xhr;
|
1637 |
+
}
|
1638 |
+
} );
|
1639 |
+
} else {
|
1640 |
+
|
1641 |
+
// Proxy ajax
|
1642 |
+
ajax = $.ajax;
|
1643 |
+
$.ajax = function( settings ) {
|
1644 |
+
var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
|
1645 |
+
port = ( "port" in settings ? settings : $.ajaxSettings ).port;
|
1646 |
+
if ( mode === "abort" ) {
|
1647 |
+
if ( pendingRequests[ port ] ) {
|
1648 |
+
pendingRequests[ port ].abort();
|
1649 |
}
|
1650 |
+
pendingRequests[ port ] = ajax.apply( this, arguments );
|
1651 |
+
return pendingRequests[ port ];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1652 |
}
|
1653 |
+
return ajax.apply( this, arguments );
|
1654 |
+
};
|
1655 |
+
}
|
1656 |
+
return $;
|
1657 |
+
}));
|
js/jquery.validate.min.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
/*! jQuery Validation Plugin - v1.
|
2 |
-
* https://
|
3 |
-
* Copyright (c)
|
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);
|
1 |
+
/*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
|
2 |
+
* https://jqueryvalidation.org/
|
3 |
+
* Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
|
4 |
+
!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){a.extend(a.fn,{validate:function(b){if(!this.length)return void(b&&b.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing."));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.on("click.validate",":submit",function(b){c.submitButton=b.currentTarget,a(this).hasClass("cancel")&&(c.cancelSubmit=!0),void 0!==a(this).attr("formnovalidate")&&(c.cancelSubmit=!0)}),this.on("submit.validate",function(b){function d(){var d,e;return c.submitButton&&(c.settings.submitHandler||c.formSubmitted)&&(d=a("<input type='hidden'/>").attr("name",c.submitButton.name).val(a(c.submitButton).val()).appendTo(c.currentForm)),!(c.settings.submitHandler&&!c.settings.debug)||(e=c.settings.submitHandler.call(c,c.currentForm,b),d&&d.remove(),void 0!==e&&e)}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(){var b,c,d;return a(this[0]).is("form")?b=this.validate().form():(d=[],b=!0,c=a(this[0].form).validate(),this.each(function(){b=c.element(this)&&b,b||(d=d.concat(c.errorList))}),c.errorList=d),b},rules:function(b,c){var d,e,f,g,h,i,j=this[0],k="undefined"!=typeof this.attr("contenteditable")&&"false"!==this.attr("contenteditable");if(null!=j&&(!j.form&&k&&(j.form=this.closest("form")[0],j.name=this.attr("name")),null!=j.form)){if(b)switch(d=a.data(j.form,"validator").settings,e=d.rules,f=a.validator.staticRules(j),b){case"add":a.extend(f,a.validator.normalizeRule(c)),delete f.messages,e[j.name]=f,c.messages&&(d.messages[j.name]=a.extend(d.messages[j.name],c.messages));break;case"remove":return c?(i={},a.each(c.split(/\s/),function(a,b){i[b]=f[b],delete f[b]}),i):(delete e[j.name],f)}return g=a.validator.normalizeRules(a.extend({},a.validator.classRules(j),a.validator.attributeRules(j),a.validator.dataRules(j),a.validator.staticRules(j)),j),g.required&&(h=g.required,delete g.required,g=a.extend({required:h},g)),g.remote&&(h=g.remote,delete g.remote,g=a.extend(g,{remote:h})),g}}});var b=function(a){return a.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")};a.extend(a.expr.pseudos||a.expr[":"],{blank:function(c){return!b(""+a(c).val())},filled:function(c){var d=a(c).val();return null!==d&&!!b(""+d)},unchecked:function(b){return!a(b).prop("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 1===arguments.length?function(){var c=a.makeArray(arguments);return c.unshift(b),a.validator.format.apply(this,c)}:void 0===c?b:(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"),function(){return c})}),b)},a.extend(a.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",pendingClass:"pending",validClass:"valid",errorElement:"label",focusCleanup:!1,focusInvalid:!0,errorContainer:a([]),errorLabelContainer:a([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(a){this.lastActive=a,this.settings.focusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass),this.hideThese(this.errorsFor(a)))},onfocusout:function(a){this.checkable(a)||!(a.name in this.submitted)&&this.optional(a)||this.element(a)},onkeyup:function(b,c){var d=[16,17,18,20,35,36,37,38,39,40,45,144,225];9===c.which&&""===this.elementValue(b)||a.inArray(c.keyCode,d)!==-1||(b.name in this.submitted||b.name in this.invalid)&&this.element(b)},onclick:function(a){a.name in this.submitted?this.element(a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).addClass(c).removeClass(d):a(b).addClass(c).removeClass(d)},unhighlight:function(b,c,d){"radio"===b.type?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.",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}."),step:a.validator.format("Please enter a multiple of {0}.")},autoCreateRanges:!1,prototype:{init:function(){function b(b){var c="undefined"!=typeof a(this).attr("contenteditable")&&"false"!==a(this).attr("contenteditable");if(!this.form&&c&&(this.form=a(this).closest("form")[0],this.name=a(this).attr("name")),d===this.form){var e=a.data(this.form,"validator"),f="on"+b.type.replace(/^validate/,""),g=e.settings;g[f]&&!a(this).is(g.ignore)&&g[f].call(e,this,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 c,d=this.currentForm,e=this.groups={};a.each(this.settings.groups,function(b,c){"string"==typeof c&&(c=c.split(/\s/)),a.each(c,function(a,c){e[c]=b})}),c=this.settings.rules,a.each(c,function(b,d){c[b]=a.validator.normalizeRule(d)}),a(this.currentForm).on("focusin.validate focusout.validate keyup.validate",":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'], [type='radio'], [type='checkbox'], [contenteditable], [type='button']",b).on("click.validate","select, option, [type='radio'], [type='checkbox']",b),this.settings.invalidHandler&&a(this.currentForm).on("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){var c,d,e=this.clean(b),f=this.validationTargetFor(e),g=this,h=!0;return void 0===f?delete this.invalid[e.name]:(this.prepareElement(f),this.currentElements=a(f),d=this.groups[f.name],d&&a.each(this.groups,function(a,b){b===d&&a!==f.name&&(e=g.validationTargetFor(g.clean(g.findByName(a))),e&&e.name in g.invalid&&(g.currentElements.push(e),h=g.check(e)&&h))}),c=this.check(f)!==!1,h=h&&c,c?this.invalid[f.name]=!1:this.invalid[f.name]=!0,this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),a(b).attr("aria-invalid",!c)),h},showErrors:function(b){if(b){var c=this;a.extend(this.errorMap,b),this.errorList=a.map(this.errorMap,function(a,b){return{message:a,element:c.findByName(b)[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.invalid={},this.submitted={},this.prepareForm(),this.hideErrors();var b=this.elements().removeData("previousValue").removeAttr("aria-invalid");this.resetElements(b)},resetElements:function(a){var b;if(this.settings.unhighlight)for(b=0;a[b];b++)this.settings.unhighlight.call(this,a[b],this.settings.errorClass,""),this.findByName(a[b].name).removeClass(this.settings.validClass);else a.removeClass(this.settings.errorClass).removeClass(this.settings.validClass)},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b,c=0;for(b in a)void 0!==a[b]&&null!==a[b]&&a[b]!==!1&&c++;return c},hideErrors:function(){this.hideThese(this.toHide)},hideThese:function(a){a.not(this.containers).text(""),this.addWrapper(a).hide()},valid:function(){return 0===this.size()},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").trigger("focus").trigger("focusin")}catch(b){}},findLastActive:function(){var b=this.lastActive;return b&&1===a.grep(this.errorList,function(a){return a.element.name===b.name}).length&&b},elements:function(){var b=this,c={};return a(this.currentForm).find("input, select, textarea, [contenteditable]").not(":submit, :reset, :image, :disabled").not(this.settings.ignore).filter(function(){var d=this.name||a(this).attr("name"),e="undefined"!=typeof a(this).attr("contenteditable")&&"false"!==a(this).attr("contenteditable");return!d&&b.settings.debug&&window.console&&console.error("%o has no name assigned",this),e&&(this.form=a(this).closest("form")[0],this.name=d),this.form===b.currentForm&&(!(d in c||!b.objectLength(a(this).rules()))&&(c[d]=!0,!0))})},clean:function(b){return a(b)[0]},errors:function(){var b=this.settings.errorClass.split(" ").join(".");return a(this.settings.errorElement+"."+b,this.errorContext)},resetInternals:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=a([]),this.toHide=a([])},reset:function(){this.resetInternals(),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,d,e=a(b),f=b.type,g="undefined"!=typeof e.attr("contenteditable")&&"false"!==e.attr("contenteditable");return"radio"===f||"checkbox"===f?this.findByName(b.name).filter(":checked").val():"number"===f&&"undefined"!=typeof b.validity?b.validity.badInput?"NaN":e.val():(c=g?e.text():e.val(),"file"===f?"C:\\fakepath\\"===c.substr(0,12)?c.substr(12):(d=c.lastIndexOf("/"),d>=0?c.substr(d+1):(d=c.lastIndexOf("\\"),d>=0?c.substr(d+1):c)):"string"==typeof c?c.replace(/\r/g,""):c)},check:function(b){b=this.validationTargetFor(this.clean(b));var c,d,e,f,g=a(b).rules(),h=a.map(g,function(a,b){return b}).length,i=!1,j=this.elementValue(b);"function"==typeof g.normalizer?f=g.normalizer:"function"==typeof this.settings.normalizer&&(f=this.settings.normalizer),f&&(j=f.call(b,j),delete g.normalizer);for(d in g){e={method:d,parameters:g[d]};try{if(c=a.validator.methods[d].call(this,j,b,e.parameters),"dependency-mismatch"===c&&1===h){i=!0;continue}if(i=!1,"pending"===c)return void(this.toHide=this.toHide.not(this.errorsFor(b)));if(!c)return this.formatAndAdd(b,e),!1}catch(k){throw this.settings.debug&&window.console&&console.log("Exception occurred when checking element "+b.id+", check the '"+e.method+"' method.",k),k instanceof TypeError&&(k.message+=". Exception occurred when checking element "+b.id+", check the '"+e.method+"' method."),k}}if(!i)return this.objectLength(g)&&this.successList.push(b),!0},customDataMessage:function(b,c){return a(b).data("msg"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase())||a(b).data("msg")},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(void 0!==arguments[a])return arguments[a]},defaultMessage:function(b,c){"string"==typeof c&&(c={method:c});var d=this.findDefined(this.customMessage(b.name,c.method),this.customDataMessage(b,c.method),!this.settings.ignoreTitle&&b.title||void 0,a.validator.messages[c.method],"<strong>Warning: No message defined for "+b.name+"</strong>"),e=/\$?\{(\d+)\}/g;return"function"==typeof d?d=d.call(this,c.parameters,b):e.test(d)&&(d=a.validator.format(d.replace(e,"{$1}"),c.parameters)),d},formatAndAdd:function(a,b){var c=this.defaultMessage(a,b);this.errorList.push({message:c,element:a,method:b.method}),this.errorMap[a.name]=c,this.submitted[a.name]=c},addWrapper:function(a){return this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper))),a},defaultShowErrors:function(){var a,b,c;for(a=0;this.errorList[a];a++)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);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),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,e,f,g,h=this.errorsFor(b),i=this.idOrName(b),j=a(b).attr("aria-describedby");h.length?(h.removeClass(this.settings.validClass).addClass(this.settings.errorClass),h.html(c)):(h=a("<"+this.settings.errorElement+">").attr("id",i+"-error").addClass(this.settings.errorClass).html(c||""),d=h,this.settings.wrapper&&(d=h.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(d):this.settings.errorPlacement?this.settings.errorPlacement.call(this,d,a(b)):d.insertAfter(b),h.is("label")?h.attr("for",i):0===h.parents("label[for='"+this.escapeCssMeta(i)+"']").length&&(f=h.attr("id"),j?j.match(new RegExp("\\b"+this.escapeCssMeta(f)+"\\b"))||(j+=" "+f):j=f,a(b).attr("aria-describedby",j),e=this.groups[b.name],e&&(g=this,a.each(g.groups,function(b,c){c===e&&a("[name='"+g.escapeCssMeta(b)+"']",g.currentForm).attr("aria-describedby",h.attr("id"))})))),!c&&this.settings.success&&(h.text(""),"string"==typeof this.settings.success?h.addClass(this.settings.success):this.settings.success(h,b)),this.toShow=this.toShow.add(h)},errorsFor:function(b){var c=this.escapeCssMeta(this.idOrName(b)),d=a(b).attr("aria-describedby"),e="label[for='"+c+"'], label[for='"+c+"'] *";return d&&(e=e+", #"+this.escapeCssMeta(d).replace(/\s+/g,", #")),this.errors().filter(e)},escapeCssMeta:function(a){return a.replace(/([\\!"#$%&'()*+,.\/:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(b){return this.checkable(b)&&(b=this.findByName(b.name)),a(b).not(this.settings.ignore)[0]},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).find("[name='"+this.escapeCssMeta(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)},dependTypes:{"boolean":function(a){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(b){this.pending[b.name]||(this.pendingRequest++,a(b).addClass(this.settings.pendingClass),this.pending[b.name]=!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[b.name],a(b).removeClass(this.settings.pendingClass),c&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(a(this.currentForm).submit(),this.submitButton&&a("input:hidden[name='"+this.submitButton.name+"']",this.currentForm).remove(),this.formSubmitted=!1):!c&&0===this.pendingRequest&&this.formSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(b,c){return c="string"==typeof c&&c||"remote",a.data(b,"previousValue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMessage(b,{method:c})})},destroy:function(){this.resetForm(),a(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur").find(".validate-lessThan-blur").off(".validate-lessThan").removeClass("validate-lessThan-blur").find(".validate-lessThanEqual-blur").off(".validate-lessThanEqual").removeClass("validate-lessThanEqual-blur").find(".validate-greaterThanEqual-blur").off(".validate-greaterThanEqual").removeClass("validate-greaterThanEqual-blur").find(".validate-greaterThan-blur").off(".validate-greaterThan").removeClass("validate-greaterThan-blur")}},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},normalizeAttributeRule:function(a,b,c,d){/min|max|step/.test(c)&&(null===b||/number|range|text/.test(b))&&(d=Number(d),isNaN(d)&&(d=void 0)),d||0===d?a[c]=d:b===c&&"range"!==b&&(a[c]=!0)},attributeRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)"required"===c?(d=b.getAttribute(c),""===d&&(d=!0),d=!!d):d=f.attr(c),this.normalizeAttributeRule(e,g,c,d);return e.maxlength&&/-1|2147483647|524288/.test(e.maxlength)&&delete e.maxlength,e},dataRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)d=f.data("rule"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase()),""===d&&(d=!0),this.normalizeAttributeRule(e,g,c,d);return e},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)return void delete b[d];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]=void 0===e.param||e.param:(a.data(c.form,"validator").resetElements(a(c)),delete b[d])}}),a.each(b,function(a,d){b[a]="function"==typeof d&&"normalizer"!==a?d(c):d}),a.each(["minlength","maxlength"],function(){b[this]&&(b[this]=Number(b[this]))}),a.each(["rangelength","range"],function(){var a;b[this]&&(Array.isArray(b[this])?b[this]=[Number(b[this][0]),Number(b[this][1])]:"string"==typeof b[this]&&(a=b[this].replace(/[\[\]]/g,"").split(/[\s,]+/),b[this]=[Number(a[0]),Number(a[1])]))}),a.validator.autoCreateRanges&&(null!=b.min&&null!=b.max&&(b.range=[b.min,b.max],delete b.min,delete b.max),null!=b.minlength&&null!=b.maxlength&&(b.rangelength=[b.minlength,b.maxlength],delete b.minlength,delete b.maxlength)),b},normalizeRule:function(b){if("string"==typeof b){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]=void 0!==d?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("select"===c.nodeName.toLowerCase()){var e=a(c).val();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:void 0!==b&&null!==b&&b.length>0},email:function(a,b){return this.optional(b)||/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(a)},url:function(a,b){return this.optional(b)||/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff]\.)+(?:[a-z\u00a1-\uffff]{2,}\.?))(?::\d{2,5})?(?:[\/?#]\S*)?$/i.test(a)},date:function(){var a=!1;return function(b,c){return a||(a=!0,this.settings.debug&&window.console&&console.warn("The `date` method is deprecated and will be removed in version '2.0.0'.\nPlease don't use it, since it relies on the Date constructor, which\nbehaves very differently across browsers and locales. Use `dateISO`\ninstead or one of the locale specific methods in `localizations/`\nand `additional-methods.js`.")),this.optional(c)||!/Invalid|NaN/.test(new Date(b).toString())}}(),dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.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)},minlength:function(a,b,c){var d=Array.isArray(a)?a.length:this.getLength(a,b);return this.optional(b)||d>=c},maxlength:function(a,b,c){var d=Array.isArray(a)?a.length:this.getLength(a,b);return this.optional(b)||d<=c},rangelength:function(a,b,c){var d=Array.isArray(a)?a.length:this.getLength(a,b);return this.optional(b)||d>=c[0]&&d<=c[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]},step:function(b,c,d){var e,f=a(c).attr("type"),g="Step attribute on input type "+f+" is not supported.",h=["text","number","range"],i=new RegExp("\\b"+f+"\\b"),j=f&&!i.test(h.join()),k=function(a){var b=(""+a).match(/(?:\.(\d+))?$/);return b&&b[1]?b[1].length:0},l=function(a){return Math.round(a*Math.pow(10,e))},m=!0;if(j)throw new Error(g);return e=k(d),(k(b)>e||l(b)%l(d)!==0)&&(m=!1),this.optional(c)||m},equalTo:function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.not(".validate-equalTo-blur").length&&e.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){a(c).valid()}),b===e.val()},remote:function(b,c,d,e){if(this.optional(c))return"dependency-mismatch";e="string"==typeof e&&e||"remote";var f,g,h,i=this.previousValue(c,e);return this.settings.messages[c.name]||(this.settings.messages[c.name]={}),i.originalMessage=i.originalMessage||this.settings.messages[c.name][e],this.settings.messages[c.name][e]=i.message,d="string"==typeof d&&{url:d}||d,h=a.param(a.extend({data:b},d.data)),i.old===h?i.valid:(i.old=h,f=this,this.startRequest(c),g={},g[c.name]=b,a.ajax(a.extend(!0,{mode:"abort",port:"validate"+c.name,dataType:"json",data:g,context:f.currentForm,success:function(a){var d,g,h,j=a===!0||"true"===a;f.settings.messages[c.name][e]=i.originalMessage,j?(h=f.formSubmitted,f.resetInternals(),f.toHide=f.errorsFor(c),f.formSubmitted=h,f.successList.push(c),f.invalid[c.name]=!1,f.showErrors()):(d={},g=a||f.defaultMessage(c,{method:e,parameters:b}),d[c.name]=i.message=g,f.invalid[c.name]=!0,f.showErrors(d)),i.valid=j,f.stopRequest(c,j)}},d)),"pending")}}});var c,d={};return a.ajaxPrefilter?a.ajaxPrefilter(function(a,b,c){var e=a.port;"abort"===a.mode&&(d[e]&&d[e].abort(),d[e]=c)}):(c=a.ajax,a.ajax=function(b){var e=("mode"in b?b:a.ajaxSettings).mode,f=("port"in b?b:a.ajaxSettings).port;return"abort"===e?(d[f]&&d[f].abort(),d[f]=c.apply(this,arguments),d[f]):c.apply(this,arguments)}),a});
|
languages/clean-and-simple-contact-form-by-meg-nicholas_pl_PL.mo
DELETED
Binary file
|
readme.txt
CHANGED
@@ -1,431 +1,427 @@
|
|
1 |
-
=== Contact Form Clean and Simple ===
|
2 |
-
Contributors:
|
3 |
-
|
4 |
-
License:
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
Stable tag: 4.7.
|
10 |
-
|
11 |
-
A clean and simple AJAX contact form with Google reCAPTCHA, Twitter Bootstrap markup and Akismet spam filtering.
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
For added piece of mind this plugin also allows you to add a ‘**reCAPTCHA**’.
|
40 |
-
This adds a picture of a couple of words to the bottom of the contact form.
|
41 |
-
Your user must correctly type the words before the form can be submitted, and in so doing, prove that they are human.
|
42 |
-
|
43 |
-
= Why Choose This Plugin? =
|
44 |
-
Granted there are many plugins of this type in existence already. Why use this one in-particular?
|
45 |
-
|
46 |
-
Here’s why:
|
47 |
-
|
48 |
-
* Minimal setup. Simply activate the plugin and place the shortcode [cscf-contact-form] on any post or page.
|
49 |
-
|
50 |
-
* **Safe**. All input entered by your user is stripped back to minimise as far as possible the likelihood of any
|
51 |
-
malicious user attempting to inject a script into your website.
|
52 |
-
If the Akismet plugin is activated all form data will be scanned for spam.
|
53 |
-
You can turn on reCAPTCHA to avoid your form being abused by bots.
|
54 |
-
|
55 |
-
* **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.
|
56 |
-
|
57 |
-
* 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.
|
58 |
-
|
59 |
-
* If your theme is based on **twitter bootstrap** then this plugin will fit right in because it already has all the right div’s and CSS classes for bootstrap.
|
60 |
-
|
61 |
-
* This plugin will only link in its jQuery file where it’s needed, it **will not impose** itself on every page of your whole site!
|
62 |
-
|
63 |
-
* Works with the **latest version of WordPress**.
|
64 |
-
|
65 |
-
*
|
66 |
-
|
67 |
-
Hopefully this plugin will fulfil all your needs
|
68 |
-
|
69 |
-
|
70 |
-
== Installation ==
|
71 |
-
There are two ways to install:
|
72 |
-
|
73 |
-
1. Click the ‘Install Now’ link from the plugin library listing to automatically download and install.
|
74 |
-
|
75 |
-
2. Download the plugin as a zip file. To install the zip file simply double click to extract it and place the whole folder in your wordpress plugins folder, e.g. [wordpress]/wp-content/plugins where [wordpress] is the directory that you installed WordPress in.
|
76 |
-
|
77 |
-
Then visit the plugin page on your wordpress site and click ‘Activate’ against the ‘Clean and Simple Contact Form’ plugin listing.
|
78 |
-
|
79 |
-
To place the contact form on your page use the shortcode [cscf-contact-form]
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
* **Message**: The message displayed to the user
|
104 |
-
|
105 |
-
* **
|
106 |
-
|
107 |
-
* **
|
108 |
-
|
109 |
-
* **Use this
|
110 |
-
|
111 |
-
* **
|
112 |
-
|
113 |
-
* **
|
114 |
-
|
115 |
-
* **reCAPTCHA
|
116 |
-
|
117 |
-
* **
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
If you
|
124 |
-
|
125 |
-
|
126 |
-
* **
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
* **
|
131 |
-
|
132 |
-
* **
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
*
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
*
|
215 |
-
= 4.6.
|
216 |
-
*
|
217 |
-
|
218 |
-
*
|
219 |
-
|
220 |
-
*
|
221 |
-
*
|
222 |
-
*
|
223 |
-
|
224 |
-
*
|
225 |
-
*
|
226 |
-
|
227 |
-
|
228 |
-
*
|
229 |
-
*
|
230 |
-
|
231 |
-
*
|
232 |
-
|
233 |
-
* Added
|
234 |
-
*
|
235 |
-
*
|
236 |
-
|
237 |
-
*
|
238 |
-
|
239 |
-
*
|
240 |
-
|
241 |
-
*
|
242 |
-
|
243 |
-
*
|
244 |
-
= 4.4.
|
245 |
-
*
|
246 |
-
|
247 |
-
*
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
*
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
*
|
256 |
-
|
257 |
-
*
|
258 |
-
|
259 |
-
* Added
|
260 |
-
*
|
261 |
-
|
262 |
-
|
263 |
-
*
|
264 |
-
*
|
265 |
-
|
266 |
-
*
|
267 |
-
|
268 |
-
*
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
= 4.2.
|
278 |
-
*
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
*
|
284 |
-
|
285 |
-
*
|
286 |
-
|
287 |
-
|
288 |
-
*
|
289 |
-
*
|
290 |
-
|
291 |
-
|
292 |
-
*
|
293 |
-
*
|
294 |
-
|
295 |
-
|
296 |
-
*
|
297 |
-
|
298 |
-
|
299 |
-
= 4.1.
|
300 |
-
* Added
|
301 |
-
|
302 |
-
|
303 |
-
= 4.1.
|
304 |
-
* Added
|
305 |
-
*
|
306 |
-
*
|
307 |
-
|
308 |
-
|
309 |
-
* Added
|
310 |
-
*
|
311 |
-
*
|
312 |
-
= 4.1.
|
313 |
-
*
|
314 |
-
*
|
315 |
-
|
316 |
-
|
317 |
-
*
|
318 |
-
|
319 |
-
|
320 |
-
* Added
|
321 |
-
*
|
322 |
-
|
323 |
-
*
|
324 |
-
* Added
|
325 |
-
|
326 |
-
|
327 |
-
*
|
328 |
-
* Added
|
329 |
-
|
330 |
-
|
331 |
-
*
|
332 |
-
*
|
333 |
-
*
|
334 |
-
*
|
335 |
-
*
|
336 |
-
*
|
337 |
-
*
|
338 |
-
|
339 |
-
*
|
340 |
-
*
|
341 |
-
*
|
342 |
-
= 4.1.
|
343 |
-
* Fixed
|
344 |
-
|
345 |
-
*
|
346 |
-
|
347 |
-
*
|
348 |
-
= 4.0.
|
349 |
-
*
|
350 |
-
*
|
351 |
-
*
|
352 |
-
|
353 |
-
|
354 |
-
* Fixed a bug:
|
355 |
-
*
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
= 4.
|
364 |
-
|
365 |
-
= 4.
|
366 |
-
|
367 |
-
= 4.
|
368 |
-
|
369 |
-
= 4.
|
370 |
-
|
371 |
-
= 4.
|
372 |
-
|
373 |
-
= 4.4.
|
374 |
-
|
375 |
-
= 4.4.
|
376 |
-
|
377 |
-
= 4.4.
|
378 |
-
|
379 |
-
= 4.4
|
380 |
-
|
381 |
-
= 4.
|
382 |
-
|
383 |
-
= 4.3.
|
384 |
-
|
385 |
-
= 4.3.
|
386 |
-
|
387 |
-
= 4.3.
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
= 4.2.
|
395 |
-
|
396 |
-
= 4.2.
|
397 |
-
|
398 |
-
= 4.2.
|
399 |
-
|
400 |
-
= 4.2.
|
401 |
-
|
402 |
-
= 4.
|
403 |
-
|
404 |
-
= 4.
|
405 |
-
|
406 |
-
= 4.1.
|
407 |
-
|
408 |
-
= 4.1.
|
409 |
-
|
410 |
-
= 4.1.
|
411 |
-
|
412 |
-
= 4.1.
|
413 |
-
|
414 |
-
= 4.1.
|
415 |
-
|
416 |
-
= 4.1.
|
417 |
-
|
418 |
-
= 4.1.
|
419 |
-
|
420 |
-
= 4.1.
|
421 |
-
|
422 |
-
= 4.
|
423 |
-
|
424 |
-
= 4.
|
425 |
-
|
426 |
-
= 4.0.
|
427 |
-
|
428 |
-
= 4.0.8 =
|
429 |
-
Ajax now works when your form has reCAPTCHA on it. Ajax validation is now cleaner.
|
430 |
-
= 4.0.7 =
|
431 |
-
Fixed a bug which occurred when plugin name was changed. reCAPTCHA will now use ssl if your webpage is ssl.
|
1 |
+
=== Contact Form Clean and Simple ===
|
2 |
+
Contributors: fullworks
|
3 |
+
License: GPLv2 or later
|
4 |
+
License URI: http://www.gnu.org/licenses/gpl.html
|
5 |
+
Tags: simple, contact, form, contact button, contact form, contact form plugin, akismet, contacts, contacts form plugin, contact me, feedback form, bootstrap, twitter, google, reCAPTCHA, ajax, secure
|
6 |
+
Requires at least: 4.6
|
7 |
+
Tested up to: 5.7
|
8 |
+
Requires PHP: 5.6
|
9 |
+
Stable tag: 4.7.2
|
10 |
+
|
11 |
+
A clean and simple AJAX contact form with Google reCAPTCHA, Twitter Bootstrap markup and Akismet spam filtering.
|
12 |
+
|
13 |
+
|
14 |
+
== Description ==
|
15 |
+
A clean and simple AJAX contact form with Google reCAPTCHA, Twitter Bootstrap markup and Akismet spam filtering.
|
16 |
+
|
17 |
+
* **Clean**: all user inputs are stripped in order to avoid cross-site scripting (XSS) vulnerabilities.
|
18 |
+
|
19 |
+
* **Simple**: AJAX enabled validation and submission for immediate response and guidance for your users (can be switched off).
|
20 |
+
|
21 |
+
* **Stylish**: Use the included stylesheet or switch it off and use your own for seamless integration with your website.
|
22 |
+
Uses **Twitter Bootstrap** classes.
|
23 |
+
|
24 |
+
* **Safe**: All incoming data is scanned for spam with **Akismet**.
|
25 |
+
|
26 |
+
This is a straightforward contact form for your WordPress site. There is very minimal set-up
|
27 |
+
required. Simply install, activate, and then place the short code **[cscf-contact-form]** on your web page.
|
28 |
+
|
29 |
+
A standard set of input boxes are provided, these include Email Address, Name, Message and a nice big ‘Send Message’ button.
|
30 |
+
|
31 |
+
When your user has completed the form an email will be sent to you containing your user’s message.
|
32 |
+
To reply simply click the ‘reply’ button on your email client.
|
33 |
+
The email address used is the one you have set up in WordPress under ‘Settings’ -> ‘General’, so do check this is correct.
|
34 |
+
|
35 |
+
To help prevent spam all data is scanned via Akismet.
|
36 |
+
For this to work you must have the [Akismet Plugin](http://wordpress.org/plugins/akismet/ "Akismet Plugin") installed and activated.
|
37 |
+
All spam will be placed in your 'comments' list which you can then review if you want to,
|
38 |
+
|
39 |
+
For added piece of mind this plugin also allows you to add a ‘**reCAPTCHA**’.
|
40 |
+
This adds a picture of a couple of words to the bottom of the contact form.
|
41 |
+
Your user must correctly type the words before the form can be submitted, and in so doing, prove that they are human.
|
42 |
+
|
43 |
+
= Why Choose This Plugin? =
|
44 |
+
Granted there are many plugins of this type in existence already. Why use this one in-particular?
|
45 |
+
|
46 |
+
Here’s why:
|
47 |
+
|
48 |
+
* Minimal setup. Simply activate the plugin and place the shortcode [cscf-contact-form] on any post or page.
|
49 |
+
|
50 |
+
* **Safe**. All input entered by your user is stripped back to minimise as far as possible the likelihood of any
|
51 |
+
malicious user attempting to inject a script into your website.
|
52 |
+
If the Akismet plugin is activated all form data will be scanned for spam.
|
53 |
+
You can turn on reCAPTCHA to avoid your form being abused by bots.
|
54 |
+
|
55 |
+
* **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.
|
56 |
+
|
57 |
+
* 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.
|
58 |
+
|
59 |
+
* If your theme is based on **twitter bootstrap** then this plugin will fit right in because it already has all the right div’s and CSS classes for bootstrap.
|
60 |
+
|
61 |
+
* This plugin will only link in its jQuery file where it’s needed, it **will not impose** itself on every page of your whole site!
|
62 |
+
|
63 |
+
* Works with the **latest version of WordPress**.
|
64 |
+
|
65 |
+
* Original plugin written by an **experienced PHP programmer**, Megan Nicholas, the code is rock solid, safe, and rigorously tested as standard practice.
|
66 |
+
|
67 |
+
Hopefully this plugin will fulfil all your needs.
|
68 |
+
|
69 |
+
|
70 |
+
== Installation ==
|
71 |
+
There are two ways to install:
|
72 |
+
|
73 |
+
1. Click the ‘Install Now’ link from the plugin library listing to automatically download and install.
|
74 |
+
|
75 |
+
2. Download the plugin as a zip file. To install the zip file simply double click to extract it and place the whole folder in your wordpress plugins folder, e.g. [wordpress]/wp-content/plugins where [wordpress] is the directory that you installed WordPress in.
|
76 |
+
|
77 |
+
Then visit the plugin page on your wordpress site and click ‘Activate’ against the ‘Clean and Simple Contact Form’ plugin listing.
|
78 |
+
|
79 |
+
To place the contact form on your page use the shortcode [cscf-contact-form]
|
80 |
+
|
81 |
+
== How to Use ==
|
82 |
+
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.
|
83 |
+
|
84 |
+
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.
|
85 |
+
|
86 |
+
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.
|
87 |
+
|
88 |
+
**If you have Jetpack plugin installed disable the contact form otherwise the wrong form might display.**
|
89 |
+
|
90 |
+
== Additional Settings ==
|
91 |
+
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.
|
92 |
+
|
93 |
+
Go to the settings screen for the contact form plugin.
|
94 |
+
|
95 |
+
You will find a link to the setting screen against the entry of this plugin on the ‘Installed Plugins’ page.
|
96 |
+
|
97 |
+
Here is a list of things that you can change
|
98 |
+
|
99 |
+
* **Message**: The message displayed to the user at the top of the contact form.
|
100 |
+
|
101 |
+
* **Message Sent Heading**: The message heading or title displayed to the user after the message has been sent.
|
102 |
+
|
103 |
+
* **Message Sent Content**: The message content or body displayed to the user after the message has been sent.
|
104 |
+
|
105 |
+
* **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.
|
106 |
+
|
107 |
+
* **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.
|
108 |
+
|
109 |
+
* **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
|
110 |
+
|
111 |
+
* **reCAPTCHA Public Key**: Enter the public key that you obtained from here.
|
112 |
+
|
113 |
+
* **reCAPTCHA Private Key**: Enter the private key that you obtained from here.
|
114 |
+
|
115 |
+
* **reCAPTCHA Theme**: Here you can change the reCAPTCHA box theme so that it fits with the style of your website.
|
116 |
+
|
117 |
+
* **Recipient Emails**: The email address where you would like all messages to be sent.
|
118 |
+
This will default to the email address you have specified under 'E-Mail Address' in your WordPress General Settings.
|
119 |
+
If you want your mail sent to a different address then enter it here.
|
120 |
+
You may enter multiple email addresses by clicking the '+' button.
|
121 |
+
|
122 |
+
* **Confirm Email Address**: Email confirmation is now optional. To force your user to re-type their email address tick 'Confirm Email Address'.
|
123 |
+
It is recommended that you leave this option on. If you turn this option off your user will only have to enter their email address once,
|
124 |
+
but if they enter it incorrectly you will have no way of getting back to them!
|
125 |
+
|
126 |
+
* **Email Subject**: This is the email subject that will appear on all messages. If you would like to set it to something different then enter it here.
|
127 |
+
|
128 |
+
* **Override 'From' Address**: If you tick this and then fill in the 'From Address:' box then all email will be sent from the given address NOT from the email address given by the form filler.
|
129 |
+
|
130 |
+
* **Option to allow enquiry to email themselves a copy of the message.
|
131 |
+
|
132 |
+
* **Contact consent**: This option allows you to be GDPR compliant by adding a 'Consent to contact' check box at the bottom of the form.
|
133 |
+
|
134 |
+
|
135 |
+
== Screenshots ==
|
136 |
+
1. Contact Form With reCAPTCHA
|
137 |
+
2. Contact Form Without reCAPTCHA
|
138 |
+
3. Message Sent
|
139 |
+
4. Contact Form Options Screen
|
140 |
+
5. Place this shortcode on your post or page to deploy
|
141 |
+
|
142 |
+
== Demo ==
|
143 |
+
Demo site coming soon.
|
144 |
+
|
145 |
+
== Frequently Asked Questions ==
|
146 |
+
= I get a message to say that the message could not be sent =
|
147 |
+
|
148 |
+
If you get this message then you have a general problem with email on your server. This plugin uses Wordpress's send mail function.
|
149 |
+
So a problem sending mail from this plugin indicates that Wordpress as a whole cannot send email.
|
150 |
+
Contact your web host provider for help, or use an SMTP plugin to use a third party email service.
|
151 |
+
|
152 |
+
= I don't receive the email =
|
153 |
+
|
154 |
+
* Check the recipient email on your settings screen, is it correct?
|
155 |
+
* Check in your spam or junk mail folder
|
156 |
+
* For Gmail check in 'All Mail', the email might have gone straight to archive
|
157 |
+
* Try overriding the 'From' email address in the settings screen. Use an email address you own or is from your own domain
|
158 |
+
|
159 |
+
= Why is a different contact form displayed? =
|
160 |
+
|
161 |
+
You may have a conflict with another plugin. Either deactivate the other contact form plugin, if you don't need it, or use
|
162 |
+
this alternative short code on your webpage - `[cscf-contact-form]`.
|
163 |
+
This problem often occurs when Jetpack plugin is installed.
|
164 |
+
|
165 |
+
= How do I display the contact form on my page/post? =
|
166 |
+
|
167 |
+
To put the contact form on your page, add the text:
|
168 |
+
`[cscf-contact-form]`
|
169 |
+
|
170 |
+
The contact form will appear when you view the page.
|
171 |
+
|
172 |
+
= When I use the style sheet that comes with the plugin my theme is affected =
|
173 |
+
|
174 |
+
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
|
175 |
+
screen so you can add your own styles to your theme's stylesheet.
|
176 |
+
|
177 |
+
= Can I have this plugin in my own language? =
|
178 |
+
|
179 |
+
Yes, I am currently building up translation files for this plugin.
|
180 |
+
If your language is not yet available you are very welcome to translate it.
|
181 |
+
|
182 |
+
= How do I change the text box sizes? =
|
183 |
+
|
184 |
+
The plugin now uses Bootstrap 3. The text box widths now use up 100% of the available width.
|
185 |
+
This makes the form responsive to all types of media. If you want to have a fixed width for the form you can put some styling around the shortcode:
|
186 |
+
`<div style="width:600px;">[cscf-contact-form]</div>`
|
187 |
+
|
188 |
+
= Can I have multiple forms? =
|
189 |
+
|
190 |
+
Currently you may only have one contact form per page. You CAN however put the contact form on more than one page using the same shortcode.
|
191 |
+
Note that making changes to the settings will affect all implementations of the plugin across your site.
|
192 |
+
|
193 |
+
= Will this work with other plugins that use Google reCAPTCHA? =
|
194 |
+
Yes it will. HOWEVER, you cannot have more than one reCAPTCHA on a page. This is a constraint created by Google.
|
195 |
+
So for example, if your 'Contact Me' page has comments below it,
|
196 |
+
the reCAPTCHA for the contact form will be displayed correctly but not in the comments form below.
|
197 |
+
The comments form will never validate due to no supplied reCAPTCHA code.
|
198 |
+
|
199 |
+
== Changelog ==
|
200 |
+
= 4.7.2 =
|
201 |
+
* Updated santization and escaping to current plugin directory recommendations
|
202 |
+
* add email header to specify text to improve formatting
|
203 |
+
* tested up to 5.8 beta 2 and PHP 8.0
|
204 |
+
|
205 |
+
= 4.7.1 =
|
206 |
+
* Tested with Wordpress version 5.3
|
207 |
+
Fixed XSS vulnerability in GDPR consent message
|
208 |
+
= 4.7.0 =
|
209 |
+
* Tested with Wordpress version 4.9.6
|
210 |
+
* Added consent to contact checkbox for GDPR compliance
|
211 |
+
= 4.6.2 =
|
212 |
+
* Turkish translation update. Thanks to Abdullah Manaz! Tested up to WordPress 4.6.1.
|
213 |
+
= 4.6.1 =
|
214 |
+
* Fixed untranslated strings. Thanks to Abdullah Manaz!
|
215 |
+
= 4.6.0 =
|
216 |
+
* Prevent multiple 'send message' clicks.
|
217 |
+
* Changed text domain to plugin slug to allow for WP translation system import
|
218 |
+
* Removed advertising from settings screen
|
219 |
+
* Added Korean translation thanks to Lee Dae-yeop
|
220 |
+
* Added Romanian translation. Thanks to Marius Pruna.
|
221 |
+
* Update French translation thanks to Steph
|
222 |
+
* Added Hungarian translation. Thanks to János Sánta.
|
223 |
+
= 4.5.1 =
|
224 |
+
* Updated Polish translations thanks to Kacper
|
225 |
+
* Updated French translation
|
226 |
+
= 4.5.0 =
|
227 |
+
* Added support for google recaptcha2. Replaces recaptcha version 1
|
228 |
+
* Update to Italian translation thanks to Silvano
|
229 |
+
* Added back the DIV to the contact form view as this introduced a display issue
|
230 |
+
* Updated German translation thanks to schasoli
|
231 |
+
* Polish translation update thanks to Kacper Rucinski
|
232 |
+
= 4.4.4 =
|
233 |
+
* Added Serbian translation thanks to [Borisa Djuraskovic](http://www.webhostinghub.com "Borisa Djuraskovic")
|
234 |
+
* Added Slovenian translation thanks to Bekim Lutolli
|
235 |
+
* Fixed some 'notice' errors
|
236 |
+
* Recaptcha styling workaround for twenty fifteen theme
|
237 |
+
* Remove empty divs from view
|
238 |
+
= 4.4.3 =
|
239 |
+
* Remove branding
|
240 |
+
= 4.4.2 =
|
241 |
+
* Akismet tweak only log as spam if akismet_result = 'true'
|
242 |
+
* Updated Turkish translations thanks again to [Abdullah Manaz](http://manaz.net "Abdullah Manaz")
|
243 |
+
* Added Indonesian translations thanks to Beny Hirmansyah
|
244 |
+
= 4.4.0 =
|
245 |
+
* Fixed XSS issue
|
246 |
+
= 4.4.1 =
|
247 |
+
* Add option for enquiry to email themselves a copy of the message
|
248 |
+
* Update to Polish translation thanks to Radosław “Robaczek” Rak
|
249 |
+
= 4.3.4 =
|
250 |
+
* Added the wordpress page of contact form to the email
|
251 |
+
* Removed link in main contact form view
|
252 |
+
= 4.3.3 =
|
253 |
+
* Before overriding the from address, check that another plugin has not done it first.
|
254 |
+
Any plugin that overrides 'from email address' and 'from name' such as wp-mail-smtp plugin will take precedence over the settings in this plugin.
|
255 |
+
* Added 'reply-to' to the email header
|
256 |
+
* Moved the Name field before Email field
|
257 |
+
* Added Hebrew translation thanks to Shay Cohen
|
258 |
+
= 4.3.2 =
|
259 |
+
* Added Norwegian Bokmål translation thanks to Jann Vestby
|
260 |
+
* Added Brazilian Portugese translation originally a Portugese translation by Ricardo Santos aka BogasoBogolha
|
261 |
+
= 4.3.1 =
|
262 |
+
* Polish translation has been updated thanks to Arkadiusz Baron
|
263 |
+
* Updated Turkish translations thanks again to [Abdullah Manaz](http://manaz.net "Abdullah Manaz")
|
264 |
+
* New installations now have default stylesheet, ajax, and confirm-email options turned on
|
265 |
+
* Compatibility with WordPress 3.8
|
266 |
+
* Tested with twentyfourteen theme
|
267 |
+
= 4.3.0 =
|
268 |
+
* Contact form is now filtered for spam when the Akisturkishturkishturkmet plugin is present.
|
269 |
+
[Learn more](http://www.megnicholas.co.uk/articles/contact-form-plugin-can-detect-spam/ "Learn More").
|
270 |
+
= 4.2.5 =
|
271 |
+
* Fixed bug that caused a PHP notice to be generated when 'Confirm Email Message' option is switched off.
|
272 |
+
Thanks to MarrsAttax
|
273 |
+
= 4.2.4 =
|
274 |
+
* The requirement for users to confirm their email address is now optional.
|
275 |
+
When turned off users only need to enter their email address once.
|
276 |
+
* Added Arabic translation thanks to [Omar AlQabandi](http://www.PlusOmar.com "Omar AlQabandi")
|
277 |
+
= 4.2.3 =
|
278 |
+
* Added ability to specify multiple recipient email addresses
|
279 |
+
* Fix settings gui - there was a problem enabling 'From' Address option when javascript is not enabled.
|
280 |
+
= 4.2.2 =
|
281 |
+
* Recaptcha library has now been namespaced to 'cscf' to remove ALL possibility of conflicts with other plugins that also include this library.
|
282 |
+
= 4.2.1 =
|
283 |
+
* Fixed potential conflict with other themes or plugins that use Google reCAPTCHA. reCAPTCHA library is not loaded if it already loaded by another plugin or theme.
|
284 |
+
* Recaptcha library function is now used to generate the sign up url on the settings page. The site domain is passed into the url for convenience.
|
285 |
+
* Options subject, message, heading, and body text are now translated when they are retrieved from the the database. Previously only the default messages were translated when no values were found in the database.
|
286 |
+
* Improved housekeeping: generic name for settings array has been changed from 'array_key' to 'cscf-options'
|
287 |
+
= 4.2.0 =
|
288 |
+
* Updated Turkish translations thanks again to [Abdullah Manaz](http://manaz.net "Abdullah Manaz")
|
289 |
+
* Fixed a problem where certain texts on the settings screen were not being translated
|
290 |
+
thanks to [Abdullah Manaz](http://manaz.net "Abdullah Manaz") again for finding this
|
291 |
+
* Updates to FAQ section
|
292 |
+
* The settings link on the plugin page may now be translated
|
293 |
+
* The text 'Contact Form' on the admin screen menu may now be translated
|
294 |
+
* Added Greek translations thanks to Georgios Diamantopoulos
|
295 |
+
= 4.1.9 =
|
296 |
+
* Added support for Bootstrap 3.0.0. Plugin is still compatible with Bootstrap 2.3.2, but if your theme uses this version
|
297 |
+
please do not use the plugin's default style sheet (uncheck the box in the settings screen)
|
298 |
+
[more information here](http://www.megnicholas.co.uk/articles/version-4-1-9-supports-bootstrap-3/ "more information").
|
299 |
+
= 4.1.8 =
|
300 |
+
* Added Russian Translation thanks to Oleg
|
301 |
+
* Correct character encoding in Estonian translation thanks to [Marko Punnar](http://aretaja.org "Marko Punnar")
|
302 |
+
* Correct some Spanish translation errors thanks to rowanda
|
303 |
+
= 4.1.7 =
|
304 |
+
* Added a note about the short code to use on the settings screen.
|
305 |
+
* Added Estonian Translation thanks to [Marko Punnar](http://aretaja.org "Marko Punnar")
|
306 |
+
* Added Japanese language thanks to Nikhil Khullar
|
307 |
+
* Updated Turkish translation thanks again to Abdullah Manaz http://manaz.net
|
308 |
+
= 4.1.6 =
|
309 |
+
* Added ability to specify a 'from' address. When supplied the email will come from that address instead of the form filler's email address.
|
310 |
+
* Changed type of email input boxes to "email"
|
311 |
+
* Added Turkish translation thanks to Abdullah Manaz http://manaz.net
|
312 |
+
= 4.1.5 =
|
313 |
+
* Removed all carriage returns from views to avoid problems with wptexturize
|
314 |
+
* Fixed typo in Dutch translation.
|
315 |
+
= 4.1.4 =
|
316 |
+
* Added Slovak translation file - thanks to Peter Gašparík
|
317 |
+
* Added Catalan translation file - thanks to Llorenç
|
318 |
+
= 4.1.3 =
|
319 |
+
* Fixed escaped characters.
|
320 |
+
* Added more translation files
|
321 |
+
* Forms now submit via ajax.
|
322 |
+
* Upgraded jquery-validate.js to 1.11. Removed jquery metadata plugin, form validation is now built with data attributes instead of json in classes.
|
323 |
+
* Improved view html.
|
324 |
+
* Added translations: Dutch thanks to Daniel Tetteroo, Armenian thanks to [Artak Kolyan](http://ablog.gratun.am "Artak Kolyan"),
|
325 |
+
Polish thanks to Patryk Peas
|
326 |
+
= 4.1.2 =
|
327 |
+
* Added some FAQs
|
328 |
+
* Added alternative shortcode [cscf-contact-form] for use when conflicts could occur.
|
329 |
+
* Updated the documentation.
|
330 |
+
* Recaptcha form now responds to language changes
|
331 |
+
* Updated pot file to reflect new name space
|
332 |
+
* Changed name space from cff to cscf
|
333 |
+
* Settings screen: recaptcha theme and key inputs are immediately enabled/disabled as the 'Use reCAPTCHA' box is clicked.
|
334 |
+
* Corrected some html seen as invalid by http://validator.w3.org/
|
335 |
+
* removed '<?=' and replaced with '<?php echo' in cscf_settings, thanks go to andrewbacon
|
336 |
+
* Added notice to setting screen when JetPack's contact form is active
|
337 |
+
* Fixed problem where 'Please enter a valid email address' was not translating in the 'confirm email address' input
|
338 |
+
= 4.1.1 =
|
339 |
+
* Fixed potential conflicts with themes that use bootstrap
|
340 |
+
* Enabled internationalisation, this plugin will now work with multiple languages
|
341 |
+
* Added German translation file for my German friends, thanks to faktorzweinet for the translation
|
342 |
+
= 4.1.0 =
|
343 |
+
* Fixed a bug in class.cff_settings.php where php opening tag had got missed off. This problem caused the settings screen not to display correctly but only occurred with some versions of php. Please upgrade if you have this problem.
|
344 |
+
= 4.0.9 =
|
345 |
+
* Switched header argument of wp_mail over to a filter to remove any potential conflicts with other emailing plugins or themes
|
346 |
+
* The ability to set a different recipient email address. Previously all email was sent to the WordPress administrator email address.
|
347 |
+
* Allow the email subject to be customised.
|
348 |
+
= 4.0.8 =
|
349 |
+
* Fixed a bug: When using reCAPTCHA ajax did not work.
|
350 |
+
* Fixed a bug: Ajax validation was not checking email address were equal (server side was doing it instead)
|
351 |
+
* Improvement: Ajax now works better.
|
352 |
+
* Documentation update: nicer links (worked how to do them in markdown!), changelog and upgrade notice sections now correctly formatted.
|
353 |
+
= 4.0.7 =
|
354 |
+
* Fixed a bug: Plugin name is actually clean-and-simple-contact-form now (not contact-form) but this new name needed to be updated in the plugin settings definitions. I also needed to rename contact-form.php to clean-and-simple-contact-form.php. My thanks to Jakub for finding this bug.
|
355 |
+
* If your webpage is ssl then reCAPTCHA will now also use ssl mode.
|
356 |
+
|
357 |
+
|
358 |
+
== Upgrade Notice ==
|
359 |
+
= 4.7.0 =
|
360 |
+
Tested with Wordpress version 4.9.6. Added 'consent to contact' GDPR compliance message
|
361 |
+
= 4.6.2 =
|
362 |
+
Updated translations. Tested up to WordPress 4.6.1.
|
363 |
+
= 4.6.0 =
|
364 |
+
Updated translations. Correct textdomain. Prevent multiple clicks.
|
365 |
+
= 4.5.1 =
|
366 |
+
Translation updates
|
367 |
+
= 4.5.0 =
|
368 |
+
Added support for Google Recaptcha2. Updated translation. Fixed layout bug.
|
369 |
+
= 4.4.4 =
|
370 |
+
Added languages, css fix for twenty fifteen theme, remove 'notice' errors, remove empty divs
|
371 |
+
= 4.4.3 =
|
372 |
+
Tested up to 4.1
|
373 |
+
= 4.4.2 =
|
374 |
+
Akismet tweak and translation updates
|
375 |
+
= 4.4.1 =
|
376 |
+
Fixed XSS issue
|
377 |
+
= 4.4.0 =
|
378 |
+
Added option for enquiry to email themselves a copy of the message plus Polish translation updated
|
379 |
+
= 4.3.4 =
|
380 |
+
Email now includes page url of contact form, removed link in main contact form view
|
381 |
+
= 4.3.3 =
|
382 |
+
Hebrew Language added, name field moved to top of form, added 'reply-to'
|
383 |
+
= 4.3.2 =
|
384 |
+
Added Norwegian and Brazilian Portugese Translations
|
385 |
+
= 4.3.1 =
|
386 |
+
Checked compatibility with WP 3.8 and TwentyFourteen theme, translation updates, defaults for new installations
|
387 |
+
= 4.3.0 =
|
388 |
+
Contact form is now filtered for spam when the Akismet plugin is present.
|
389 |
+
[Learn more](http://www.megnicholas.co.uk/articles/contact-form-plugin-can-detect-spam/ "Learn More").
|
390 |
+
= 4.2.5 =
|
391 |
+
Small bug fix
|
392 |
+
= 4.2.4 =
|
393 |
+
'Confirm Email' can now be turned off. Arabic translation added.
|
394 |
+
= 4.2.3 =
|
395 |
+
Multiple recipients are now possible
|
396 |
+
= 4.2.2 =
|
397 |
+
Remove ALL possibility of conflicts with other plugins that also include Google reCAPTCHA library
|
398 |
+
= 4.2.1 =
|
399 |
+
Translation and housekeeping updates
|
400 |
+
= 4.2.0 =
|
401 |
+
Translation and documentation updates
|
402 |
+
= 4.1.9 =
|
403 |
+
Support for [Bootstrap 3](http://www.megnicholas.co.uk/articles/version-4-1-9-supports-bootstrap-3/ "More information on 4.1.9")
|
404 |
+
= 4.1.8 =
|
405 |
+
Added Russian translation and some modifications to Estonian and Spanish translations
|
406 |
+
= 4.1.7
|
407 |
+
More translations. A helpful note about the short code to use has been put on the settings screen
|
408 |
+
= 4.1.6 =
|
409 |
+
Ability to specify a 'From' address. This email will be used to send the mail instead of the form filler's email address.
|
410 |
+
= 4.1.5 =
|
411 |
+
Works with themes that pre-process the html.
|
412 |
+
= 4.1.4 =
|
413 |
+
New translations - Slovak and Catalan
|
414 |
+
= 4.1.3 =
|
415 |
+
Form now submits via ajax!
|
416 |
+
= 4.1.2 =
|
417 |
+
Alternative shortcode, recaptcha internationalisation, Jetpack conflict warning notice
|
418 |
+
= 4.1.1 =
|
419 |
+
Internationalisation, fixed conflict with some bootstrapped themes.
|
420 |
+
= 4.1.0 =
|
421 |
+
Please upgrade if your settings screen is not displaying.
|
422 |
+
= 4.0.9 =
|
423 |
+
More customisation: recipient email address, and email subject.
|
424 |
+
= 4.0.8 =
|
425 |
+
Ajax now works when your form has reCAPTCHA on it. Ajax validation is now cleaner.
|
426 |
+
= 4.0.7 =
|
427 |
+
Fixed a bug which occurred when plugin name was changed. reCAPTCHA will now use ssl if your webpage is ssl.
|
|
|
|
|
|
|
|
shortcodes/contact-form.php
CHANGED
@@ -1,60 +1,55 @@
|
|
1 |
<?php
|
2 |
-
add_shortcode('contact-form', 'cscf_ContactForm');
|
3 |
-
add_shortcode('cscf-contact-form', 'cscf_ContactForm');
|
4 |
-
|
5 |
-
function cscf_ContactForm()
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
{
|
21 |
-
$view = new CSCF_View('message-not-sent');
|
22 |
-
}
|
23 |
-
|
24 |
-
return $view->Render();
|
25 |
-
}
|
26 |
|
27 |
//load google recaptcha script if required
|
28 |
if ( $contact->RecaptchaPublicKey <> '' && $contact->RecaptchaPrivateKey <> '' ) {
|
29 |
-
wp_enqueue_script('csf-recaptcha2');
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
}
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
$view->Set('messageSentView',$messageSentView);
|
55 |
-
$view->Set('messageNotSentView',new CSCF_View('message-not-sent'));
|
56 |
-
|
57 |
-
return $view->Render();
|
58 |
|
59 |
}
|
60 |
|
1 |
<?php
|
2 |
+
add_shortcode( 'contact-form', 'cscf_ContactForm' );
|
3 |
+
add_shortcode( 'cscf-contact-form', 'cscf_ContactForm' );
|
4 |
+
|
5 |
+
function cscf_ContactForm() {
|
6 |
+
|
7 |
+
$contact = new cscf_Contact;
|
8 |
+
|
9 |
+
if ( $contact->IsValid() ) {
|
10 |
+
if ( $contact->SendMail() ) {
|
11 |
+
$view = new CSCF_View( 'message-sent' );
|
12 |
+
$view->Set( 'heading', cscf_PluginSettings::SentMessageHeading() );
|
13 |
+
$view->Set( 'message', cscf_PluginSettings::SentMessageBody() );
|
14 |
+
} else {
|
15 |
+
$view = new CSCF_View( 'message-not-sent' );
|
16 |
+
}
|
17 |
+
|
18 |
+
return $view->Render();
|
19 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
|
21 |
//load google recaptcha script if required
|
22 |
if ( $contact->RecaptchaPublicKey <> '' && $contact->RecaptchaPrivateKey <> '' ) {
|
23 |
+
wp_enqueue_script( 'csf-recaptcha2' );
|
24 |
+
}
|
25 |
+
|
26 |
+
//here we need some jquery scripts and styles, so load them here
|
27 |
+
if ( cscf_PluginSettings::UseClientValidation() == true ) {
|
28 |
+
wp_enqueue_script( 'jquery-validate' );
|
29 |
+
wp_enqueue_script( 'cscf-validate' );
|
30 |
}
|
31 |
+
|
32 |
+
//only load the stylesheet if required
|
33 |
+
if ( cscf_PluginSettings::LoadStyleSheet() == true ) {
|
34 |
+
wp_enqueue_style( 'cscf-bootstrap' );
|
35 |
+
}
|
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 |
+
$view->Set( 'confirmEmail', cscf_PluginSettings::ConfirmEmail() );
|
46 |
+
$view->Set( 'postID', get_the_ID() );
|
47 |
+
|
48 |
+
|
49 |
+
$view->Set( 'messageSentView', $messageSentView );
|
50 |
+
$view->Set( 'messageNotSentView', new CSCF_View( 'message-not-sent' ) );
|
51 |
+
|
52 |
+
return $view->Render();
|
|
|
|
|
|
|
|
|
|
|
53 |
|
54 |
}
|
55 |
|
views/contact-form.view.php
CHANGED
@@ -1,215 +1,216 @@
|
|
1 |
<div id="cscf" class="cscfBlock">
|
2 |
-
|
3 |
-
<?php echo $messageSentView->Render(); ?>
|
4 |
-
|
5 |
-
|
6 |
-
<?php echo $messageNotSentView->Render(); ?>
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
<?php wp_nonce_field( 'cscf_contact', 'cscf_nonce' ); ?>
|
13 |
-
|
14 |
|
15 |
<?php if ( isset( $contact->Errors['recaptcha'] ) ) { ?>
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
<?php } ?>
|
20 |
|
21 |
-
|
22 |
-
|
23 |
echo ' error has-error';
|
24 |
} ?>">
|
25 |
-
|
26 |
|
27 |
|
28 |
-
|
29 |
<?php if ( cscf_PluginSettings::InputIcons() == true ) { ?>
|
30 |
-
|
31 |
<?php } ?>
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
<span for="cscf_name" class="help-inline help-block error"
|
41 |
style="display:<?php echo isset( $contact->Errors['name'] ) ? 'block' : 'none'; ?>;">
|
42 |
|
43 |
<?php if ( isset( $contact->Errors['name'] ) ) {
|
44 |
-
echo $contact->Errors['name'];
|
45 |
} ?>
|
46 |
</span>
|
47 |
-
|
48 |
|
49 |
|
50 |
-
|
51 |
-
|
52 |
echo ' error has-error';
|
53 |
} ?>">
|
54 |
-
|
55 |
|
56 |
-
|
57 |
<?php if ( cscf_PluginSettings::InputIcons() == true ) { ?>
|
58 |
-
|
59 |
<?php } ?>
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
<span for="cscf_email" class="help-inline help-block error"
|
71 |
style="display:<?php echo isset( $contact->Errors['email'] ) ? 'block' : 'none'; ?>;">
|
72 |
<?php if ( isset( $contact->Errors['email'] ) ) {
|
73 |
-
echo $contact->Errors['email'];
|
74 |
} ?>
|
75 |
</span>
|
76 |
-
|
77 |
|
78 |
<?php if ( $confirmEmail ) { ?>
|
79 |
-
|
80 |
-
|
81 |
echo ' error has-error';
|
82 |
} ?>">
|
83 |
-
|
84 |
-
|
85 |
<?php if ( cscf_PluginSettings::InputIcons() == true ) { ?>
|
86 |
-
|
87 |
<?php } ?>
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
<?php if ( isset( $contact->Errors['confirm-email'] ) ) {
|
103 |
-
echo $contact->Errors['confirm-email'];
|
104 |
} ?>
|
105 |
</span>
|
106 |
-
|
107 |
<?php } ?>
|
108 |
|
109 |
|
110 |
-
|
111 |
-
|
112 |
echo ' error has-error';
|
113 |
} ?>">
|
114 |
-
|
115 |
-
|
116 |
<?php if ( cscf_PluginSettings::InputIcons() == true ) { ?>
|
117 |
-
|
118 |
<?php } ?>
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
<?php if ( isset( $contact->Errors['message'] ) ) {
|
129 |
-
echo $contact->Errors['message'];
|
130 |
} ?>
|
131 |
</span>
|
132 |
-
|
133 |
|
134 |
<?php if ( cscf_PluginSettings::EmailToSender() ) { ?>
|
135 |
-
|
136 |
-
|
137 |
echo ' error has-error';
|
138 |
} ?>">
|
139 |
-
|
140 |
-
|
141 |
<?php if ( cscf_PluginSettings::InputIcons() == true ) { ?>
|
142 |
-
|
143 |
<?php } ?>
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
<?php if ( isset( $contact->Errors['email-sender'] ) ) {
|
151 |
-
echo $contact->Errors['email-sender'];
|
152 |
} ?>
|
153 |
</span>
|
154 |
-
|
155 |
<?php } ?>
|
156 |
|
157 |
|
158 |
|
159 |
<?php if ( cscf_PluginSettings::ContactConsent() ) { ?>
|
160 |
-
|
161 |
-
|
162 |
echo ' error has-error';
|
163 |
} ?>">
|
164 |
-
|
165 |
-
|
|
|
166 |
<?php if ( cscf_PluginSettings::InputIcons() == true ) { ?>
|
167 |
-
|
168 |
<?php } ?>
|
169 |
-
|
170 |
-
data-msg-required="<?php
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
<?php if ( isset( $contact->Errors['contact-consent'] ) ) {
|
178 |
-
echo $contact->Errors['contact-consent'];
|
179 |
} ?>
|
180 |
</span>
|
181 |
-
|
182 |
<?php } ?>
|
183 |
|
184 |
-
|
185 |
<?php if ( $contact->RecaptchaPublicKey <> '' && $contact->RecaptchaPrivateKey <> '' ) { ?>
|
186 |
|
187 |
-
|
188 |
if ( isset( $contact->Errors['recaptcha'] ) ) {
|
189 |
echo ' error has-error';
|
190 |
} ?>">
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
|
195 |
|
196 |
-
|
197 |
-
|
198 |
-
echo $contact->Errors['recaptcha'];
|
199 |
} ?></div>
|
200 |
|
201 |
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
bottom: 12px; left: 25px; margin: 0px; padding: 0px; right: 25px;
|
214 |
background: #f9f9f9; border: 1px solid #c1c1c1; border-radius: 3px;">
|
215 |
<textarea id="g-recaptcha-response" name="g-recaptcha-response"
|
@@ -217,15 +218,16 @@
|
|
217 |
style="width: 250px; height: 40px; border: 1px solid #c1c1c1;
|
218 |
margin: 10px 25px; padding: 0px; resize: none;">
|
219 |
</textarea>
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
|
225 |
-
|
226 |
-
|
227 |
<?php } ?>
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
</div>
|
|
1 |
<div id="cscf" class="cscfBlock">
|
2 |
+
<div class="cscfMessageSent" style="display:none;">
|
3 |
+
<?php echo wp_kses_post( $messageSentView->Render() ); ?>
|
4 |
+
</div>
|
5 |
+
<div class="cscfMessageNotSent" style="display:none;">
|
6 |
+
<?php echo wp_kses_post( $messageNotSentView->Render() ); ?>
|
7 |
+
</div>
|
8 |
+
<div class="cscfForm">
|
9 |
+
<p><?php echo wp_kses_post( $message ); ?></p>
|
10 |
+
|
11 |
+
<form role="form" id="frmCSCF" name="frmCSCF" method="post">
|
12 |
<?php wp_nonce_field( 'cscf_contact', 'cscf_nonce' ); ?>
|
13 |
+
<input type="hidden" name="post-id" value="<?php echo esc_attr( $postID ); ?>">
|
14 |
|
15 |
<?php if ( isset( $contact->Errors['recaptcha'] ) ) { ?>
|
16 |
+
<div class="control-group form-group">
|
17 |
+
<p class="text-error"><?php echo esc_html( $contact->Errors['recaptcha'] ); ?></p>
|
18 |
+
</div>
|
19 |
<?php } ?>
|
20 |
|
21 |
+
<!-- name -->
|
22 |
+
<div class="control-group form-group<?php if ( isset( $contact->Errors['name'] ) ) {
|
23 |
echo ' error has-error';
|
24 |
} ?>">
|
25 |
+
<label for="cscf_name"><?php esc_html_e( 'Name:', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?></label>
|
26 |
|
27 |
|
28 |
+
<div class="<?php echo ( true === cscf_PluginSettings::InputIcons() ) ? 'input-group' : ''; ?>">
|
29 |
<?php if ( cscf_PluginSettings::InputIcons() == true ) { ?>
|
30 |
+
<span class="input-group-addon"><span class="glyphicon glyphicon-user"></span></span>
|
31 |
<?php } ?>
|
32 |
+
<input class="form-control input-xlarge"
|
33 |
+
data-rule-required="true"
|
34 |
+
data-msg-required="<?php esc_html_e( 'Please give your name.', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>"
|
35 |
+
type="text" id="cscf_name" name="cscf[name]"
|
36 |
+
value="<?php echo esc_attr( $contact->Name ); ?>"
|
37 |
+
placeholder="<?php esc_html_e( 'Your Name', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>"
|
38 |
+
/>
|
39 |
+
</div>
|
40 |
<span for="cscf_name" class="help-inline help-block error"
|
41 |
style="display:<?php echo isset( $contact->Errors['name'] ) ? 'block' : 'none'; ?>;">
|
42 |
|
43 |
<?php if ( isset( $contact->Errors['name'] ) ) {
|
44 |
+
echo esc_html( $contact->Errors['name'] );
|
45 |
} ?>
|
46 |
</span>
|
47 |
+
</div>
|
48 |
|
49 |
|
50 |
+
<!--email address-->
|
51 |
+
<div class="control-group form-group<?php if ( isset( $contact->Errors['email'] ) ) {
|
52 |
echo ' error has-error';
|
53 |
} ?>">
|
54 |
+
<label for="cscf_email"><?php esc_html_e( 'Email Address:', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?></label>
|
55 |
|
56 |
+
<div class="<?php echo ( true === cscf_PluginSettings::InputIcons() ) ? 'input-group' : ''; ?>">
|
57 |
<?php if ( cscf_PluginSettings::InputIcons() == true ) { ?>
|
58 |
+
<span class="input-group-addon"><span class="glyphicon glyphicon-envelope"></span></span>
|
59 |
<?php } ?>
|
60 |
+
<input class="form-control input-xlarge"
|
61 |
+
data-rule-required="true"
|
62 |
+
data-rule-email="true"
|
63 |
+
data-msg-required="<?php esc_html_e( 'Please give your email address.', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>"
|
64 |
+
data-msg-email="<?php esc_html_e( 'Please enter a valid email address.', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>"
|
65 |
+
type="email" id="cscf_email" name="cscf[email]"
|
66 |
+
value="<?php echo esc_attr( $contact->Email ); ?>"
|
67 |
+
placeholder="<?php esc_html_e( 'Your Email Address', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>"
|
68 |
+
/>
|
69 |
+
</div>
|
70 |
<span for="cscf_email" class="help-inline help-block error"
|
71 |
style="display:<?php echo isset( $contact->Errors['email'] ) ? 'block' : 'none'; ?>;">
|
72 |
<?php if ( isset( $contact->Errors['email'] ) ) {
|
73 |
+
echo esc_html( $contact->Errors['email'] );
|
74 |
} ?>
|
75 |
</span>
|
76 |
+
</div>
|
77 |
|
78 |
<?php if ( $confirmEmail ) { ?>
|
79 |
+
<!--confirm email address -->
|
80 |
+
<div class="control-group form-group<?php if ( isset( $contact->Errors['confirm-email'] ) ) {
|
81 |
echo ' error has-error';
|
82 |
} ?>">
|
83 |
+
<label for="cscf_confirm-email"><?php esc_html_e( 'Confirm Email Address:', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?></label>
|
84 |
+
<div class="<?php echo ( true === cscf_PluginSettings::InputIcons() ) ? 'input-group' : ''; ?>">
|
85 |
<?php if ( cscf_PluginSettings::InputIcons() == true ) { ?>
|
86 |
+
<span class="input-group-addon"><span class="glyphicon glyphicon-envelope"></span></span>
|
87 |
<?php } ?>
|
88 |
+
<input class="form-control input-xlarge"
|
89 |
+
data-rule-required="true"
|
90 |
+
data-rule-email="true"
|
91 |
+
data-rule-equalTo="#cscf_email"
|
92 |
+
data-msg-required="<?php esc_html_e( 'Please enter the same email address again.', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>"
|
93 |
+
data-msg-email="<?php esc_html_e( 'Please enter a valid email address.', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>"
|
94 |
+
data-msg-equalTo="<?php esc_html_e( 'Please enter the same email address again.', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>"
|
95 |
+
type="email" id="cscf_confirm-email" name="cscf[confirm-email]"
|
96 |
+
value="<?php echo esc_attr( $contact->ConfirmEmail ); ?>"
|
97 |
+
placeholder="<?php esc_html_e( 'Confirm Your Email Address', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>"
|
98 |
+
/>
|
99 |
+
</div>
|
100 |
+
<span for="cscf_confirm-email" class="help-inline help-block error"
|
101 |
+
style="display:<?php echo isset( $contact->Errors['confirm-email'] ) ? 'block' : 'none'; ?>;">
|
102 |
<?php if ( isset( $contact->Errors['confirm-email'] ) ) {
|
103 |
+
echo esc_attr( $contact->Errors['confirm-email'] );
|
104 |
} ?>
|
105 |
</span>
|
106 |
+
</div>
|
107 |
<?php } ?>
|
108 |
|
109 |
|
110 |
+
<!-- message -->
|
111 |
+
<div class="control-group form-group<?php if ( isset( $contact->Errors['message'] ) ) {
|
112 |
echo ' error has-error';
|
113 |
} ?>">
|
114 |
+
<label for="cscf_message"><?php esc_html_e( 'Message:', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?></label>
|
115 |
+
<div class="<?php echo ( true === cscf_PluginSettings::InputIcons() ) ? 'input-group' : ''; ?>">
|
116 |
<?php if ( cscf_PluginSettings::InputIcons() == true ) { ?>
|
117 |
+
<span class="input-group-addon"><span class="glyphicon glyphicon-comment"></span></span>
|
118 |
<?php } ?>
|
119 |
+
<textarea class="form-control input-xlarge"
|
120 |
+
data-rule-required="true"
|
121 |
+
data-msg-required="<?php esc_html_e( 'Please give a message.', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>"
|
122 |
+
id="cscf_message" name="cscf[message]" rows="10"
|
123 |
+
placeholder="<?php esc_html_e( 'Your Message', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>"><?php echo esc_textarea( $contact->Message ); ?></textarea>
|
124 |
+
</div>
|
125 |
+
|
126 |
+
<span for="cscf_message" class="help-inline help-block error"
|
127 |
+
style="display:<?php echo isset( $contact->Errors['message'] ) ? 'block' : 'none'; ?>;">
|
128 |
<?php if ( isset( $contact->Errors['message'] ) ) {
|
129 |
+
echo esc_attr( $contact->Errors['message'] );
|
130 |
} ?>
|
131 |
</span>
|
132 |
+
</div>
|
133 |
|
134 |
<?php if ( cscf_PluginSettings::EmailToSender() ) { ?>
|
135 |
+
<!-- email to sender -->
|
136 |
+
<div class="control-group form-group<?php if ( isset( $contact->Errors['email-sender'] ) ) {
|
137 |
echo ' error has-error';
|
138 |
} ?>">
|
139 |
+
<label for="cscf_email-sender"><?php esc_html_e( 'Send me a copy:', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?></label>
|
140 |
+
<div class="<?php echo ( true === cscf_PluginSettings::InputIcons() ) ? "input-group" : ""; ?>">
|
141 |
<?php if ( cscf_PluginSettings::InputIcons() == true ) { ?>
|
142 |
+
<span class="input-group-addon"><span class="glyphicon glyphicon-comment"></span></span>
|
143 |
<?php } ?>
|
144 |
+
<input <?php echo ( true == $contact->EmailToSender ) ? 'checked' : ''; ?> type="checkbox"
|
145 |
+
id="cscf_email-sender"
|
146 |
+
name="cscf[email-sender]">
|
147 |
+
</div>
|
148 |
+
<span for="cscf_email-sender" class="help-inline help-block error"
|
149 |
+
style="display:<?php echo isset( $contact->Errors['email-sender'] ) ? 'block' : 'none'; ?>;">
|
150 |
<?php if ( isset( $contact->Errors['email-sender'] ) ) {
|
151 |
+
echo esc_attr( $contact->Errors['email-sender'] );
|
152 |
} ?>
|
153 |
</span>
|
154 |
+
</div>
|
155 |
<?php } ?>
|
156 |
|
157 |
|
158 |
|
159 |
<?php if ( cscf_PluginSettings::ContactConsent() ) { ?>
|
160 |
+
<!-- contact consent -->
|
161 |
+
<div class="control-group form-group<?php if ( isset( $contact->Errors['contact-consent'] ) ) {
|
162 |
echo ' error has-error';
|
163 |
} ?>">
|
164 |
+
<label for="cscf_contact-consent"><?php echo esc_html( cscf_PluginSettings::ContactConsentMsg() ); ?>
|
165 |
+
:</label>
|
166 |
+
<div class="<?php echo ( cscf_PluginSettings::InputIcons() ) ? "input-group" : ""; ?>">
|
167 |
<?php if ( cscf_PluginSettings::InputIcons() == true ) { ?>
|
168 |
+
<span class="input-group-addon"><span class="glyphicon glyphicon-comment"></span></span>
|
169 |
<?php } ?>
|
170 |
+
<input data-rule-required="true"
|
171 |
+
data-msg-required="<?php esc_html_e( 'Please give your consent.', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>"
|
172 |
+
<?php echo ( true === $contact->ContactConsent ) ? 'checked' : ''; ?> type="checkbox"
|
173 |
+
id="cscf_contact-consent"
|
174 |
+
name="cscf[contact-consent]">
|
175 |
+
</div>
|
176 |
+
<span for="cscf[contact-consent]" class="help-inline help-block error"
|
177 |
+
style="display:<?php echo isset( $contact->Errors['contact-consent'] ) ? 'block' : 'none'; ?>;">
|
178 |
<?php if ( isset( $contact->Errors['contact-consent'] ) ) {
|
179 |
+
echo esc_html( $contact->Errors['contact-consent'] );
|
180 |
} ?>
|
181 |
</span>
|
182 |
+
</div>
|
183 |
<?php } ?>
|
184 |
|
185 |
+
<!-- recaptcha -->
|
186 |
<?php if ( $contact->RecaptchaPublicKey <> '' && $contact->RecaptchaPrivateKey <> '' ) { ?>
|
187 |
|
188 |
+
<div class="control-group form-group<?php
|
189 |
if ( isset( $contact->Errors['recaptcha'] ) ) {
|
190 |
echo ' error has-error';
|
191 |
} ?>">
|
192 |
+
<div id="recaptcha_div">
|
193 |
+
<div class="g-recaptcha" data-theme="<?php echo esc_attr( cscf_PluginSettings::Theme() ); ?>"
|
194 |
+
data-sitekey="<?php echo esc_attr( $contact->RecaptchaPublicKey ); ?>"></div>
|
195 |
|
196 |
|
197 |
+
<div for="cscf_recaptcha"
|
198 |
+
class="help-block has-error error"><?php if ( isset( $contact->Errors['recaptcha'] ) ) {
|
199 |
+
echo esc_html( $contact->Errors['recaptcha'] );
|
200 |
} ?></div>
|
201 |
|
202 |
|
203 |
+
<noscript>
|
204 |
+
<div style="width: 302px; height: 422px;">
|
205 |
+
<div style="width: 302px; height: 422px; position: relative;">
|
206 |
+
<div style="width: 302px; height: 422px; position: absolute;">
|
207 |
+
<iframe
|
208 |
+
src="https://www.google.com/recaptcha/api/fallback?k=<?php echo esc_attr( $contact->RecaptchaPublicKey ); ?>"
|
209 |
+
frameborder="0" scrolling="no"
|
210 |
+
style="width: 302px; height:422px; border-style: none;">
|
211 |
+
</iframe>
|
212 |
+
</div>
|
213 |
+
<div style="width: 300px; height: 60px; border-style: none;
|
214 |
bottom: 12px; left: 25px; margin: 0px; padding: 0px; right: 25px;
|
215 |
background: #f9f9f9; border: 1px solid #c1c1c1; border-radius: 3px;">
|
216 |
<textarea id="g-recaptcha-response" name="g-recaptcha-response"
|
218 |
style="width: 250px; height: 40px; border: 1px solid #c1c1c1;
|
219 |
margin: 10px 25px; padding: 0px; resize: none;">
|
220 |
</textarea>
|
221 |
+
</div>
|
222 |
+
</div>
|
223 |
+
</div>
|
224 |
+
</noscript>
|
225 |
|
226 |
+
</div>
|
227 |
+
</div>
|
228 |
<?php } ?>
|
229 |
+
<input type="submit" id="cscf_SubmitButton" class="btn btn-default"
|
230 |
+
value="<?php esc_html_e( 'Send Message', 'clean-and-simple-contact-form-by-meg-nicholas' ); ?>"/>
|
231 |
+
</form>
|
232 |
+
</div>
|
233 |
+
</div>
|
views/message-not-sent.view.php
CHANGED
@@ -1 +1 @@
|
|
1 |
-
<p><?php
|
1 |
+
<p><?php esc_html_e('Sorry, there has been a problem and your message was not sent.','clean-and-simple-contact-form-by-meg-nicholas') ?></p>
|
views/message-sent.view.php
CHANGED
@@ -1,2 +1,2 @@
|
|
1 |
-
<h3><?php echo $heading; ?></h3>
|
2 |
-
<p><?php echo $message; ?> </p>
|
1 |
+
<h3><?php echo esc_html($heading); ?></h3>
|
2 |
+
<p><?php echo esc_html($message); ?> </p>
|