Custom Field Template - Version 1.9.5

Version Description

  • tinyMCE and quicktags in WordPress 3.3.
  • Upgrade of jQuery Validation Plugin.
  • Bugfix: multiple and fieldset options (Thanks, Colin Duwe).
Download this release

Release Info

Developer Hiroaki Miyashita
Plugin Icon 128x128 Custom Field Template
Version 1.9.5
Comparing to
See all releases

Code changes from version 1.9.4 to 1.9.5

Files changed (3) hide show
  1. custom-field-template.php +115 -39
  2. js/jquery.validate.js +1188 -1159
  3. readme.txt +7 -2
custom-field-template.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: Custom Field Template
4
  Plugin URI: http://wpgogo.com/development/custom-field-template.html
5
  Description: This plugin adds the default custom fields on the Write Post/Page.
6
  Author: Hiroaki Miyashita
7
- Version: 1.9.4
8
  Author URI: http://wpgogo.com/
9
  */
10
 
@@ -66,6 +66,7 @@ class custom_field_template {
66
  add_shortcode( 'cft', array(&$this, 'output_custom_field_values') );
67
  add_shortcode( 'cftsearch', array(&$this, 'search_custom_field_values') );
68
  endif;
 
69
  }
70
 
71
  function custom_field_template_init() {
@@ -147,6 +148,8 @@ class custom_field_template {
147
  add_action( 'edit_form_advanced', array(&$this, 'insert_custom_field'), 1 );
148
  add_action( 'edit_page_form', array(&$this, 'insert_custom_field'), 1 );
149
  } else {
 
 
150
  require_once(ABSPATH . 'wp-admin/includes/template.php');
151
  add_meta_box('cftdiv', __('Custom Field Template', 'custom-field-template'), array(&$this, 'insert_custom_field'), 'post', 'normal', 'core');
152
  add_meta_box('cftdiv', __('Custom Field Template', 'custom-field-template'), array(&$this, 'insert_custom_field'), 'page', 'normal', 'core');
@@ -168,7 +171,7 @@ class custom_field_template {
168
  endforeach;
169
  if ( isset($custom_post_type) && is_array($custom_post_type) ) :
170
  foreach( $custom_post_type as $val ) :
171
- if ( function_exists('remove_meta_box') && $options['custom_field_template_disable_default_custom_fields'] ) :
172
  remove_meta_box('postcustom', $val, 'normal');
173
  endif;
174
  add_meta_box('cftdiv', __('Custom Field Template', 'custom-field-template'), array(&$this, 'insert_custom_field'), $val, 'normal', 'core');
@@ -633,7 +636,6 @@ type = file';
633
  #cft dd p.label { font-weight:bold; margin:0; }
634
  #cft_instruction { margin:10px; }
635
  #cft fieldset { border:1px solid #CCC; margin:5px; padding:5px; }
636
- #cft .mceStatusbar { padding-bottom:22px; }
637
  #cft .dl_checkbox { margin:0; }
638
  ';
639
  update_option('custom_field_template_data', $options);
@@ -1883,10 +1885,18 @@ jQuery(this).addClass("closed");
1883
  $out = '<script type="text/javascript">' . "\n" .
1884
  '// <![CDATA[' . "\n" .
1885
  'jQuery(document).ready(function() {if ( typeof tinyMCE != "undefined" ) {' . "\n";
 
 
 
 
 
 
 
 
1886
  if ( !empty($options['custom_field_template_use_wpautop']) ) :
1887
- $out .= 'document.getElementById("'. $name . $rand . '").value = document.getElementById("'. $name . $rand . '").value; tinyMCE.execCommand("mceAddControl", false, "'. $name . $rand . '"); tinyMCEID.push("'. $name . $rand . '");' . "\n";
1888
  else:
1889
- $out .= 'document.getElementById("'. $name . $rand . '").value = switchEditors.wpautop(document.getElementById("'. $name . $rand . '").value); tinyMCE.execCommand("mceAddControl", false, "'. $name . $rand . '"); tinyMCEID.push("'. $name . $rand . '");' . "\n";
1890
  endif;
1891
  $out .= '}});' . "\n";
1892
  $out .= '// ]]>' . "\n" . '</script>';
@@ -1898,31 +1908,36 @@ jQuery(this).addClass("closed");
1898
 
1899
  if ( $mediaButton == true ) :
1900
  $media_upload_iframe_src = "media-upload.php";
1901
-
1902
- if ( !$mediaOffImage ) :
1903
- $image_upload_iframe_src = apply_filters('image_upload_iframe_src', "$media_upload_iframe_src?type=image");
1904
- $image_title = __('Add an Image');
1905
- $media .= "<a href=\"{$image_upload_iframe_src}&TB_iframe=true\" id=\"add_image{$rand}\" title='$image_title' onclick=\"focusTextArea('{$name}{$rand}'); jQuery(this).attr('href',jQuery(this).attr('href').replace('\?','?post_id='+jQuery('#post_ID').val())); return thickbox(this);\"><img src='images/media-button-image.gif' alt='$image_title' /></a> ";
1906
- endif;
1907
- if ( !$mediaOffVideo ) :
1908
- $video_upload_iframe_src = apply_filters('video_upload_iframe_src', "$media_upload_iframe_src?type=video");
1909
- $video_title = __('Add Video');
1910
- $media .= "<a href=\"{$video_upload_iframe_src}&amp;TB_iframe=true\" id=\"add_video{$rand}\" title='$video_title' onclick=\"focusTextArea('{$name}{$rand}'); jQuery(this).attr('href',jQuery(this).attr('href').replace('\?','?post_id='+jQuery('#post_ID').val())); return thickbox(this);\"><img src='images/media-button-video.gif' alt='$video_title' /></a> ";
1911
- endif;
1912
- if ( !$mediaOffAudio ) :
1913
- $audio_upload_iframe_src = apply_filters('audio_upload_iframe_src', "$media_upload_iframe_src?type=audio");
1914
- $audio_title = __('Add Audio');
1915
- $media .= "<a href=\"{$audio_upload_iframe_src}&amp;TB_iframe=true\" id=\"add_audio{$rand}\" title='$audio_title' onclick=\"focusTextArea('{$name}{$rand}'); jQuery(this).attr('href',jQuery(this).attr('href').replace('\?','?post_id='+jQuery('#post_ID').val())); return thickbox(this);\"><img src='images/media-button-music.gif' alt='$audio_title' /></a> ";
1916
- endif;
1917
- if ( !$mediaOffMedia ) :
 
 
 
 
 
1918
  $media_title = __('Add Media');
1919
- $media .= "<a href=\"{$media_upload_iframe_src}?TB_iframe=true\" id=\"add_media{$rand}\" title='$media_title' onclick=\"focusTextArea('{$name}{$rand}'); jQuery(this).attr('href',jQuery(this).attr('href').replace('\?','?post_id='+jQuery('#post_ID').val())); return thickbox(this);\"><img src='images/media-button-other.gif' alt='$media_title' /></a>";
1920
  endif;
1921
  endif;
1922
 
1923
  $switch = '<div>';
1924
  if( $tinyMCE == true && user_can_richedit() ) {
1925
- $switch .= '<a href="#toggle" onclick="switchMode(\''.$name.$rand.'\'); return false;">' . __('Toggle', 'custom-field-template') . '</a>';
1926
  }
1927
  $switch .= '</div>';
1928
  }
@@ -1931,7 +1946,13 @@ jQuery(this).addClass("closed");
1931
 
1932
  if ( $hideKey == true ) $hide = ' class="hideKey"';
1933
  $content_class = ' class="';
1934
- if ( $htmlEditor == true ) $content_class .= 'content';
 
 
 
 
 
 
1935
  if ( !empty($class) ) $content_class .= ' ' . $class;
1936
  $content_class .= '"';
1937
  if ( !empty($style) ) $style = ' style="' . $style . '"';
@@ -1948,10 +1969,27 @@ jQuery(this).addClass("closed");
1948
 
1949
  if ( $multipleButton == true && $ct_value == $cftnum ) :
1950
  $addfield .= '<div style="margin-top:-1em;">';
 
 
 
 
 
 
 
 
 
 
 
1951
  if ( !empty($tinyMCE) ) :
1952
- $addfield .= '<a href="#clear" onclick="var original_id, new_id; jQuery(this).parent().parent().parent().find('."'textarea'".').each(function(){original_id = jQuery(this).attr('."'id'".');tinyMCE.execCommand(' . "'mceRemoveControl'" . ',false,jQuery(this).attr('."'id'".'));});var clone = jQuery(this).parent().parent().parent().clone().insertAfter(jQuery(this).parent().parent().parent()); clone.find('."'textarea'".').val('."''".');if(original_id.match(/([0-9]+)$/)) {var matchval = RegExp.$1;re = new RegExp(matchval, '."'ig'".');clone.html(clone.html().replace(re, parseInt(matchval)+1)); new_id = original_id.replace(/([0-9]+)$/, parseInt(matchval)+1);}if ( tinyMCE.get(jQuery(this).attr('."original_id".')) ) {tinyMCE.execCommand(' . "'mceAddControl'" . ',false, original_id);tinyMCE.execCommand(' . "'mceAddControl'" . ',false, new_id);}jQuery(this).parent().css('."'visibility','hidden'".');jQuery(this).parent().prev().css('."'visibility','hidden'".'); return false;">' . __('Add New', 'custom-field-template') . '</a>';
 
 
 
 
 
 
1953
  else :
1954
- $addfield .= '<a href="#clear" onclick="var original_id, new_id; jQuery(this).parent().parent().parent().find('."'textarea'".').each(function(){original_id = jQuery(this).attr('."'id'".');});var clone = jQuery(this).parent().parent().parent().clone().insertAfter(jQuery(this).parent().parent().parent()); clone.find('."'textarea'".').val('."''".');if(original_id.match(/([0-9]+)$/)) {var matchval = RegExp.$1;re = new RegExp(matchval, '."'ig'".');clone.html(clone.html().replace(re, parseInt(matchval)+1)); new_id = original_id.replace(/([0-9]+)$/, parseInt(matchval)+1);}jQuery(this).parent().css('."'visibility','hidden'".');jQuery(this).parent().prev().css('."'visibility','hidden'".'); return false;">' . __('Add New', 'custom-field-template') . '</a>';
1955
  endif;
1956
  $addfield .= '</div>';
1957
  endif;
@@ -1965,16 +2003,26 @@ jQuery(this).addClass("closed");
1965
  $out .= '<p class="label">' . stripcslashes($label) . '</p>';
1966
 
1967
  $out .= trim($before);
 
 
1968
 
1969
  if ( $htmlEditor == true ) :
1970
- if( $tinyMCE == true ) $quicktags_hide = ' jQuery(\'#qt_' . sha1($name . $rand) . '_qtags\').hide();';
1971
- $out .= '<div class="quicktags"><script type="text/javascript">' . "\n" . '// <![CDATA[' . "\n" . '
1972
- jQuery(document).ready(function() { qt_' . sha1($name . $rand) . ' = new QTags(\'qt_' . sha1($name . $rand) . '\', \'' . $name . $rand . '\', \'editorcontainer_' . $name . $rand . '\', \'more\'); ' . $quicktags_hide . ' });' . "\n" . '// ]]>' . "\n" . '</script>';
1973
- $editorcontainer_class = ' class="editorcontainer"';
 
 
 
 
 
 
 
 
1974
  endif;
1975
 
1976
  $out .= '<div' . $editorcontainer_class . ' id="editorcontainer_' . $name . $rand . '"><textarea id="' . $name . $rand . '" name="' . $name . '[' . $sid . '][]" rows="' .$rows. '" cols="' . $cols . '"' . $content_class . $style . $event_output . '>' . esc_attr(trim($value)) . '</textarea><input type="hidden" name="'.$name.'_rand['.$sid.']" value="'.$rand.'" /></div>';
1977
- if ( $htmlEditor == true ) $out .= '</div>';
1978
  $out .= trim($after).'</dd></dl>'."\n";
1979
 
1980
  return $out;
@@ -2199,8 +2247,17 @@ jQuery(this).addClass("closed");
2199
  if ( isset($_REQUEST['post']) ) $addbutton = $this->get_post_meta( $_REQUEST['post'], $title, true )-1;
2200
  if ( !isset($addbutton) || $addbutton<=0 ) $addbutton = 0;
2201
  if ( $data['cftnum']/2 == $addbutton ) :
2202
- $addfield .= ' <a href="#clear" onclick="var textarea_ids = new Array();jQuery(this).parent().parent().parent().find('."'textarea'".').each(function(){ed = tinyMCE.get(jQuery(this).attr('."'id'".')); if(ed) {textarea_ids.push(jQuery(this).attr('."'id'".'));tinyMCE.execCommand(' . "'mceRemoveControl'" . ',false,jQuery(this).attr('."'id'".'));}});var checked_ids = new Array();jQuery(this).parent().parent().parent().find('."'input[type=radio]:checked'".').each(function(){checked_ids.push(jQuery(this).attr('."'id'".'));});var tmp = jQuery(this).parent().parent().parent().clone().insertAfter(jQuery(this).parent().parent().parent());for( var i=0;i<checked_ids.length;i++) { jQuery('."'#'+checked_ids[i]".').attr('."'checked'".', true); }
2203
- tmp.find('."'input[type=text],input[type=hidden],input[type=file]'".').val('."''".');tmp.find('."'select'".').val('."''".');tmp.find('."'textarea'".').val('."''".');tmp.find('."'input'".').attr('."'checked',false".');tmp.find('."'p'".').remove();tmp.find('."'dl'".').each(function(){ if(jQuery(this).attr('."'id'".')){if(jQuery(this).attr('."'id'".').match(/_([0-9]+)$/)) {matchval = RegExp.$1;matchval++;jQuery(this).attr('."'id',".'jQuery(this).attr('."'id'".').replace(/_([0-9]+)$/, \'_\'+matchval)); jQuery(this).find('."'textarea'".').each(function(){if(jQuery(this).attr('."'id'".').match(/([0-9]+)$/)) {var check = false;for( var i=0;i<textarea_ids.length;i++) { if ( jQuery(this).attr('."'id'".')==textarea_ids[i] ) { check = true; } }if ( check ) { matchval2 = RegExp.$1;jQuery(this).attr('."'id',".'jQuery(this).attr('."'id'".').replace(/([0-9]+)$/, parseInt(matchval2)+1));re = new RegExp(matchval2, '."'ig'".');jQuery(this).parent().parent().parent().html(jQuery(this).parent().parent().parent().html().replace(re, parseInt(matchval2)+1)); textarea_ids.push(jQuery(this).attr('."'id'".'));}} jQuery(this).attr('."'name',".'jQuery(this).attr('."'name'".').replace(/\[([0-9]+)\]$/, \'[\'+matchval+\']\'));});jQuery(this).find('."'input'".').each(function(){jQuery(this).attr('."'id',".'jQuery(this).attr('."'id'".').replace(/_([0-9]+)_/, \'_\'+matchval+\'_\'));jQuery(this).attr('."'id',".'jQuery(this).attr('."'id'".').replace(/_([0-9]+)$/, \'_\'+matchval));jQuery(this).attr('."'name',".'jQuery(this).attr('."'name'".').replace(/\[([0-9]+)\]$/, \'[\'+matchval+\']\'));});jQuery(this).find('."'label'".').each(function(){jQuery(this).attr('."'for',".'jQuery(this).attr('."'for'".').replace(/_([0-9]+)_/, \'_\'+matchval+\'_\'));jQuery(this).attr('."'for',".'jQuery(this).attr('."'for'".').replace(/_([0-9]+)$/, \'_\'+matchval));jQuery(this).attr('."'for',".'jQuery(this).attr('."'for'".').replace(/\[([0-9]+)\]$/, \'[\'+matchval+\']\'));});}}});for( var i=0;i<textarea_ids.length;i++) { tinyMCE.execCommand(' . "'mceAddControl'" . ',false, textarea_ids[i]); }jQuery(this).parent().css('."'visibility','hidden'".');return false;">' . __('Add New', 'custom-field-template') . '</a>';
 
 
 
 
 
 
 
 
 
2204
  else :
2205
  $addfield .= ' <a href="#clear" onclick="jQuery(this).parent().parent().parent().remove();return false;">' . __('Delete', 'custom-field-template') . '</a>';
2206
  endif;
@@ -2279,6 +2336,7 @@ tmp.find('."'input[type=text],input[type=hidden],input[type=file]'".').val('."''
2279
 
2280
  $out .= '<script type="text/javascript">' . "\n" .
2281
  '// <![CDATA[' . "\n";
 
2282
  $out .= 'function send_to_custom_field(h) {' . "\n" .
2283
  ' if ( tmpFocus ) ed = tmpFocus;' . "\n" .
2284
  ' else if ( typeof tinyMCE == "undefined" ) ed = document.getElementById("content");' . "\n" .
@@ -2309,6 +2367,18 @@ tmp.find('."'input[type=text],input[type=hidden],input[type=file]'".').val('."''
2309
  ' isTinyMCE = false;' . "\n";
2310
  }
2311
 
 
 
 
 
 
 
 
 
 
 
 
 
2312
  $out .= '}' . "\n" .
2313
  'jQuery(".thickbox").bind("click", function (e) {' . "\n" .
2314
  ' tmpFocus = undefined;' . "\n" .
@@ -2340,10 +2410,10 @@ tmp.find('."'input[type=text],input[type=hidden],input[type=file]'".').val('."''
2340
  ' var ed = tinyMCE.get(id);' . "\n" .
2341
  ' if ( ! ed || ed.isHidden() ) {' . "\n" .
2342
  ' document.getElementById(id).value = switchEditors.wpautop(document.getElementById(id).value);' . "\n" .
2343
- ' if ( ed ) { jQuery(\'#editorcontainer_\'+id).prev().hide(); ed.show(); }' . "\n" .
2344
- ' else {tinyMCE.execCommand("mceAddControl", false, id);}' . "\n" .
2345
  ' } else {' . "\n" .
2346
- ' ed.hide(); jQuery(\'#editorcontainer_\'+id).prev().show(); document.getElementById(id).style.color="#000000";' . "\n" .
2347
  ' }' . "\n" .
2348
  '}' . "\n";
2349
 
@@ -2486,7 +2556,13 @@ jQuery("#edButtonPreview").trigger("click"); }' . "\n";*/
2486
  $out .= $body;
2487
  $out .= '</div>';
2488
 
2489
- $out .= '<div style="position:absolute; top:30px; right:5px;">';
 
 
 
 
 
 
2490
  $out .= '<img class="waiting" style="display:none; vertical-align:middle;" src="images/loading.gif" alt="" id="cftloading_img" /> ';
2491
  if ( !empty($options['custom_field_template_use_disable_button']) ) :
2492
  $out .= '<input type="hidden" id="disable_value" value="0" />';
@@ -3194,7 +3270,7 @@ jQuery("#edButtonPreview").trigger("click"); }' . "\n";*/
3194
  endif;
3195
  if ( empty($value) && $val['outputNone'] ) $value = $val['outputNone'];
3196
  if ( $val['shortCode'] == true ) $value = do_shortcode($value);
3197
- if ( !empty($val['label']) && $options['custom_field_template_replace_keys_by_labels'] )
3198
  $key = stripcslashes($val['label']);
3199
  if ( $val['hideKey'] != true && $num == 0 )
3200
  $output .= '<dt>' . $key . '</dt>' . "\n";
4
  Plugin URI: http://wpgogo.com/development/custom-field-template.html
5
  Description: This plugin adds the default custom fields on the Write Post/Page.
6
  Author: Hiroaki Miyashita
7
+ Version: 1.9.5
8
  Author URI: http://wpgogo.com/
9
  */
10
 
66
  add_shortcode( 'cft', array(&$this, 'output_custom_field_values') );
67
  add_shortcode( 'cftsearch', array(&$this, 'search_custom_field_values') );
68
  endif;
69
+
70
  }
71
 
72
  function custom_field_template_init() {
148
  add_action( 'edit_form_advanced', array(&$this, 'insert_custom_field'), 1 );
149
  add_action( 'edit_page_form', array(&$this, 'insert_custom_field'), 1 );
150
  } else {
151
+ if ( substr($wp_version, 0, 3) >= '3.3' )
152
+ require_once(ABSPATH . 'wp-admin/includes/screen.php');
153
  require_once(ABSPATH . 'wp-admin/includes/template.php');
154
  add_meta_box('cftdiv', __('Custom Field Template', 'custom-field-template'), array(&$this, 'insert_custom_field'), 'post', 'normal', 'core');
155
  add_meta_box('cftdiv', __('Custom Field Template', 'custom-field-template'), array(&$this, 'insert_custom_field'), 'page', 'normal', 'core');
171
  endforeach;
172
  if ( isset($custom_post_type) && is_array($custom_post_type) ) :
173
  foreach( $custom_post_type as $val ) :
174
+ if ( function_exists('remove_meta_box') && !empty($options['custom_field_template_disable_default_custom_fields']) ) :
175
  remove_meta_box('postcustom', $val, 'normal');
176
  endif;
177
  add_meta_box('cftdiv', __('Custom Field Template', 'custom-field-template'), array(&$this, 'insert_custom_field'), $val, 'normal', 'core');
636
  #cft dd p.label { font-weight:bold; margin:0; }
637
  #cft_instruction { margin:10px; }
638
  #cft fieldset { border:1px solid #CCC; margin:5px; padding:5px; }
 
639
  #cft .dl_checkbox { margin:0; }
640
  ';
641
  update_option('custom_field_template_data', $options);
1885
  $out = '<script type="text/javascript">' . "\n" .
1886
  '// <![CDATA[' . "\n" .
1887
  'jQuery(document).ready(function() {if ( typeof tinyMCE != "undefined" ) {' . "\n";
1888
+
1889
+ if ( substr($wp_version, 0, 3) < '3.3' ) :
1890
+ $load_tinyMCE = 'tinyMCE.execCommand("mceAddControl", false, "'. $name . $rand . '");';
1891
+ $editorcontainer_class = ' class="editorcontainer"';
1892
+ else :
1893
+ $load_tinyMCE = 'var ed = new tinyMCE.Editor("'. $name . $rand . '", tinyMCEPreInit.mceInit["content"]); ed.render();';
1894
+ $editorcontainer_class = ' class="wp-editor-container"';
1895
+ endif;
1896
  if ( !empty($options['custom_field_template_use_wpautop']) ) :
1897
+ $out .= 'document.getElementById("'. $name . $rand . '").value = document.getElementById("'. $name . $rand . '").value; '.$load_tinyMCE.' tinyMCEID.push("'. $name . $rand . '");' . "\n";
1898
  else:
1899
+ $out .= 'document.getElementById("'. $name . $rand . '").value = switchEditors.wpautop(document.getElementById("'. $name . $rand . '").value); '.$load_tinyMCE.' tinyMCEID.push("'. $name . $rand . '");' . "\n";
1900
  endif;
1901
  $out .= '}});' . "\n";
1902
  $out .= '// ]]>' . "\n" . '</script>';
1908
 
1909
  if ( $mediaButton == true ) :
1910
  $media_upload_iframe_src = "media-upload.php";
1911
+
1912
+ if ( substr($wp_version, 0, 3) < '3.3' ) :
1913
+ if ( !$mediaOffImage ) :
1914
+ $image_upload_iframe_src = apply_filters('image_upload_iframe_src', "$media_upload_iframe_src?type=image");
1915
+ $image_title = __('Add an Image');
1916
+ $media .= "<a href=\"{$image_upload_iframe_src}&TB_iframe=true\" id=\"add_image{$rand}\" title='$image_title' onclick=\"focusTextArea('{$name}{$rand}'); jQuery(this).attr('href',jQuery(this).attr('href').replace('\?','?post_id='+jQuery('#post_ID').val())); return thickbox(this);\"><img src='images/media-button-image.gif' alt='$image_title' /></a> ";
1917
+ endif;
1918
+ if ( !$mediaOffVideo ) :
1919
+ $video_upload_iframe_src = apply_filters('video_upload_iframe_src', "$media_upload_iframe_src?type=video");
1920
+ $video_title = __('Add Video');
1921
+ $media .= "<a href=\"{$video_upload_iframe_src}&amp;TB_iframe=true\" id=\"add_video{$rand}\" title='$video_title' onclick=\"focusTextArea('{$name}{$rand}'); jQuery(this).attr('href',jQuery(this).attr('href').replace('\?','?post_id='+jQuery('#post_ID').val())); return thickbox(this);\"><img src='images/media-button-video.gif' alt='$video_title' /></a> ";
1922
+ endif;
1923
+ if ( !$mediaOffAudio ) :
1924
+ $audio_upload_iframe_src = apply_filters('audio_upload_iframe_src', "$media_upload_iframe_src?type=audio");
1925
+ $audio_title = __('Add Audio');
1926
+ $media .= "<a href=\"{$audio_upload_iframe_src}&amp;TB_iframe=true\" id=\"add_audio{$rand}\" title='$audio_title' onclick=\"focusTextArea('{$name}{$rand}'); jQuery(this).attr('href',jQuery(this).attr('href').replace('\?','?post_id='+jQuery('#post_ID').val())); return thickbox(this);\"><img src='images/media-button-music.gif' alt='$audio_title' /></a> ";
1927
+ endif;
1928
+ if ( !$mediaOffMedia ) :
1929
+ $media_title = __('Add Media');
1930
+ $media .= "<a href=\"{$media_upload_iframe_src}?TB_iframe=true\" id=\"add_media{$rand}\" title='$media_title' onclick=\"focusTextArea('{$name}{$rand}'); jQuery(this).attr('href',jQuery(this).attr('href').replace('\?','?post_id='+jQuery('#post_ID').val())); return thickbox(this);\"><img src='images/media-button-other.gif' alt='$media_title' /></a>";
1931
+ endif;
1932
+ else :
1933
  $media_title = __('Add Media');
1934
+ $media .= "<a href=\"{$media_upload_iframe_src}?TB_iframe=true\" id=\"add_media{$rand}\" title='$media_title' onclick=\"focusTextArea('{$name}{$rand}'); jQuery(this).attr('href',jQuery(this).attr('href').replace('\?','?post_id='+jQuery('#post_ID').val())); return thickbox(this);\"><img src='images/media-button.png' alt='$media_title' /></a>";
1935
  endif;
1936
  endif;
1937
 
1938
  $switch = '<div>';
1939
  if( $tinyMCE == true && user_can_richedit() ) {
1940
+ $switch .= '<a href="#toggle" onclick="switchMode(jQuery(this).parent().parent().parent().find(\'textarea\').attr(\'id\')); return false;">' . __('Toggle', 'custom-field-template') . '</a>';
1941
  }
1942
  $switch .= '</div>';
1943
  }
1946
 
1947
  if ( $hideKey == true ) $hide = ' class="hideKey"';
1948
  $content_class = ' class="';
1949
+ if ( $htmlEditor == true || $tinyMCE == true ) :
1950
+ if ( substr($wp_version, 0, 3) < '3.3' ) :
1951
+ $content_class .= 'content';
1952
+ else :
1953
+ $content_class .= 'wp-editor-area';
1954
+ endif;
1955
+ endif;
1956
  if ( !empty($class) ) $content_class .= ' ' . $class;
1957
  $content_class .= '"';
1958
  if ( !empty($style) ) $style = ' style="' . $style . '"';
1969
 
1970
  if ( $multipleButton == true && $ct_value == $cftnum ) :
1971
  $addfield .= '<div style="margin-top:-1em;">';
1972
+ if ( !empty($htmlEditor) ) :
1973
+ if ( substr($wp_version, 0, 3) < '3.3' ) :
1974
+ $load_htmlEditor1 = 'jQuery(\'#qt_\'+original_id+\'_qtags\').remove();';
1975
+ $load_htmlEditor2 = 'qt_set(original_id);qt_set(new_id);';
1976
+ if( $tinyMCE == true ) : $load_htmlEditor2 .= ' jQuery(\'#qt_\'+original_id+\'_qtags\').hide(); jQuery(\'#qt_\'+new_id+\'_qtags\').hide();'; endif;
1977
+ else :
1978
+ $load_htmlEditor1 = 'jQuery(\'#qt_\'+original_id+\'_toolbar\').remove();';
1979
+ $load_htmlEditor2 = 'new QTags(new_id);QTags._buttonsInit();';
1980
+ if( $tinyMCE == true ) : $load_htmlEditor2 .= ' jQuery(\'#qt_\'+new_id+\'_toolbar\').hide();'; endif;
1981
+ endif;
1982
+ endif;
1983
  if ( !empty($tinyMCE) ) :
1984
+ if ( substr($wp_version, 0, 3) < '3.3' ) :
1985
+ $load_tinyMCE = 'tinyMCE.execCommand(' . "'mceAddControl'" . ',false, original_id);tinyMCE.execCommand(' . "'mceAddControl'" . ',false, new_id);';
1986
+ else :
1987
+ $load_tinyMCE = 'var ed = new tinyMCE.Editor(original_id, tinyMCEPreInit.mceInit[\'content\']); ed.render(); var ed = new tinyMCE.Editor(new_id, tinyMCEPreInit.mceInit[\'content\']); ed.render();';
1988
+ endif;
1989
+
1990
+ $addfield .= '<a href="#clear" onclick="var original_id; var new_id; jQuery(this).parent().parent().parent().find('."'textarea'".').each(function(){original_id = jQuery(this).attr('."'id'".');'.$load_htmlEditor1.'tinyMCE.execCommand(' . "'mceRemoveControl'" . ',false,jQuery(this).attr('."'id'".'));});var clone = jQuery(this).parent().parent().parent().clone().insertAfter(jQuery(this).parent().parent().parent()); clone.find('."'textarea'".').val('."''".');if(original_id.match(/([0-9]+)$/)) {var matchval = RegExp.$1;re = new RegExp(matchval, '."'ig'".');clone.html(clone.html().replace(re, parseInt(matchval)+1)); new_id = original_id.replace(/([0-9]+)$/, parseInt(matchval)+1);}if ( tinyMCE.get(jQuery(this).attr('."original_id".')) ) {'.$load_tinyMCE.'}jQuery(this).parent().css('."'visibility','hidden'".');'.$load_htmlEditor2.'jQuery(this).parent().prev().css('."'visibility','hidden'".'); return false;">' . __('Add New', 'custom-field-template') . '</a>';
1991
  else :
1992
+ $addfield .= '<a href="#clear" onclick="var original_id; var new_id; jQuery(this).parent().parent().parent().find('."'textarea'".').each(function(){original_id = jQuery(this).attr('."'id'".');});'.$load_htmlEditor1.'var clone = jQuery(this).parent().parent().parent().clone().insertAfter(jQuery(this).parent().parent().parent()); clone.find('."'textarea'".').val('."''".');if(original_id.match(/([0-9]+)$/)) {var matchval = RegExp.$1;re = new RegExp(matchval, '."'ig'".');clone.html(clone.html().replace(re, parseInt(matchval)+1)); new_id = original_id.replace(/([0-9]+)$/, parseInt(matchval)+1);}'.$load_htmlEditor2.'jQuery(this).parent().css('."'visibility','hidden'".');jQuery(this).parent().prev().css('."'visibility','hidden'".'); return false;">' . __('Add New', 'custom-field-template') . '</a>';
1993
  endif;
1994
  $addfield .= '</div>';
1995
  endif;
2003
  $out .= '<p class="label">' . stripcslashes($label) . '</p>';
2004
 
2005
  $out .= trim($before);
2006
+
2007
+ if ( ($htmlEditor == true || $tinyMCE == true) && substr($wp_version, 0, 3) < '3.3' ) $out .= '<div class="quicktags">';
2008
 
2009
  if ( $htmlEditor == true ) :
2010
+ if ( substr($wp_version, 0, 3) < '3.3' ) :
2011
+ if( $tinyMCE == true ) $quicktags_hide = ' jQuery(\'#qt_' . $name . $rand . '_qtags\').hide();';
2012
+ $out .= '<script type="text/javascript">' . "\n" . '// <![CDATA[' . '
2013
+ jQuery(document).ready(function() { qt_' . $name . $rand . ' = new QTags(\'qt_' . $name . $rand . '\', \'' . $name . $rand . '\', \'editorcontainer_' . $name . $rand . '\', \'more\'); ' . $quicktags_hide . ' });' . "\n" . '// ]]>' . "\n" . '</script>';
2014
+ $editorcontainer_class = ' class="editorcontainer"';
2015
+ else :
2016
+ if( $tinyMCE == true ) $quicktags_hide = ' jQuery(\'#qt_' . $name . $rand . '_toolbar\').hide();';
2017
+ $out .= '<script type="text/javascript">' . "\n" . '// <![CDATA[' . '
2018
+ jQuery(document).ready(function() { new QTags(\'' . $name . $rand . '\'); QTags._buttonsInit(); ' . $quicktags_hide . ' }); ' . "\n";
2019
+ $out .= '// ]]>' . "\n" . '</script>';
2020
+ $editorcontainer_class = ' class="wp-editor-container"';
2021
+ endif;
2022
  endif;
2023
 
2024
  $out .= '<div' . $editorcontainer_class . ' id="editorcontainer_' . $name . $rand . '"><textarea id="' . $name . $rand . '" name="' . $name . '[' . $sid . '][]" rows="' .$rows. '" cols="' . $cols . '"' . $content_class . $style . $event_output . '>' . esc_attr(trim($value)) . '</textarea><input type="hidden" name="'.$name.'_rand['.$sid.']" value="'.$rand.'" /></div>';
2025
+ if ( ($htmlEditor == true || $tinyMCE == true) && substr($wp_version, 0, 3) < '3.3' ) $out .= '</div>';
2026
  $out .= trim($after).'</dd></dl>'."\n";
2027
 
2028
  return $out;
2247
  if ( isset($_REQUEST['post']) ) $addbutton = $this->get_post_meta( $_REQUEST['post'], $title, true )-1;
2248
  if ( !isset($addbutton) || $addbutton<=0 ) $addbutton = 0;
2249
  if ( $data['cftnum']/2 == $addbutton ) :
2250
+ if ( substr($wp_version, 0, 3) < '3.3' ) :
2251
+ $load_htmlEditor1 = 'if ( jQuery(\'#qt_\'+jQuery(this).attr('."'id'".')+\'_qtags\').html() ) {jQuery(\'#qt_\'+jQuery(this).attr('."'id'".')+\'_qtags\').remove();';
2252
+ $load_htmlEditor2 = 'qt_set(textarea_html_ids[i]);';
2253
+ $load_tinyMCE = 'tinyMCE.execCommand(' . "'mceAddControl'" . ',false, textarea_tmce_ids[i]); switchMode(textarea_tmce_ids[i]); switchMode(textarea_tmce_ids[i]);';
2254
+ else :
2255
+ $load_htmlEditor1 = 'if ( jQuery(\'#qt_\'+jQuery(this).attr('."'id'".')+\'_toolbar\').html() ) {jQuery(\'#qt_\'+jQuery(this).attr('."'id'".')+\'_toolbar\').remove();';
2256
+ $load_htmlEditor2 = 'new QTags(textarea_html_ids[i]);QTags._buttonsInit();';
2257
+ $load_tinyMCE = 'var ed = new tinyMCE.Editor(textarea_tmce_ids[i], tinyMCEPreInit.mceInit[\'content\']); ed.render(); switchMode(textarea_tmce_ids[i]); switchMode(textarea_tmce_ids[i]);';
2258
+ endif;
2259
+ $addfield .= '<input type="hidden" id="' . $this->sanitize_name( $title ) . '_count" value="0" /><script type="text/javascript">jQuery(document).ready(function() {jQuery(\'#' . $this->sanitize_name( $title ) . '_count\').val(0); });</script>';
2260
+ $addfield .= ' <a href="#clear" onclick="var textarea_tmce_ids = new Array();var textarea_html_ids = new Array();var html_start = 0;jQuery(this).parent().parent().parent().find('."'textarea'".').each(function(){if ( jQuery(this).attr('."'id'".') ) {'.$load_htmlEditor1.'if ( jQuery(\'#'.$this->sanitize_name( $title ).'_count\').val() == 0 ) html_start++;textarea_html_ids.push(jQuery(this).attr('."'id'".'));}}ed = tinyMCE.get(jQuery(this).attr('."'id'".')); if(ed) {textarea_tmce_ids.push(jQuery(this).attr('."'id'".'));tinyMCE.execCommand(' . "'mceRemoveControl'" . ',false,jQuery(this).attr('."'id'".'));}});var checked_ids = new Array();jQuery(this).parent().parent().parent().find('."'input[type=radio]:checked'".').each(function(){checked_ids.push(jQuery(this).attr('."'id'".'));});var tmp = jQuery(this).parent().parent().parent().clone().insertAfter(jQuery(this).parent().parent().parent());tmp.find('."'input'".').attr('."'checked',false".');for( var i=0;i<checked_ids.length;i++) { jQuery('."'#'+checked_ids[i]".').attr('."'checked'".', true); }tmp.find('."'input[type=text],input[type=hidden],input[type=file]'".').val('."''".');tmp.find('."'select'".').val('."''".');tmp.find('."'textarea'".').text('."''".');tmp.find('."'p'".').remove();tmp.find('."'dl'".').each(function(){if(jQuery(this).attr('."'id'".')){if(jQuery(this).attr('."'id'".').match(/_([0-9]+)$/)) {matchval = RegExp.$1;matchval++;jQuery(this).attr('."'id',".'jQuery(this).attr('."'id'".').replace(/_([0-9]+)$/, \'_\'+matchval));jQuery(this).find('."'textarea'".').each(function(){if(jQuery(this).attr('."'id'".').match(/([0-9]+)$/)) {var tmce_check = false;var html_check = false;for( var i=0;i<textarea_tmce_ids.length;i++) { if ( jQuery(this).attr('."'id'".')==textarea_tmce_ids[i] ) { tmce_check = true; } }for( var i=0;i<textarea_html_ids.length;i++) { if ( jQuery(this).attr('."'id'".')==textarea_html_ids[i] ) { html_check = true; } } if ( tmce_check || html_check ) {matchval2 = RegExp.$1;jQuery(this).attr('."'id',".'jQuery(this).attr('."'id'".').replace(/([0-9]+)$/, parseInt(matchval2)+1));re = new RegExp(matchval2, '."'ig'".');jQuery(this).parent().parent().parent().html(jQuery(this).parent().parent().parent().html().replace(re, parseInt(matchval2)+1));if ( tmce_check ) textarea_tmce_ids.push(jQuery(this).attr('."'id'".'));if ( html_check ) textarea_html_ids.push(jQuery(this).attr('."'id'".'));}}jQuery(this).attr('."'name',".'jQuery(this).attr('."'name'".').replace(/\[([0-9]+)\]$/, \'[\'+matchval+\']\'));});jQuery(this).find('."'input'".').each(function(){if(jQuery(this).attr('."'id'".')){jQuery(this).attr('."'id',".'jQuery(this).attr('."'id'".').replace(/_([0-9]+)_/, \'_\'+matchval+\'_\'));jQuery(this).attr('."'id',".'jQuery(this).attr('."'id'".').replace(/_([0-9]+)$/, \'_\'+matchval));}if(jQuery(this).attr('."'name'".')){jQuery(this).attr('."'name',".'jQuery(this).attr('."'name'".').replace(/\[([0-9]+)\]$/, \'[\'+matchval+\']\'));}});jQuery(this).find('."'label'".').each(function(){jQuery(this).attr('."'for',".'jQuery(this).attr('."'for'".').replace(/_([0-9]+)_/, \'_\'+matchval+\'_\'));jQuery(this).attr('."'for',".'jQuery(this).attr('."'for'".').replace(/_([0-9]+)$/, \'_\'+matchval));jQuery(this).attr('."'for',".'jQuery(this).attr('."'for'".').replace(/\[([0-9]+)\]$/, \'[\'+matchval+\']\'));});}}});for( var i=html_start;i<textarea_html_ids.length;i++) { '.$load_htmlEditor2.' }for( var i=html_start;i<textarea_tmce_ids.length;i++) { '.$load_tinyMCE.' }jQuery(this).parent().css('."'visibility','hidden'".');jQuery(\'#'.$this->sanitize_name( $title ).'_count\').val(parseInt(jQuery(\'#'.$this->sanitize_name( $title ).'_count\').val())+1);return false;">' . __('Add New', 'custom-field-template') . '</a>';
2261
  else :
2262
  $addfield .= ' <a href="#clear" onclick="jQuery(this).parent().parent().parent().remove();return false;">' . __('Delete', 'custom-field-template') . '</a>';
2263
  endif;
2336
 
2337
  $out .= '<script type="text/javascript">' . "\n" .
2338
  '// <![CDATA[' . "\n";
2339
+ $out .= 'function qt_set(new_id) { eval("qt_"+new_id+" = new QTags(\'qt_"+new_id+"\', \'"+new_id+"\', \'editorcontainer_"+new_id+"\', \'more\');");}';
2340
  $out .= 'function send_to_custom_field(h) {' . "\n" .
2341
  ' if ( tmpFocus ) ed = tmpFocus;' . "\n" .
2342
  ' else if ( typeof tinyMCE == "undefined" ) ed = document.getElementById("content");' . "\n" .
2367
  ' isTinyMCE = false;' . "\n";
2368
  }
2369
 
2370
+ if ( substr($wp_version, 0, 3) < '3.3' ) :
2371
+ $qt_position = 'prev()';
2372
+ else :
2373
+ $qt_position = 'children(\':first\')';
2374
+ endif;
2375
+
2376
+ if ( substr($wp_version, 0, 3) < '3.3' ) :
2377
+ $load_tinyMCE = 'tinyMCE.execCommand(' . "'mceAddControl'" . ',false, id);';
2378
+ else :
2379
+ $load_tinyMCE = 'var ed = new tinyMCE.Editor(id, tinyMCEPreInit.mceInit[\'content\']); ed.render();';
2380
+ endif;
2381
+
2382
  $out .= '}' . "\n" .
2383
  'jQuery(".thickbox").bind("click", function (e) {' . "\n" .
2384
  ' tmpFocus = undefined;' . "\n" .
2410
  ' var ed = tinyMCE.get(id);' . "\n" .
2411
  ' if ( ! ed || ed.isHidden() ) {' . "\n" .
2412
  ' document.getElementById(id).value = switchEditors.wpautop(document.getElementById(id).value);' . "\n" .
2413
+ ' if ( ed ) { jQuery(\'#editorcontainer_\'+id).'.$qt_position.'.hide(); ed.show(); }' . "\n" .
2414
+ ' else {'.$load_tinyMCE.'}' . "\n" .
2415
  ' } else {' . "\n" .
2416
+ ' ed.hide(); jQuery(\'#editorcontainer_\'+id).'.$qt_position.'.show(); document.getElementById(id).style.color="#000000";' . "\n" .
2417
  ' }' . "\n" .
2418
  '}' . "\n";
2419
 
2556
  $out .= $body;
2557
  $out .= '</div>';
2558
 
2559
+ if ( substr($wp_version, 0, 3) < '3.3' ) :
2560
+ $top_margin = 30;
2561
+ else :
2562
+ $top_margin = 0;
2563
+ endif;
2564
+
2565
+ $out .= '<div style="position:absolute; top:'.$top_margin.'px; right:5px;">';
2566
  $out .= '<img class="waiting" style="display:none; vertical-align:middle;" src="images/loading.gif" alt="" id="cftloading_img" /> ';
2567
  if ( !empty($options['custom_field_template_use_disable_button']) ) :
2568
  $out .= '<input type="hidden" id="disable_value" value="0" />';
3270
  endif;
3271
  if ( empty($value) && $val['outputNone'] ) $value = $val['outputNone'];
3272
  if ( $val['shortCode'] == true ) $value = do_shortcode($value);
3273
+ if ( !empty($val['label']) && !empty($options['custom_field_template_replace_keys_by_labels']) )
3274
  $key = stripcslashes($val['label']);
3275
  if ( $val['hideKey'] != true && $num == 0 )
3276
  $output .= '<dt>' . $key . '</dt>' . "\n";
js/jquery.validate.js CHANGED
@@ -1,1159 +1,1188 @@
1
- /**
2
- * jQuery Validation Plugin 1.8.0
3
- *
4
- * http://bassistance.de/jquery-plugins/jquery-plugin-validation/
5
- * http://docs.jquery.com/Plugins/Validation
6
- *
7
- * Copyright (c) 2006 - 2011 Jörn Zaefferer
8
- *
9
- * Dual licensed under the MIT and GPL licenses:
10
- * http://www.opensource.org/licenses/mit-license.php
11
- * http://www.gnu.org/licenses/gpl.html
12
- */
13
-
14
- (function($) {
15
-
16
- $.extend($.fn, {
17
- // http://docs.jquery.com/Plugins/Validation/validate
18
- validate: function( options ) {
19
-
20
- // if nothing is selected, return nothing; can't chain anyway
21
- if (!this.length) {
22
- options && options.debug && window.console && console.warn( "nothing selected, can't validate, returning nothing" );
23
- return;
24
- }
25
-
26
- // check if a validator for this form was already created
27
- var validator = $.data(this[0], 'validator');
28
- if ( validator ) {
29
- return validator;
30
- }
31
-
32
- validator = new $.validator( options, this[0] );
33
- $.data(this[0], 'validator', validator);
34
-
35
- if ( validator.settings.onsubmit ) {
36
-
37
- // allow suppresing validation by adding a cancel class to the submit button
38
- this.find("input, button").filter(".cancel").click(function() {
39
- validator.cancelSubmit = true;
40
- });
41
-
42
- // when a submitHandler is used, capture the submitting button
43
- if (validator.settings.submitHandler) {
44
- this.find("input, button").filter(":submit").click(function() {
45
- validator.submitButton = this;
46
- });
47
- }
48
-
49
- // validate the form on submit
50
- this.submit( function( event ) {
51
- if ( validator.settings.debug )
52
- // prevent form submit to be able to see console output
53
- event.preventDefault();
54
-
55
- function handle() {
56
- if ( validator.settings.submitHandler ) {
57
- if (validator.submitButton) {
58
- // insert a hidden input as a replacement for the missing submit button
59
- var hidden = $("<input type='hidden'/>").attr("name", validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm);
60
- }
61
- validator.settings.submitHandler.call( validator, validator.currentForm );
62
- if (validator.submitButton) {
63
- // and clean up afterwards; thanks to no-block-scope, hidden can be referenced
64
- hidden.remove();
65
- }
66
- return false;
67
- }
68
- return true;
69
- }
70
-
71
- // prevent submit for invalid forms or custom submit handlers
72
- if ( validator.cancelSubmit ) {
73
- validator.cancelSubmit = false;
74
- return handle();
75
- }
76
- if ( validator.form() ) {
77
- if ( validator.pendingRequest ) {
78
- validator.formSubmitted = true;
79
- return false;
80
- }
81
- return handle();
82
- } else {
83
- validator.focusInvalid();
84
- return false;
85
- }
86
- });
87
- }
88
-
89
- return validator;
90
- },
91
- // http://docs.jquery.com/Plugins/Validation/valid
92
- valid: function() {
93
- if ( $(this[0]).is('form')) {
94
- return this.validate().form();
95
- } else {
96
- var valid = true;
97
- var validator = $(this[0].form).validate();
98
- this.each(function() {
99
- valid &= validator.element(this);
100
- });
101
- return valid;
102
- }
103
- },
104
- // attributes: space seperated list of attributes to retrieve and remove
105
- removeAttrs: function(attributes) {
106
- var result = {},
107
- $element = this;
108
- $.each(attributes.split(/\s/), function(index, value) {
109
- result[value] = $element.attr(value);
110
- $element.removeAttr(value);
111
- });
112
- return result;
113
- },
114
- // http://docs.jquery.com/Plugins/Validation/rules
115
- rules: function(command, argument) {
116
- var element = this[0];
117
-
118
- if (command) {
119
- var settings = $.data(element.form, 'validator').settings;
120
- var staticRules = settings.rules;
121
- var existingRules = $.validator.staticRules(element);
122
- switch(command) {
123
- case "add":
124
- $.extend(existingRules, $.validator.normalizeRule(argument));
125
- staticRules[element.name] = existingRules;
126
- if (argument.messages)
127
- settings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages );
128
- break;
129
- case "remove":
130
- if (!argument) {
131
- delete staticRules[element.name];
132
- return existingRules;
133
- }
134
- var filtered = {};
135
- $.each(argument.split(/\s/), function(index, method) {
136
- filtered[method] = existingRules[method];
137
- delete existingRules[method];
138
- });
139
- return filtered;
140
- }
141
- }
142
-
143
- var data = $.validator.normalizeRules(
144
- $.extend(
145
- {},
146
- $.validator.metadataRules(element),
147
- $.validator.classRules(element),
148
- $.validator.attributeRules(element),
149
- $.validator.staticRules(element)
150
- ), element);
151
-
152
- // make sure required is at front
153
- if (data.required) {
154
- var param = data.required;
155
- delete data.required;
156
- data = $.extend({required: param}, data);
157
- }
158
-
159
- return data;
160
- }
161
- });
162
-
163
- // Custom selectors
164
- $.extend($.expr[":"], {
165
- // http://docs.jquery.com/Plugins/Validation/blank
166
- blank: function(a) {return !$.trim("" + a.value);},
167
- // http://docs.jquery.com/Plugins/Validation/filled
168
- filled: function(a) {return !!$.trim("" + a.value);},
169
- // http://docs.jquery.com/Plugins/Validation/unchecked
170
- unchecked: function(a) {return !a.checked;}
171
- });
172
-
173
- // constructor for validator
174
- $.validator = function( options, form ) {
175
- this.settings = $.extend( true, {}, $.validator.defaults, options );
176
- this.currentForm = form;
177
- this.init();
178
- };
179
-
180
- $.validator.format = function(source, params) {
181
- if ( arguments.length == 1 )
182
- return function() {
183
- var args = $.makeArray(arguments);
184
- args.unshift(source);
185
- return $.validator.format.apply( this, args );
186
- };
187
- if ( arguments.length > 2 && params.constructor != Array ) {
188
- params = $.makeArray(arguments).slice(1);
189
- }
190
- if ( params.constructor != Array ) {
191
- params = [ params ];
192
- }
193
- $.each(params, function(i, n) {
194
- source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n);
195
- });
196
- return source;
197
- };
198
-
199
- $.extend($.validator, {
200
-
201
- defaults: {
202
- messages: {},
203
- groups: {},
204
- rules: {},
205
- errorClass: "error",
206
- validClass: "valid",
207
- errorElement: "label",
208
- focusInvalid: true,
209
- errorContainer: $( [] ),
210
- errorLabelContainer: $( [] ),
211
- onsubmit: true,
212
- ignore: [],
213
- ignoreTitle: false,
214
- onfocusin: function(element) {
215
- this.lastActive = element;
216
-
217
- // hide error label and remove error class on focus if enabled
218
- if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {
219
- this.settings.unhighlight && this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
220
- this.addWrapper(this.errorsFor(element)).hide();
221
- }
222
- },
223
- onfocusout: function(element) {
224
- if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) {
225
- this.element(element);
226
- }
227
- },
228
- onkeyup: function(element) {
229
- if ( element.name in this.submitted || element == this.lastElement ) {
230
- this.element(element);
231
- }
232
- },
233
- onclick: function(element) {
234
- // click on selects, radiobuttons and checkboxes
235
- if ( element.name in this.submitted )
236
- this.element(element);
237
- // or option elements, check parent select in that case
238
- else if (element.parentNode.name in this.submitted)
239
- this.element(element.parentNode);
240
- },
241
- highlight: function( element, errorClass, validClass ) {
242
- $(element).addClass(errorClass).removeClass(validClass);
243
- },
244
- unhighlight: function( element, errorClass, validClass ) {
245
- $(element).removeClass(errorClass).addClass(validClass);
246
- }
247
- },
248
-
249
- // http://docs.jquery.com/Plugins/Validation/Validator/setDefaults
250
- setDefaults: function(settings) {
251
- $.extend( $.validator.defaults, settings );
252
- },
253
-
254
- messages: {
255
- required: "This field is required.",
256
- remote: "Please fix this field.",
257
- email: "Please enter a valid email address.",
258
- url: "Please enter a valid URL.",
259
- date: "Please enter a valid date.",
260
- dateISO: "Please enter a valid date (ISO).",
261
- number: "Please enter a valid number.",
262
- digits: "Please enter only digits.",
263
- creditcard: "Please enter a valid credit card number.",
264
- equalTo: "Please enter the same value again.",
265
- accept: "Please enter a value with a valid extension.",
266
- maxlength: $.validator.format("Please enter no more than {0} characters."),
267
- minlength: $.validator.format("Please enter at least {0} characters."),
268
- rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."),
269
- range: $.validator.format("Please enter a value between {0} and {1}."),
270
- max: $.validator.format("Please enter a value less than or equal to {0}."),
271
- min: $.validator.format("Please enter a value greater than or equal to {0}.")
272
- },
273
-
274
- autoCreateRanges: false,
275
-
276
- prototype: {
277
-
278
- init: function() {
279
- this.labelContainer = $(this.settings.errorLabelContainer);
280
- this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm);
281
- this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer );
282
- this.submitted = {};
283
- this.valueCache = {};
284
- this.pendingRequest = 0;
285
- this.pending = {};
286
- this.invalid = {};
287
- this.reset();
288
-
289
- var groups = (this.groups = {});
290
- $.each(this.settings.groups, function(key, value) {
291
- $.each(value.split(/\s/), function(index, name) {
292
- groups[name] = key;
293
- });
294
- });
295
- var rules = this.settings.rules;
296
- $.each(rules, function(key, value) {
297
- rules[key] = $.validator.normalizeRule(value);
298
- });
299
-
300
- function delegate(event) {
301
- var validator = $.data(this[0].form, "validator"),
302
- eventType = "on" + event.type.replace(/^validate/, "");
303
- validator.settings[eventType] && validator.settings[eventType].call(validator, this[0] );
304
- }
305
- $(this.currentForm)
306
- .validateDelegate(":text, :password, :file, select, textarea", "focusin focusout keyup", delegate)
307
- .validateDelegate(":radio, :checkbox, select, option", "click", delegate);
308
-
309
- if (this.settings.invalidHandler)
310
- $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);
311
- },
312
-
313
- // http://docs.jquery.com/Plugins/Validation/Validator/form
314
- form: function() {
315
- this.checkForm();
316
- $.extend(this.submitted, this.errorMap);
317
- this.invalid = $.extend({}, this.errorMap);
318
- if (!this.valid())
319
- $(this.currentForm).triggerHandler("invalid-form", [this]);
320
- this.showErrors();
321
- return this.valid();
322
- },
323
-
324
- checkForm: function() {
325
- this.prepareForm();
326
- for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) {
327
- this.check( elements[i] );
328
- }
329
- return this.valid();
330
- },
331
-
332
- // http://docs.jquery.com/Plugins/Validation/Validator/element
333
- element: function( element ) {
334
- element = this.clean( element );
335
- this.lastElement = element;
336
- this.prepareElement( element );
337
- this.currentElements = $(element);
338
- var result = this.check( element );
339
- if ( result ) {
340
- delete this.invalid[element.name];
341
- } else {
342
- this.invalid[element.name] = true;
343
- }
344
- if ( !this.numberOfInvalids() ) {
345
- // Hide error containers on last error
346
- this.toHide = this.toHide.add( this.containers );
347
- }
348
- this.showErrors();
349
- return result;
350
- },
351
-
352
- // http://docs.jquery.com/Plugins/Validation/Validator/showErrors
353
- showErrors: function(errors) {
354
- if(errors) {
355
- // add items to error list and map
356
- $.extend( this.errorMap, errors );
357
- this.errorList = [];
358
- for ( var name in errors ) {
359
- this.errorList.push({
360
- message: errors[name],
361
- element: this.findByName(name)[0]
362
- });
363
- }
364
- // remove items from success list
365
- this.successList = $.grep( this.successList, function(element) {
366
- return !(element.name in errors);
367
- });
368
- }
369
- this.settings.showErrors
370
- ? this.settings.showErrors.call( this, this.errorMap, this.errorList )
371
- : this.defaultShowErrors();
372
- },
373
-
374
- // http://docs.jquery.com/Plugins/Validation/Validator/resetForm
375
- resetForm: function() {
376
- if ( $.fn.resetForm )
377
- $( this.currentForm ).resetForm();
378
- this.submitted = {};
379
- this.prepareForm();
380
- this.hideErrors();
381
- this.elements().removeClass( this.settings.errorClass );
382
- },
383
-
384
- numberOfInvalids: function() {
385
- return this.objectLength(this.invalid);
386
- },
387
-
388
- objectLength: function( obj ) {
389
- var count = 0;
390
- for ( var i in obj )
391
- count++;
392
- return count;
393
- },
394
-
395
- hideErrors: function() {
396
- this.addWrapper( this.toHide ).hide();
397
- },
398
-
399
- valid: function() {
400
- return this.size() == 0;
401
- },
402
-
403
- size: function() {
404
- return this.errorList.length;
405
- },
406
-
407
- focusInvalid: function() {
408
- if( this.settings.focusInvalid ) {
409
- try {
410
- $(this.findLastActive() || this.errorList.length && this.errorList[0].element || [])
411
- .filter(":visible")
412
- .focus()
413
- // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
414
- .trigger("focusin");
415
- } catch(e) {
416
- // ignore IE throwing errors when focusing hidden elements
417
- }
418
- }
419
- },
420
-
421
- findLastActive: function() {
422
- var lastActive = this.lastActive;
423
- return lastActive && $.grep(this.errorList, function(n) {
424
- return n.element.name == lastActive.name;
425
- }).length == 1 && lastActive;
426
- },
427
-
428
- elements: function() {
429
- var validator = this,
430
- rulesCache = {};
431
-
432
- // select all valid inputs inside the form (no submit or reset buttons)
433
- // workaround $Query([]).add until http://dev.jquery.com/ticket/2114 is solved
434
- return $([]).add(this.currentForm.elements)
435
- .filter(":input")
436
- .not(":submit, :reset, :image, [disabled]")
437
- .not( this.settings.ignore )
438
- .filter(function() {
439
- !this.name && validator.settings.debug && window.console && console.error( "%o has no name assigned", this);
440
-
441
- // select only the first element for each name, and only those with rules specified
442
- if ( this.name in rulesCache || !validator.objectLength($(this).rules()) )
443
- return false;
444
-
445
- rulesCache[this.name] = true;
446
- return true;
447
- });
448
- },
449
-
450
- clean: function( selector ) {
451
- return $( selector )[0];
452
- },
453
-
454
- errors: function() {
455
- return $( this.settings.errorElement + "." + this.settings.errorClass, this.errorContext );
456
- },
457
-
458
- reset: function() {
459
- this.successList = [];
460
- this.errorList = [];
461
- this.errorMap = {};
462
- this.toShow = $([]);
463
- this.toHide = $([]);
464
- this.currentElements = $([]);
465
- },
466
-
467
- prepareForm: function() {
468
- this.reset();
469
- this.toHide = this.errors().add( this.containers );
470
- },
471
-
472
- prepareElement: function( element ) {
473
- this.reset();
474
- this.toHide = this.errorsFor(element);
475
- },
476
-
477
- check: function( element ) {
478
- element = this.clean( element );
479
-
480
- // if radio/checkbox, validate first element in group instead
481
- if (this.checkable(element)) {
482
- element = this.findByName( element.name ).not(this.settings.ignore)[0];
483
- }
484
-
485
- var rules = $(element).rules();
486
- var dependencyMismatch = false;
487
- for (var method in rules ) {
488
- var rule = { method: method, parameters: rules[method] };
489
- try {
490
- var result = $.validator.methods[method].call( this, element.value.replace(/\r/g, ""), element, rule.parameters );
491
-
492
- // if a method indicates that the field is optional and therefore valid,
493
- // don't mark it as valid when there are no other rules
494
- if ( result == "dependency-mismatch" ) {
495
- dependencyMismatch = true;
496
- continue;
497
- }
498
- dependencyMismatch = false;
499
-
500
- if ( result == "pending" ) {
501
- this.toHide = this.toHide.not( this.errorsFor(element) );
502
- return;
503
- }
504
-
505
- if( !result ) {
506
- this.formatAndAdd( element, rule );
507
- return false;
508
- }
509
- } catch(e) {
510
- this.settings.debug && window.console && console.log("exception occured when checking element " + element.id
511
- + ", check the '" + rule.method + "' method", e);
512
- throw e;
513
- }
514
- }
515
- if (dependencyMismatch)
516
- return;
517
- if ( this.objectLength(rules) )
518
- this.successList.push(element);
519
- return true;
520
- },
521
-
522
- // return the custom message for the given element and validation method
523
- // specified in the element's "messages" metadata
524
- customMetaMessage: function(element, method) {
525
- if (!$.metadata)
526
- return;
527
-
528
- var meta = this.settings.meta
529
- ? $(element).metadata()[this.settings.meta]
530
- : $(element).metadata();
531
-
532
- return meta && meta.messages && meta.messages[method];
533
- },
534
-
535
- // return the custom message for the given element name and validation method
536
- customMessage: function( name, method ) {
537
- var m = this.settings.messages[name];
538
- return m && (m.constructor == String
539
- ? m
540
- : m[method]);
541
- },
542
-
543
- // return the first defined argument, allowing empty strings
544
- findDefined: function() {
545
- for(var i = 0; i < arguments.length; i++) {
546
- if (arguments[i] !== undefined)
547
- return arguments[i];
548
- }
549
- return undefined;
550
- },
551
-
552
- defaultMessage: function( element, method) {
553
- return this.findDefined(
554
- this.customMessage( element.name, method ),
555
- this.customMetaMessage( element, method ),
556
- // title is never undefined, so handle empty string as undefined
557
- !this.settings.ignoreTitle && element.title || undefined,
558
- $.validator.messages[method],
559
- "<strong>Warning: No message defined for " + element.name + "</strong>"
560
- );
561
- },
562
-
563
- formatAndAdd: function( element, rule ) {
564
- var message = this.defaultMessage( element, rule.method ),
565
- theregex = /\$?\{(\d+)\}/g;
566
- if ( typeof message == "function" ) {
567
- message = message.call(this, rule.parameters, element);
568
- } else if (theregex.test(message)) {
569
- message = jQuery.format(message.replace(theregex, '{$1}'), rule.parameters);
570
- }
571
- this.errorList.push({
572
- message: message,
573
- element: element
574
- });
575
-
576
- this.errorMap[element.name] = message;
577
- this.submitted[element.name] = message;
578
- },
579
-
580
- addWrapper: function(toToggle) {
581
- if ( this.settings.wrapper )
582
- toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
583
- return toToggle;
584
- },
585
-
586
- defaultShowErrors: function() {
587
- for ( var i = 0; this.errorList[i]; i++ ) {
588
- var error = this.errorList[i];
589
- this.settings.highlight && this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
590
- this.showLabel( error.element, error.message );
591
- }
592
- if( this.errorList.length ) {
593
- this.toShow = this.toShow.add( this.containers );
594
- }
595
- if (this.settings.success) {
596
- for ( var i = 0; this.successList[i]; i++ ) {
597
- this.showLabel( this.successList[i] );
598
- }
599
- }
600
- if (this.settings.unhighlight) {
601
- for ( var i = 0, elements = this.validElements(); elements[i]; i++ ) {
602
- this.settings.unhighlight.call( this, elements[i], this.settings.errorClass, this.settings.validClass );
603
- }
604
- }
605
- this.toHide = this.toHide.not( this.toShow );
606
- this.hideErrors();
607
- this.addWrapper( this.toShow ).show();
608
- },
609
-
610
- validElements: function() {
611
- return this.currentElements.not(this.invalidElements());
612
- },
613
-
614
- invalidElements: function() {
615
- return $(this.errorList).map(function() {
616
- return this.element;
617
- });
618
- },
619
-
620
- showLabel: function(element, message) {
621
- var label = this.errorsFor( element );
622
- if ( label.length ) {
623
- // refresh error/success class
624
- label.removeClass().addClass( this.settings.errorClass );
625
-
626
- // check if we have a generated label, replace the message then
627
- label.attr("generated") && label.html(message);
628
- } else {
629
- // create label
630
- label = $("<" + this.settings.errorElement + "/>")
631
- .attr({"for": this.idOrName(element), generated: true})
632
- .addClass(this.settings.errorClass)
633
- .html(message || "");
634
- if ( this.settings.wrapper ) {
635
- // make sure the element is visible, even in IE
636
- // actually showing the wrapped element is handled elsewhere
637
- label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
638
- }
639
- if ( !this.labelContainer.append(label).length )
640
- this.settings.errorPlacement
641
- ? this.settings.errorPlacement(label, $(element) )
642
- : label.insertAfter(element);
643
- }
644
- if ( !message && this.settings.success ) {
645
- label.text("");
646
- typeof this.settings.success == "string"
647
- ? label.addClass( this.settings.success )
648
- : this.settings.success( label );
649
- }
650
- this.toShow = this.toShow.add(label);
651
- },
652
-
653
- errorsFor: function(element) {
654
- var name = this.idOrName(element);
655
- return this.errors().filter(function() {
656
- return $(this).attr('for') == name;
657
- });
658
- },
659
-
660
- idOrName: function(element) {
661
- return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name);
662
- },
663
-
664
- checkable: function( element ) {
665
- return /radio|checkbox/i.test(element.type);
666
- },
667
-
668
- findByName: function( name ) {
669
- // select by name and filter by form for performance over form.find("[name=...]")
670
- var form = this.currentForm;
671
- return $(document.getElementsByName(name)).map(function(index, element) {
672
- return element.form == form && element.name == name && element || null;
673
- });
674
- },
675
-
676
- getLength: function(value, element) {
677
- switch( element.nodeName.toLowerCase() ) {
678
- case 'select':
679
- return $("option:selected", element).length;
680
- case 'input':
681
- if( this.checkable( element) )
682
- return this.findByName(element.name).filter(':checked').length;
683
- }
684
- return value.length;
685
- },
686
-
687
- depend: function(param, element) {
688
- return this.dependTypes[typeof param]
689
- ? this.dependTypes[typeof param](param, element)
690
- : true;
691
- },
692
-
693
- dependTypes: {
694
- "boolean": function(param, element) {
695
- return param;
696
- },
697
- "string": function(param, element) {
698
- return !!$(param, element.form).length;
699
- },
700
- "function": function(param, element) {
701
- return param(element);
702
- }
703
- },
704
-
705
- optional: function(element) {
706
- return !$.validator.methods.required.call(this, $.trim(element.value), element) && "dependency-mismatch";
707
- },
708
-
709
- startRequest: function(element) {
710
- if (!this.pending[element.name]) {
711
- this.pendingRequest++;
712
- this.pending[element.name] = true;
713
- }
714
- },
715
-
716
- stopRequest: function(element, valid) {
717
- this.pendingRequest--;
718
- // sometimes synchronization fails, make sure pendingRequest is never < 0
719
- if (this.pendingRequest < 0)
720
- this.pendingRequest = 0;
721
- delete this.pending[element.name];
722
- if ( valid && this.pendingRequest == 0 && this.formSubmitted && this.form() ) {
723
- $(this.currentForm).submit();
724
- this.formSubmitted = false;
725
- } else if (!valid && this.pendingRequest == 0 && this.formSubmitted) {
726
- $(this.currentForm).triggerHandler("invalid-form", [this]);
727
- this.formSubmitted = false;
728
- }
729
- },
730
-
731
- previousValue: function(element) {
732
- return $.data(element, "previousValue") || $.data(element, "previousValue", {
733
- old: null,
734
- valid: true,
735
- message: this.defaultMessage( element, "remote" )
736
- });
737
- }
738
-
739
- },
740
-
741
- classRuleSettings: {
742
- required: {required: true},
743
- email: {email: true},
744
- url: {url: true},
745
- date: {date: true},
746
- dateISO: {dateISO: true},
747
- dateDE: {dateDE: true},
748
- number: {number: true},
749
- numberDE: {numberDE: true},
750
- digits: {digits: true},
751
- creditcard: {creditcard: true}
752
- },
753
-
754
- addClassRules: function(className, rules) {
755
- className.constructor == String ?
756
- this.classRuleSettings[className] = rules :
757
- $.extend(this.classRuleSettings, className);
758
- },
759
-
760
- classRules: function(element) {
761
- var rules = {};
762
- var classes = $(element).attr('class');
763
- classes && $.each(classes.split(' '), function() {
764
- if (this in $.validator.classRuleSettings) {
765
- $.extend(rules, $.validator.classRuleSettings[this]);
766
- }
767
- });
768
- return rules;
769
- },
770
-
771
- attributeRules: function(element) {
772
- var rules = {};
773
- var $element = $(element);
774
-
775
- for (var method in $.validator.methods) {
776
- var value = $element.attr(method);
777
- if (value) {
778
- rules[method] = value;
779
- }
780
- }
781
-
782
- // maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs
783
- if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) {
784
- delete rules.maxlength;
785
- }
786
-
787
- return rules;
788
- },
789
-
790
- metadataRules: function(element) {
791
- if (!$.metadata) return {};
792
-
793
- var meta = $.data(element.form, 'validator').settings.meta;
794
- return meta ?
795
- $(element).metadata()[meta] :
796
- $(element).metadata();
797
- },
798
-
799
- staticRules: function(element) {
800
- var rules = {};
801
- var validator = $.data(element.form, 'validator');
802
- if (validator.settings.rules) {
803
- rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {};
804
- }
805
- return rules;
806
- },
807
-
808
- normalizeRules: function(rules, element) {
809
- // handle dependency check
810
- $.each(rules, function(prop, val) {
811
- // ignore rule when param is explicitly false, eg. required:false
812
- if (val === false) {
813
- delete rules[prop];
814
- return;
815
- }
816
- if (val.param || val.depends) {
817
- var keepRule = true;
818
- switch (typeof val.depends) {
819
- case "string":
820
- keepRule = !!$(val.depends, element.form).length;
821
- break;
822
- case "function":
823
- keepRule = val.depends.call(element, element);
824
- break;
825
- }
826
- if (keepRule) {
827
- rules[prop] = val.param !== undefined ? val.param : true;
828
- } else {
829
- delete rules[prop];
830
- }
831
- }
832
- });
833
-
834
- // evaluate parameters
835
- $.each(rules, function(rule, parameter) {
836
- rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter;
837
- });
838
-
839
- // clean number parameters
840
- $.each(['minlength', 'maxlength', 'min', 'max'], function() {
841
- if (rules[this]) {
842
- rules[this] = Number(rules[this]);
843
- }
844
- });
845
- $.each(['rangelength', 'range'], function() {
846
- if (rules[this]) {
847
- rules[this] = [Number(rules[this][0]), Number(rules[this][1])];
848
- }
849
- });
850
-
851
- if ($.validator.autoCreateRanges) {
852
- // auto-create ranges
853
- if (rules.min && rules.max) {
854
- rules.range = [rules.min, rules.max];
855
- delete rules.min;
856
- delete rules.max;
857
- }
858
- if (rules.minlength && rules.maxlength) {
859
- rules.rangelength = [rules.minlength, rules.maxlength];
860
- delete rules.minlength;
861
- delete rules.maxlength;
862
- }
863
- }
864
-
865
- // To support custom messages in metadata ignore rule methods titled "messages"
866
- if (rules.messages) {
867
- delete rules.messages;
868
- }
869
-
870
- return rules;
871
- },
872
-
873
- // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
874
- normalizeRule: function(data) {
875
- if( typeof data == "string" ) {
876
- var transformed = {};
877
- $.each(data.split(/\s/), function() {
878
- transformed[this] = true;
879
- });
880
- data = transformed;
881
- }
882
- return data;
883
- },
884
-
885
- // http://docs.jquery.com/Plugins/Validation/Validator/addMethod
886
- addMethod: function(name, method, message) {
887
- $.validator.methods[name] = method;
888
- $.validator.messages[name] = message != undefined ? message : $.validator.messages[name];
889
- if (method.length < 3) {
890
- $.validator.addClassRules(name, $.validator.normalizeRule(name));
891
- }
892
- },
893
-
894
- methods: {
895
-
896
- // http://docs.jquery.com/Plugins/Validation/Methods/required
897
- required: function(value, element, param) {
898
- // check if dependency is met
899
- if ( !this.depend(param, element) )
900
- return "dependency-mismatch";
901
- switch( element.nodeName.toLowerCase() ) {
902
- case 'select':
903
- // could be an array for select-multiple or a string, both are fine this way
904
- var val = $(element).val();
905
- return val && val.length > 0;
906
- case 'input':
907
- if ( this.checkable(element) )
908
- return this.getLength(value, element) > 0;
909
- default:
910
- return $.trim(value).length > 0;
911
- }
912
- },
913
-
914
- // http://docs.jquery.com/Plugins/Validation/Methods/remote
915
- remote: function(value, element, param) {
916
- if ( this.optional(element) )
917
- return "dependency-mismatch";
918
-
919
- var previous = this.previousValue(element);
920
- if (!this.settings.messages[element.name] )
921
- this.settings.messages[element.name] = {};
922
- previous.originalMessage = this.settings.messages[element.name].remote;
923
- this.settings.messages[element.name].remote = previous.message;
924
-
925
- param = typeof param == "string" && {url:param} || param;
926
-
927
- if ( this.pending[element.name] ) {
928
- return "pending";
929
- }
930
- if ( previous.old === value ) {
931
- return previous.valid;
932
- }
933
-
934
- previous.old = value;
935
- var validator = this;
936
- this.startRequest(element);
937
- var data = {};
938
- data[element.name] = value;
939
- $.ajax($.extend(true, {
940
- url: param,
941
- mode: "abort",
942
- port: "validate" + element.name,
943
- dataType: "json",
944
- data: data,
945
- success: function(response) {
946
- validator.settings.messages[element.name].remote = previous.originalMessage;
947
- var valid = response === true;
948
- if ( valid ) {
949
- var submitted = validator.formSubmitted;
950
- validator.prepareElement(element);
951
- validator.formSubmitted = submitted;
952
- validator.successList.push(element);
953
- validator.showErrors();
954
- } else {
955
- var errors = {};
956
- var message = response || validator.defaultMessage( element, "remote" );
957
- errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message;
958
- validator.showErrors(errors);
959
- }
960
- previous.valid = valid;
961
- validator.stopRequest(element, valid);
962
- }
963
- }, param));
964
- return "pending";
965
- },
966
-
967
- // http://docs.jquery.com/Plugins/Validation/Methods/minlength
968
- minlength: function(value, element, param) {
969
- return this.optional(element) || this.getLength($.trim(value), element) >= param;
970
- },
971
-
972
- // http://docs.jquery.com/Plugins/Validation/Methods/maxlength
973
- maxlength: function(value, element, param) {
974
- return this.optional(element) || this.getLength($.trim(value), element) <= param;
975
- },
976
-
977
- // http://docs.jquery.com/Plugins/Validation/Methods/rangelength
978
- rangelength: function(value, element, param) {
979
- var length = this.getLength($.trim(value), element);
980
- return this.optional(element) || ( length >= param[0] && length <= param[1] );
981
- },
982
-
983
- // http://docs.jquery.com/Plugins/Validation/Methods/min
984
- min: function( value, element, param ) {
985
- return this.optional(element) || value >= param;
986
- },
987
-
988
- // http://docs.jquery.com/Plugins/Validation/Methods/max
989
- max: function( value, element, param ) {
990
- return this.optional(element) || value <= param;
991
- },
992
-
993
- // http://docs.jquery.com/Plugins/Validation/Methods/range
994
- range: function( value, element, param ) {
995
- return this.optional(element) || ( value >= param[0] && value <= param[1] );
996
- },
997
-
998
- // http://docs.jquery.com/Plugins/Validation/Methods/email
999
- email: function(value, element) {
1000
- // contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
1001
- return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value);
1002
- },
1003
-
1004
- // http://docs.jquery.com/Plugins/Validation/Methods/url
1005
- url: function(value, element) {
1006
- // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
1007
- return this.optional(element) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
1008
- },
1009
-
1010
- // http://docs.jquery.com/Plugins/Validation/Methods/date
1011
- date: function(value, element) {
1012
- return this.optional(element) || !/Invalid|NaN/.test(new Date(value));
1013
- },
1014
-
1015
- // http://docs.jquery.com/Plugins/Validation/Methods/dateISO
1016
- dateISO: function(value, element) {
1017
- return this.optional(element) || /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value);
1018
- },
1019
-
1020
- // http://docs.jquery.com/Plugins/Validation/Methods/number
1021
- number: function(value, element) {
1022
- return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value);
1023
- },
1024
-
1025
- // http://docs.jquery.com/Plugins/Validation/Methods/digits
1026
- digits: function(value, element) {
1027
- return this.optional(element) || /^\d+$/.test(value);
1028
- },
1029
-
1030
- // http://docs.jquery.com/Plugins/Validation/Methods/creditcard
1031
- // based on http://en.wikipedia.org/wiki/Luhn
1032
- creditcard: function(value, element) {
1033
- if ( this.optional(element) )
1034
- return "dependency-mismatch";
1035
- // accept only digits and dashes
1036
- if (/[^0-9-]+/.test(value))
1037
- return false;
1038
- var nCheck = 0,
1039
- nDigit = 0,
1040
- bEven = false;
1041
-
1042
- value = value.replace(/\D/g, "");
1043
-
1044
- for (var n = value.length - 1; n >= 0; n--) {
1045
- var cDigit = value.charAt(n);
1046
- var nDigit = parseInt(cDigit, 10);
1047
- if (bEven) {
1048
- if ((nDigit *= 2) > 9)
1049
- nDigit -= 9;
1050
- }
1051
- nCheck += nDigit;
1052
- bEven = !bEven;
1053
- }
1054
-
1055
- return (nCheck % 10) == 0;
1056
- },
1057
-
1058
- // http://docs.jquery.com/Plugins/Validation/Methods/accept
1059
- accept: function(value, element, param) {
1060
- param = typeof param == "string" ? param.replace(/,/g, '|') : "png|jpe?g|gif";
1061
- return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i"));
1062
- },
1063
-
1064
- // http://docs.jquery.com/Plugins/Validation/Methods/equalTo
1065
- equalTo: function(value, element, param) {
1066
- // bind to the blur event of the target in order to revalidate whenever the target field is updated
1067
- // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead
1068
- var target = $(param).unbind(".validate-equalTo").bind("blur.validate-equalTo", function() {
1069
- $(element).valid();
1070
- });
1071
- return value == target.val();
1072
- }
1073
-
1074
- }
1075
-
1076
- });
1077
-
1078
- // deprecated, use $.validator.format instead
1079
- $.format = $.validator.format;
1080
-
1081
- })(jQuery);
1082
-
1083
- // ajax mode: abort
1084
- // usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
1085
- // if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
1086
- ;(function($) {
1087
- var pendingRequests = {};
1088
- // Use a prefilter if available (1.5+)
1089
- if ( $.ajaxPrefilter ) {
1090
- $.ajaxPrefilter(function(settings, _, xhr) {
1091
- var port = settings.port;
1092
- if (settings.mode == "abort") {
1093
- if ( pendingRequests[port] ) {
1094
- pendingRequests[port].abort();
1095
- }
1096
- pendingRequests[port] = xhr;
1097
- }
1098
- });
1099
- } else {
1100
- // Proxy ajax
1101
- var ajax = $.ajax;
1102
- $.ajax = function(settings) {
1103
- var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
1104
- port = ( "port" in settings ? settings : $.ajaxSettings ).port;
1105
- if (mode == "abort") {
1106
- if ( pendingRequests[port] ) {
1107
- pendingRequests[port].abort();
1108
- }
1109
- return (pendingRequests[port] = ajax.apply(this, arguments));
1110
- }
1111
- return ajax.apply(this, arguments);
1112
- };
1113
- }
1114
- })(jQuery);
1115
-
1116
- // provides cross-browser focusin and focusout events
1117
- // IE has native support, in other browsers, use event caputuring (neither bubbles)
1118
-
1119
- // provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
1120
- // handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target
1121
- ;(function($) {
1122
- // only implement if not provided by jQuery core (since 1.4)
1123
- // TODO verify if jQuery 1.4's implementation is compatible with older jQuery special-event APIs
1124
- if (!jQuery.event.special.focusin && !jQuery.event.special.focusout && document.addEventListener) {
1125
- $.each({
1126
- focus: 'focusin',
1127
- blur: 'focusout'
1128
- }, function( original, fix ){
1129
- $.event.special[fix] = {
1130
- setup:function() {
1131
- this.addEventListener( original, handler, true );
1132
- },
1133
- teardown:function() {
1134
- this.removeEventListener( original, handler, true );
1135
- },
1136
- handler: function(e) {
1137
- arguments[0] = $.event.fix(e);
1138
- arguments[0].type = fix;
1139
- return $.event.handle.apply(this, arguments);
1140
- }
1141
- };
1142
- function handler(e) {
1143
- e = $.event.fix(e);
1144
- e.type = fix;
1145
- return $.event.handle.call(this, e);
1146
- }
1147
- });
1148
- };
1149
- $.extend($.fn, {
1150
- validateDelegate: function(delegate, type, handler) {
1151
- return this.bind(type, function(event) {
1152
- var target = $(event.target);
1153
- if (target.is(delegate)) {
1154
- return handler.apply(target, arguments);
1155
- }
1156
- });
1157
- }
1158
- });
1159
- })(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * jQuery Validation Plugin 1.9.0
3
+ *
4
+ * http://bassistance.de/jquery-plugins/jquery-plugin-validation/
5
+ * http://docs.jquery.com/Plugins/Validation
6
+ *
7
+ * Copyright (c) 2006 - 2011 Jörn Zaefferer
8
+ *
9
+ * Dual licensed under the MIT and GPL licenses:
10
+ * http://www.opensource.org/licenses/mit-license.php
11
+ * http://www.gnu.org/licenses/gpl.html
12
+ */
13
+
14
+ (function($) {
15
+
16
+ $.extend($.fn, {
17
+ // http://docs.jquery.com/Plugins/Validation/validate
18
+ validate: function( options ) {
19
+
20
+ // if nothing is selected, return nothing; can't chain anyway
21
+ if (!this.length) {
22
+ options && options.debug && window.console && console.warn( "nothing selected, can't validate, returning nothing" );
23
+ return;
24
+ }
25
+
26
+ // check if a validator for this form was already created
27
+ var validator = $.data(this[0], 'validator');
28
+ if ( validator ) {
29
+ return validator;
30
+ }
31
+
32
+ // Add novalidate tag if HTML5.
33
+ this.attr('novalidate', 'novalidate');
34
+
35
+ validator = new $.validator( options, this[0] );
36
+ $.data(this[0], 'validator', validator);
37
+
38
+ if ( validator.settings.onsubmit ) {
39
+
40
+ var inputsAndButtons = this.find("input, button");
41
+
42
+ // allow suppresing validation by adding a cancel class to the submit button
43
+ inputsAndButtons.filter(".cancel").click(function () {
44
+ validator.cancelSubmit = true;
45
+ });
46
+
47
+ // when a submitHandler is used, capture the submitting button
48
+ if (validator.settings.submitHandler) {
49
+ inputsAndButtons.filter(":submit").click(function () {
50
+ validator.submitButton = this;
51
+ });
52
+ }
53
+
54
+ // validate the form on submit
55
+ this.submit( function( event ) {
56
+ if ( validator.settings.debug )
57
+ // prevent form submit to be able to see console output
58
+ event.preventDefault();
59
+
60
+ function handle() {
61
+ if ( validator.settings.submitHandler ) {
62
+ if (validator.submitButton) {
63
+ // insert a hidden input as a replacement for the missing submit button
64
+ var hidden = $("<input type='hidden'/>").attr("name", validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm);
65
+ }
66
+ validator.settings.submitHandler.call( validator, validator.currentForm );
67
+ if (validator.submitButton) {
68
+ // and clean up afterwards; thanks to no-block-scope, hidden can be referenced
69
+ hidden.remove();
70
+ }
71
+ return false;
72
+ }
73
+ return true;
74
+ }
75
+
76
+ // prevent submit for invalid forms or custom submit handlers
77
+ if ( validator.cancelSubmit ) {
78
+ validator.cancelSubmit = false;
79
+ return handle();
80
+ }
81
+ if ( validator.form() ) {
82
+ if ( validator.pendingRequest ) {
83
+ validator.formSubmitted = true;
84
+ return false;
85
+ }
86
+ return handle();
87
+ } else {
88
+ validator.focusInvalid();
89
+ return false;
90
+ }
91
+ });
92
+ }
93
+
94
+ return validator;
95
+ },
96
+ // http://docs.jquery.com/Plugins/Validation/valid
97
+ valid: function() {
98
+ if ( $(this[0]).is('form')) {
99
+ return this.validate().form();
100
+ } else {
101
+ var valid = true;
102
+ var validator = $(this[0].form).validate();
103
+ this.each(function() {
104
+ valid &= validator.element(this);
105
+ });
106
+ return valid;
107
+ }
108
+ },
109
+ // attributes: space seperated list of attributes to retrieve and remove
110
+ removeAttrs: function(attributes) {
111
+ var result = {},
112
+ $element = this;
113
+ $.each(attributes.split(/\s/), function(index, value) {
114
+ result[value] = $element.attr(value);
115
+ $element.removeAttr(value);
116
+ });
117
+ return result;
118
+ },
119
+ // http://docs.jquery.com/Plugins/Validation/rules
120
+ rules: function(command, argument) {
121
+ var element = this[0];
122
+
123
+ if (command) {
124
+ var settings = $.data(element.form, 'validator').settings;
125
+ var staticRules = settings.rules;
126
+ var existingRules = $.validator.staticRules(element);
127
+ switch(command) {
128
+ case "add":
129
+ $.extend(existingRules, $.validator.normalizeRule(argument));
130
+ staticRules[element.name] = existingRules;
131
+ if (argument.messages)
132
+ settings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages );
133
+ break;
134
+ case "remove":
135
+ if (!argument) {
136
+ delete staticRules[element.name];
137
+ return existingRules;
138
+ }
139
+ var filtered = {};
140
+ $.each(argument.split(/\s/), function(index, method) {
141
+ filtered[method] = existingRules[method];
142
+ delete existingRules[method];
143
+ });
144
+ return filtered;
145
+ }
146
+ }
147
+
148
+ var data = $.validator.normalizeRules(
149
+ $.extend(
150
+ {},
151
+ $.validator.metadataRules(element),
152
+ $.validator.classRules(element),
153
+ $.validator.attributeRules(element),
154
+ $.validator.staticRules(element)
155
+ ), element);
156
+
157
+ // make sure required is at front
158
+ if (data.required) {
159
+ var param = data.required;
160
+ delete data.required;
161
+ data = $.extend({required: param}, data);
162
+ }
163
+
164
+ return data;
165
+ }
166
+ });
167
+
168
+ // Custom selectors
169
+ $.extend($.expr[":"], {
170
+ // http://docs.jquery.com/Plugins/Validation/blank
171
+ blank: function(a) {return !$.trim("" + a.value);},
172
+ // http://docs.jquery.com/Plugins/Validation/filled
173
+ filled: function(a) {return !!$.trim("" + a.value);},
174
+ // http://docs.jquery.com/Plugins/Validation/unchecked
175
+ unchecked: function(a) {return !a.checked;}
176
+ });
177
+
178
+ // constructor for validator
179
+ $.validator = function( options, form ) {
180
+ this.settings = $.extend( true, {}, $.validator.defaults, options );
181
+ this.currentForm = form;
182
+ this.init();
183
+ };
184
+
185
+ $.validator.format = function(source, params) {
186
+ if ( arguments.length == 1 )
187
+ return function() {
188
+ var args = $.makeArray(arguments);
189
+ args.unshift(source);
190
+ return $.validator.format.apply( this, args );
191
+ };
192
+ if ( arguments.length > 2 && params.constructor != Array ) {
193
+ params = $.makeArray(arguments).slice(1);
194
+ }
195
+ if ( params.constructor != Array ) {
196
+ params = [ params ];
197
+ }
198
+ $.each(params, function(i, n) {
199
+ source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n);
200
+ });
201
+ return source;
202
+ };
203
+
204
+ $.extend($.validator, {
205
+
206
+ defaults: {
207
+ messages: {},
208
+ groups: {},
209
+ rules: {},
210
+ errorClass: "error",
211
+ validClass: "valid",
212
+ errorElement: "label",
213
+ focusInvalid: true,
214
+ errorContainer: $( [] ),
215
+ errorLabelContainer: $( [] ),
216
+ onsubmit: true,
217
+ ignore: ":hidden",
218
+ ignoreTitle: false,
219
+ onfocusin: function(element, event) {
220
+ this.lastActive = element;
221
+
222
+ // hide error label and remove error class on focus if enabled
223
+ if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {
224
+ this.settings.unhighlight && this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
225
+ this.addWrapper(this.errorsFor(element)).hide();
226
+ }
227
+ },
228
+ onfocusout: function(element, event) {
229
+ if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) {
230
+ this.element(element);
231
+ }
232
+ },
233
+ onkeyup: function(element, event) {
234
+ if ( element.name in this.submitted || element == this.lastElement ) {
235
+ this.element(element);
236
+ }
237
+ },
238
+ onclick: function(element, event) {
239
+ // click on selects, radiobuttons and checkboxes
240
+ if ( element.name in this.submitted )
241
+ this.element(element);
242
+ // or option elements, check parent select in that case
243
+ else if (element.parentNode.name in this.submitted)
244
+ this.element(element.parentNode);
245
+ },
246
+ highlight: function(element, errorClass, validClass) {
247
+ if (element.type === 'radio') {
248
+ this.findByName(element.name).addClass(errorClass).removeClass(validClass);
249
+ } else {
250
+ $(element).addClass(errorClass).removeClass(validClass);
251
+ }
252
+ },
253
+ unhighlight: function(element, errorClass, validClass) {
254
+ if (element.type === 'radio') {
255
+ this.findByName(element.name).removeClass(errorClass).addClass(validClass);
256
+ } else {
257
+ $(element).removeClass(errorClass).addClass(validClass);
258
+ }
259
+ }
260
+ },
261
+
262
+ // http://docs.jquery.com/Plugins/Validation/Validator/setDefaults
263
+ setDefaults: function(settings) {
264
+ $.extend( $.validator.defaults, settings );
265
+ },
266
+
267
+ messages: {
268
+ required: "This field is required.",
269
+ remote: "Please fix this field.",
270
+ email: "Please enter a valid email address.",
271
+ url: "Please enter a valid URL.",
272
+ date: "Please enter a valid date.",
273
+ dateISO: "Please enter a valid date (ISO).",
274
+ number: "Please enter a valid number.",
275
+ digits: "Please enter only digits.",
276
+ creditcard: "Please enter a valid credit card number.",
277
+ equalTo: "Please enter the same value again.",
278
+ accept: "Please enter a value with a valid extension.",
279
+ maxlength: $.validator.format("Please enter no more than {0} characters."),
280
+ minlength: $.validator.format("Please enter at least {0} characters."),
281
+ rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."),
282
+ range: $.validator.format("Please enter a value between {0} and {1}."),
283
+ max: $.validator.format("Please enter a value less than or equal to {0}."),
284
+ min: $.validator.format("Please enter a value greater than or equal to {0}.")
285
+ },
286
+
287
+ autoCreateRanges: false,
288
+
289
+ prototype: {
290
+
291
+ init: function() {
292
+ this.labelContainer = $(this.settings.errorLabelContainer);
293
+ this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm);
294
+ this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer );
295
+ this.submitted = {};
296
+ this.valueCache = {};
297
+ this.pendingRequest = 0;
298
+ this.pending = {};
299
+ this.invalid = {};
300
+ this.reset();
301
+
302
+ var groups = (this.groups = {});
303
+ $.each(this.settings.groups, function(key, value) {
304
+ $.each(value.split(/\s/), function(index, name) {
305
+ groups[name] = key;
306
+ });
307
+ });
308
+ var rules = this.settings.rules;
309
+ $.each(rules, function(key, value) {
310
+ rules[key] = $.validator.normalizeRule(value);
311
+ });
312
+
313
+ function delegate(event) {
314
+ var validator = $.data(this[0].form, "validator"),
315
+ eventType = "on" + event.type.replace(/^validate/, "");
316
+ validator.settings[eventType] && validator.settings[eventType].call(validator, this[0], event);
317
+ }
318
+ $(this.currentForm)
319
+ .validateDelegate("[type='text'], [type='password'], [type='file'], select, textarea, " +
320
+ "[type='number'], [type='search'] ,[type='tel'], [type='url'], " +
321
+ "[type='email'], [type='datetime'], [type='date'], [type='month'], " +
322
+ "[type='week'], [type='time'], [type='datetime-local'], " +
323
+ "[type='range'], [type='color'] ",
324
+ "focusin focusout keyup", delegate)
325
+ .validateDelegate("[type='radio'], [type='checkbox'], select, option", "click", delegate);
326
+
327
+ if (this.settings.invalidHandler)
328
+ $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);
329
+ },
330
+
331
+ // http://docs.jquery.com/Plugins/Validation/Validator/form
332
+ form: function() {
333
+ this.checkForm();
334
+ $.extend(this.submitted, this.errorMap);
335
+ this.invalid = $.extend({}, this.errorMap);
336
+ if (!this.valid())
337
+ $(this.currentForm).triggerHandler("invalid-form", [this]);
338
+ this.showErrors();
339
+ return this.valid();
340
+ },
341
+
342
+ checkForm: function() {
343
+ this.prepareForm();
344
+ for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) {
345
+ this.check( elements[i] );
346
+ }
347
+ return this.valid();
348
+ },
349
+
350
+ // http://docs.jquery.com/Plugins/Validation/Validator/element
351
+ element: function( element ) {
352
+ element = this.validationTargetFor( this.clean( element ) );
353
+ this.lastElement = element;
354
+ this.prepareElement( element );
355
+ this.currentElements = $(element);
356
+ var result = this.check( element );
357
+ if ( result ) {
358
+ delete this.invalid[element.name];
359
+ } else {
360
+ this.invalid[element.name] = true;
361
+ }
362
+ if ( !this.numberOfInvalids() ) {
363
+ // Hide error containers on last error
364
+ this.toHide = this.toHide.add( this.containers );
365
+ }
366
+ this.showErrors();
367
+ return result;
368
+ },
369
+
370
+ // http://docs.jquery.com/Plugins/Validation/Validator/showErrors
371
+ showErrors: function(errors) {
372
+ if(errors) {
373
+ // add items to error list and map
374
+ $.extend( this.errorMap, errors );
375
+ this.errorList = [];
376
+ for ( var name in errors ) {
377
+ this.errorList.push({
378
+ message: errors[name],
379
+ element: this.findByName(name)[0]
380
+ });
381
+ }
382
+ // remove items from success list
383
+ this.successList = $.grep( this.successList, function(element) {
384
+ return !(element.name in errors);
385
+ });
386
+ }
387
+ this.settings.showErrors
388
+ ? this.settings.showErrors.call( this, this.errorMap, this.errorList )
389
+ : this.defaultShowErrors();
390
+ },
391
+
392
+ // http://docs.jquery.com/Plugins/Validation/Validator/resetForm
393
+ resetForm: function() {
394
+ if ( $.fn.resetForm )
395
+ $( this.currentForm ).resetForm();
396
+ this.submitted = {};
397
+ this.lastElement = null;
398
+ this.prepareForm();
399
+ this.hideErrors();
400
+ this.elements().removeClass( this.settings.errorClass );
401
+ },
402
+
403
+ numberOfInvalids: function() {
404
+ return this.objectLength(this.invalid);
405
+ },
406
+
407
+ objectLength: function( obj ) {
408
+ var count = 0;
409
+ for ( var i in obj )
410
+ count++;
411
+ return count;
412
+ },
413
+
414
+ hideErrors: function() {
415
+ this.addWrapper( this.toHide ).hide();
416
+ },
417
+
418
+ valid: function() {
419
+ return this.size() == 0;
420
+ },
421
+
422
+ size: function() {
423
+ return this.errorList.length;
424
+ },
425
+
426
+ focusInvalid: function() {
427
+ if( this.settings.focusInvalid ) {
428
+ try {
429
+ $(this.findLastActive() || this.errorList.length && this.errorList[0].element || [])
430
+ .filter(":visible")
431
+ .focus()
432
+ // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
433
+ .trigger("focusin");
434
+ } catch(e) {
435
+ // ignore IE throwing errors when focusing hidden elements
436
+ }
437
+ }
438
+ },
439
+
440
+ findLastActive: function() {
441
+ var lastActive = this.lastActive;
442
+ return lastActive && $.grep(this.errorList, function(n) {
443
+ return n.element.name == lastActive.name;
444
+ }).length == 1 && lastActive;
445
+ },
446
+
447
+ elements: function() {
448
+ var validator = this,
449
+ rulesCache = {};
450
+
451
+ // select all valid inputs inside the form (no submit or reset buttons)
452
+ return $(this.currentForm)
453
+ .find("input, select, textarea")
454
+ .not(":submit, :reset, :image, [disabled]")
455
+ .not( this.settings.ignore )
456
+ .filter(function() {
457
+ !this.name && validator.settings.debug && window.console && console.error( "%o has no name assigned", this);
458
+
459
+ // select only the first element for each name, and only those with rules specified
460
+ if ( this.name in rulesCache || !validator.objectLength($(this).rules()) )
461
+ return false;
462
+
463
+ rulesCache[this.name] = true;
464
+ return true;
465
+ });
466
+ },
467
+
468
+ clean: function( selector ) {
469
+ return $( selector )[0];
470
+ },
471
+
472
+ errors: function() {
473
+ return $( this.settings.errorElement + "." + this.settings.errorClass, this.errorContext );
474
+ },
475
+
476
+ reset: function() {
477
+ this.successList = [];
478
+ this.errorList = [];
479
+ this.errorMap = {};
480
+ this.toShow = $([]);
481
+ this.toHide = $([]);
482
+ this.currentElements = $([]);
483
+ },
484
+
485
+ prepareForm: function() {
486
+ this.reset();
487
+ this.toHide = this.errors().add( this.containers );
488
+ },
489
+
490
+ prepareElement: function( element ) {
491
+ this.reset();
492
+ this.toHide = this.errorsFor(element);
493
+ },
494
+
495
+ check: function( element ) {
496
+ element = this.validationTargetFor( this.clean( element ) );
497
+
498
+ var rules = $(element).rules();
499
+ var dependencyMismatch = false;
500
+ for (var method in rules ) {
501
+ var rule = { method: method, parameters: rules[method] };
502
+ try {
503
+ var result = $.validator.methods[method].call( this, element.value.replace(/\r/g, ""), element, rule.parameters );
504
+
505
+ // if a method indicates that the field is optional and therefore valid,
506
+ // don't mark it as valid when there are no other rules
507
+ if ( result == "dependency-mismatch" ) {
508
+ dependencyMismatch = true;
509
+ continue;
510
+ }
511
+ dependencyMismatch = false;
512
+
513
+ if ( result == "pending" ) {
514
+ this.toHide = this.toHide.not( this.errorsFor(element) );
515
+ return;
516
+ }
517
+
518
+ if( !result ) {
519
+ this.formatAndAdd( element, rule );
520
+ return false;
521
+ }
522
+ } catch(e) {
523
+ this.settings.debug && window.console && console.log("exception occured when checking element " + element.id
524
+ + ", check the '" + rule.method + "' method", e);
525
+ throw e;
526
+ }
527
+ }
528
+ if (dependencyMismatch)
529
+ return;
530
+ if ( this.objectLength(rules) )
531
+ this.successList.push(element);
532
+ return true;
533
+ },
534
+
535
+ // return the custom message for the given element and validation method
536
+ // specified in the element's "messages" metadata
537
+ customMetaMessage: function(element, method) {
538
+ if (!$.metadata)
539
+ return;
540
+
541
+ var meta = this.settings.meta
542
+ ? $(element).metadata()[this.settings.meta]
543
+ : $(element).metadata();
544
+
545
+ return meta && meta.messages && meta.messages[method];
546
+ },
547
+
548
+ // return the custom message for the given element name and validation method
549
+ customMessage: function( name, method ) {
550
+ var m = this.settings.messages[name];
551
+ return m && (m.constructor == String
552
+ ? m
553
+ : m[method]);
554
+ },
555
+
556
+ // return the first defined argument, allowing empty strings
557
+ findDefined: function() {
558
+ for(var i = 0; i < arguments.length; i++) {
559
+ if (arguments[i] !== undefined)
560
+ return arguments[i];
561
+ }
562
+ return undefined;
563
+ },
564
+
565
+ defaultMessage: function( element, method) {
566
+ return this.findDefined(
567
+ this.customMessage( element.name, method ),
568
+ this.customMetaMessage( element, method ),
569
+ // title is never undefined, so handle empty string as undefined
570
+ !this.settings.ignoreTitle && element.title || undefined,
571
+ $.validator.messages[method],
572
+ "<strong>Warning: No message defined for " + element.name + "</strong>"
573
+ );
574
+ },
575
+
576
+ formatAndAdd: function( element, rule ) {
577
+ var message = this.defaultMessage( element, rule.method ),
578
+ theregex = /\$?\{(\d+)\}/g;
579
+ if ( typeof message == "function" ) {
580
+ message = message.call(this, rule.parameters, element);
581
+ } else if (theregex.test(message)) {
582
+ message = jQuery.format(message.replace(theregex, '{$1}'), rule.parameters);
583
+ }
584
+ this.errorList.push({
585
+ message: message,
586
+ element: element
587
+ });
588
+
589
+ this.errorMap[element.name] = message;
590
+ this.submitted[element.name] = message;
591
+ },
592
+
593
+ addWrapper: function(toToggle) {
594
+ if ( this.settings.wrapper )
595
+ toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
596
+ return toToggle;
597
+ },
598
+
599
+ defaultShowErrors: function() {
600
+ for ( var i = 0; this.errorList[i]; i++ ) {
601
+ var error = this.errorList[i];
602
+ this.settings.highlight && this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
603
+ this.showLabel( error.element, error.message );
604
+ }
605
+ if( this.errorList.length ) {
606
+ this.toShow = this.toShow.add( this.containers );
607
+ }
608
+ if (this.settings.success) {
609
+ for ( var i = 0; this.successList[i]; i++ ) {
610
+ this.showLabel( this.successList[i] );
611
+ }
612
+ }
613
+ if (this.settings.unhighlight) {
614
+ for ( var i = 0, elements = this.validElements(); elements[i]; i++ ) {
615
+ this.settings.unhighlight.call( this, elements[i], this.settings.errorClass, this.settings.validClass );
616
+ }
617
+ }
618
+ this.toHide = this.toHide.not( this.toShow );
619
+ this.hideErrors();
620
+ this.addWrapper( this.toShow ).show();
621
+ },
622
+
623
+ validElements: function() {
624
+ return this.currentElements.not(this.invalidElements());
625
+ },
626
+
627
+ invalidElements: function() {
628
+ return $(this.errorList).map(function() {
629
+ return this.element;
630
+ });
631
+ },
632
+
633
+ showLabel: function(element, message) {
634
+ var label = this.errorsFor( element );
635
+ if ( label.length ) {
636
+ // refresh error/success class
637
+ label.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );
638
+
639
+ // check if we have a generated label, replace the message then
640
+ label.attr("generated") && label.html(message);
641
+ } else {
642
+ // create label
643
+ label = $("<" + this.settings.errorElement + "/>")
644
+ .attr({"for": this.idOrName(element), generated: true})
645
+ .addClass(this.settings.errorClass)
646
+ .html(message || "");
647
+ if ( this.settings.wrapper ) {
648
+ // make sure the element is visible, even in IE
649
+ // actually showing the wrapped element is handled elsewhere
650
+ label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
651
+ }
652
+ if ( !this.labelContainer.append(label).length )
653
+ this.settings.errorPlacement
654
+ ? this.settings.errorPlacement(label, $(element) )
655
+ : label.insertAfter(element);
656
+ }
657
+ if ( !message && this.settings.success ) {
658
+ label.text("");
659
+ typeof this.settings.success == "string"
660
+ ? label.addClass( this.settings.success )
661
+ : this.settings.success( label );
662
+ }
663
+ this.toShow = this.toShow.add(label);
664
+ },
665
+
666
+ errorsFor: function(element) {
667
+ var name = this.idOrName(element);
668
+ return this.errors().filter(function() {
669
+ return $(this).attr('for') == name;
670
+ });
671
+ },
672
+
673
+ idOrName: function(element) {
674
+ return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name);
675
+ },
676
+
677
+ validationTargetFor: function(element) {
678
+ // if radio/checkbox, validate first element in group instead
679
+ if (this.checkable(element)) {
680
+ element = this.findByName( element.name ).not(this.settings.ignore)[0];
681
+ }
682
+ return element;
683
+ },
684
+
685
+ checkable: function( element ) {
686
+ return /radio|checkbox/i.test(element.type);
687
+ },
688
+
689
+ findByName: function( name ) {
690
+ // select by name and filter by form for performance over form.find("[name=...]")
691
+ var form = this.currentForm;
692
+ return $(document.getElementsByName(name)).map(function(index, element) {
693
+ return element.form == form && element.name == name && element || null;
694
+ });
695
+ },
696
+
697
+ getLength: function(value, element) {
698
+ switch( element.nodeName.toLowerCase() ) {
699
+ case 'select':
700
+ return $("option:selected", element).length;
701
+ case 'input':
702
+ if( this.checkable( element) )
703
+ return this.findByName(element.name).filter(':checked').length;
704
+ }
705
+ return value.length;
706
+ },
707
+
708
+ depend: function(param, element) {
709
+ return this.dependTypes[typeof param]
710
+ ? this.dependTypes[typeof param](param, element)
711
+ : true;
712
+ },
713
+
714
+ dependTypes: {
715
+ "boolean": function(param, element) {
716
+ return param;
717
+ },
718
+ "string": function(param, element) {
719
+ return !!$(param, element.form).length;
720
+ },
721
+ "function": function(param, element) {
722
+ return param(element);
723
+ }
724
+ },
725
+
726
+ optional: function(element) {
727
+ return !$.validator.methods.required.call(this, $.trim(element.value), element) && "dependency-mismatch";
728
+ },
729
+
730
+ startRequest: function(element) {
731
+ if (!this.pending[element.name]) {
732
+ this.pendingRequest++;
733
+ this.pending[element.name] = true;
734
+ }
735
+ },
736
+
737
+ stopRequest: function(element, valid) {
738
+ this.pendingRequest--;
739
+ // sometimes synchronization fails, make sure pendingRequest is never < 0
740
+ if (this.pendingRequest < 0)
741
+ this.pendingRequest = 0;
742
+ delete this.pending[element.name];
743
+ if ( valid && this.pendingRequest == 0 && this.formSubmitted && this.form() ) {
744
+ $(this.currentForm).submit();
745
+ this.formSubmitted = false;
746
+ } else if (!valid && this.pendingRequest == 0 && this.formSubmitted) {
747
+ $(this.currentForm).triggerHandler("invalid-form", [this]);
748
+ this.formSubmitted = false;
749
+ }
750
+ },
751
+
752
+ previousValue: function(element) {
753
+ return $.data(element, "previousValue") || $.data(element, "previousValue", {
754
+ old: null,
755
+ valid: true,
756
+ message: this.defaultMessage( element, "remote" )
757
+ });
758
+ }
759
+
760
+ },
761
+
762
+ classRuleSettings: {
763
+ required: {required: true},
764
+ email: {email: true},
765
+ url: {url: true},
766
+ date: {date: true},
767
+ dateISO: {dateISO: true},
768
+ dateDE: {dateDE: true},
769
+ number: {number: true},
770
+ numberDE: {numberDE: true},
771
+ digits: {digits: true},
772
+ creditcard: {creditcard: true}
773
+ },
774
+
775
+ addClassRules: function(className, rules) {
776
+ className.constructor == String ?
777
+ this.classRuleSettings[className] = rules :
778
+ $.extend(this.classRuleSettings, className);
779
+ },
780
+
781
+ classRules: function(element) {
782
+ var rules = {};
783
+ var classes = $(element).attr('class');
784
+ classes && $.each(classes.split(' '), function() {
785
+ if (this in $.validator.classRuleSettings) {
786
+ $.extend(rules, $.validator.classRuleSettings[this]);
787
+ }
788
+ });
789
+ return rules;
790
+ },
791
+
792
+ attributeRules: function(element) {
793
+ var rules = {};
794
+ var $element = $(element);
795
+
796
+ for (var method in $.validator.methods) {
797
+ var value;
798
+ // If .prop exists (jQuery >= 1.6), use it to get true/false for required
799
+ if (method === 'required' && typeof $.fn.prop === 'function') {
800
+ value = $element.prop(method);
801
+ } else {
802
+ value = $element.attr(method);
803
+ }
804
+ if (value) {
805
+ rules[method] = value;
806
+ } else if ($element[0].getAttribute("type") === method) {
807
+ rules[method] = true;
808
+ }
809
+ }
810
+
811
+ // maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs
812
+ if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) {
813
+ delete rules.maxlength;
814
+ }
815
+
816
+ return rules;
817
+ },
818
+
819
+ metadataRules: function(element) {
820
+ if (!$.metadata) return {};
821
+
822
+ var meta = $.data(element.form, 'validator').settings.meta;
823
+ return meta ?
824
+ $(element).metadata()[meta] :
825
+ $(element).metadata();
826
+ },
827
+
828
+ staticRules: function(element) {
829
+ var rules = {};
830
+ var validator = $.data(element.form, 'validator');
831
+ if (validator.settings.rules) {
832
+ rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {};
833
+ }
834
+ return rules;
835
+ },
836
+
837
+ normalizeRules: function(rules, element) {
838
+ // handle dependency check
839
+ $.each(rules, function(prop, val) {
840
+ // ignore rule when param is explicitly false, eg. required:false
841
+ if (val === false) {
842
+ delete rules[prop];
843
+ return;
844
+ }
845
+ if (val.param || val.depends) {
846
+ var keepRule = true;
847
+ switch (typeof val.depends) {
848
+ case "string":
849
+ keepRule = !!$(val.depends, element.form).length;
850
+ break;
851
+ case "function":
852
+ keepRule = val.depends.call(element, element);
853
+ break;
854
+ }
855
+ if (keepRule) {
856
+ rules[prop] = val.param !== undefined ? val.param : true;
857
+ } else {
858
+ delete rules[prop];
859
+ }
860
+ }
861
+ });
862
+
863
+ // evaluate parameters
864
+ $.each(rules, function(rule, parameter) {
865
+ rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter;
866
+ });
867
+
868
+ // clean number parameters
869
+ $.each(['minlength', 'maxlength', 'min', 'max'], function() {
870
+ if (rules[this]) {
871
+ rules[this] = Number(rules[this]);
872
+ }
873
+ });
874
+ $.each(['rangelength', 'range'], function() {
875
+ if (rules[this]) {
876
+ rules[this] = [Number(rules[this][0]), Number(rules[this][1])];
877
+ }
878
+ });
879
+
880
+ if ($.validator.autoCreateRanges) {
881
+ // auto-create ranges
882
+ if (rules.min && rules.max) {
883
+ rules.range = [rules.min, rules.max];
884
+ delete rules.min;
885
+ delete rules.max;
886
+ }
887
+ if (rules.minlength && rules.maxlength) {
888
+ rules.rangelength = [rules.minlength, rules.maxlength];
889
+ delete rules.minlength;
890
+ delete rules.maxlength;
891
+ }
892
+ }
893
+
894
+ // To support custom messages in metadata ignore rule methods titled "messages"
895
+ if (rules.messages) {
896
+ delete rules.messages;
897
+ }
898
+
899
+ return rules;
900
+ },
901
+
902
+ // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
903
+ normalizeRule: function(data) {
904
+ if( typeof data == "string" ) {
905
+ var transformed = {};
906
+ $.each(data.split(/\s/), function() {
907
+ transformed[this] = true;
908
+ });
909
+ data = transformed;
910
+ }
911
+ return data;
912
+ },
913
+
914
+ // http://docs.jquery.com/Plugins/Validation/Validator/addMethod
915
+ addMethod: function(name, method, message) {
916
+ $.validator.methods[name] = method;
917
+ $.validator.messages[name] = message != undefined ? message : $.validator.messages[name];
918
+ if (method.length < 3) {
919
+ $.validator.addClassRules(name, $.validator.normalizeRule(name));
920
+ }
921
+ },
922
+
923
+ methods: {
924
+
925
+ // http://docs.jquery.com/Plugins/Validation/Methods/required
926
+ required: function(value, element, param) {
927
+ // check if dependency is met
928
+ if ( !this.depend(param, element) )
929
+ return "dependency-mismatch";
930
+ switch( element.nodeName.toLowerCase() ) {
931
+ case 'select':
932
+ // could be an array for select-multiple or a string, both are fine this way
933
+ var val = $(element).val();
934
+ return val && val.length > 0;
935
+ case 'input':
936
+ if ( this.checkable(element) )
937
+ return this.getLength(value, element) > 0;
938
+ default:
939
+ return $.trim(value).length > 0;
940
+ }
941
+ },
942
+
943
+ // http://docs.jquery.com/Plugins/Validation/Methods/remote
944
+ remote: function(value, element, param) {
945
+ if ( this.optional(element) )
946
+ return "dependency-mismatch";
947
+
948
+ var previous = this.previousValue(element);
949
+ if (!this.settings.messages[element.name] )
950
+ this.settings.messages[element.name] = {};
951
+ previous.originalMessage = this.settings.messages[element.name].remote;
952
+ this.settings.messages[element.name].remote = previous.message;
953
+
954
+ param = typeof param == "string" && {url:param} || param;
955
+
956
+ if ( this.pending[element.name] ) {
957
+ return "pending";
958
+ }
959
+ if ( previous.old === value ) {
960
+ return previous.valid;
961
+ }
962
+
963
+ previous.old = value;
964
+ var validator = this;
965
+ this.startRequest(element);
966
+ var data = {};
967
+ data[element.name] = value;
968
+ $.ajax($.extend(true, {
969
+ url: param,
970
+ mode: "abort",
971
+ port: "validate" + element.name,
972
+ dataType: "json",
973
+ data: data,
974
+ success: function(response) {
975
+ validator.settings.messages[element.name].remote = previous.originalMessage;
976
+ var valid = response === true;
977
+ if ( valid ) {
978
+ var submitted = validator.formSubmitted;
979
+ validator.prepareElement(element);
980
+ validator.formSubmitted = submitted;
981
+ validator.successList.push(element);
982
+ validator.showErrors();
983
+ } else {
984
+ var errors = {};
985
+ var message = response || validator.defaultMessage( element, "remote" );
986
+ errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message;
987
+ validator.showErrors(errors);
988
+ }
989
+ previous.valid = valid;
990
+ validator.stopRequest(element, valid);
991
+ }
992
+ }, param));
993
+ return "pending";
994
+ },
995
+
996
+ // http://docs.jquery.com/Plugins/Validation/Methods/minlength
997
+ minlength: function(value, element, param) {
998
+ return this.optional(element) || this.getLength($.trim(value), element) >= param;
999
+ },
1000
+
1001
+ // http://docs.jquery.com/Plugins/Validation/Methods/maxlength
1002
+ maxlength: function(value, element, param) {
1003
+ return this.optional(element) || this.getLength($.trim(value), element) <= param;
1004
+ },
1005
+
1006
+ // http://docs.jquery.com/Plugins/Validation/Methods/rangelength
1007
+ rangelength: function(value, element, param) {
1008
+ var length = this.getLength($.trim(value), element);
1009
+ return this.optional(element) || ( length >= param[0] && length <= param[1] );
1010
+ },
1011
+
1012
+ // http://docs.jquery.com/Plugins/Validation/Methods/min
1013
+ min: function( value, element, param ) {
1014
+ return this.optional(element) || value >= param;
1015
+ },
1016
+
1017
+ // http://docs.jquery.com/Plugins/Validation/Methods/max
1018
+ max: function( value, element, param ) {
1019
+ return this.optional(element) || value <= param;
1020
+ },
1021
+
1022
+ // http://docs.jquery.com/Plugins/Validation/Methods/range
1023
+ range: function( value, element, param ) {
1024
+ return this.optional(element) || ( value >= param[0] && value <= param[1] );
1025
+ },
1026
+
1027
+ // http://docs.jquery.com/Plugins/Validation/Methods/email
1028
+ email: function(value, element) {
1029
+ // contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
1030
+ return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value);
1031
+ },
1032
+
1033
+ // http://docs.jquery.com/Plugins/Validation/Methods/url
1034
+ url: function(value, element) {
1035
+ // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
1036
+ return this.optional(element) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
1037
+ },
1038
+
1039
+ // http://docs.jquery.com/Plugins/Validation/Methods/date
1040
+ date: function(value, element) {
1041
+ return this.optional(element) || !/Invalid|NaN/.test(new Date(value));
1042
+ },
1043
+
1044
+ // http://docs.jquery.com/Plugins/Validation/Methods/dateISO
1045
+ dateISO: function(value, element) {
1046
+ return this.optional(element) || /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value);
1047
+ },
1048
+
1049
+ // http://docs.jquery.com/Plugins/Validation/Methods/number
1050
+ number: function(value, element) {
1051
+ return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value);
1052
+ },
1053
+
1054
+ // http://docs.jquery.com/Plugins/Validation/Methods/digits
1055
+ digits: function(value, element) {
1056
+ return this.optional(element) || /^\d+$/.test(value);
1057
+ },
1058
+
1059
+ // http://docs.jquery.com/Plugins/Validation/Methods/creditcard
1060
+ // based on http://en.wikipedia.org/wiki/Luhn
1061
+ creditcard: function(value, element) {
1062
+ if ( this.optional(element) )
1063
+ return "dependency-mismatch";
1064
+ // accept only spaces, digits and dashes
1065
+ if (/[^0-9 -]+/.test(value))
1066
+ return false;
1067
+ var nCheck = 0,
1068
+ nDigit = 0,
1069
+ bEven = false;
1070
+
1071
+ value = value.replace(/\D/g, "");
1072
+
1073
+ for (var n = value.length - 1; n >= 0; n--) {
1074
+ var cDigit = value.charAt(n);
1075
+ var nDigit = parseInt(cDigit, 10);
1076
+ if (bEven) {
1077
+ if ((nDigit *= 2) > 9)
1078
+ nDigit -= 9;
1079
+ }
1080
+ nCheck += nDigit;
1081
+ bEven = !bEven;
1082
+ }
1083
+
1084
+ return (nCheck % 10) == 0;
1085
+ },
1086
+
1087
+ // http://docs.jquery.com/Plugins/Validation/Methods/accept
1088
+ accept: function(value, element, param) {
1089
+ param = typeof param == "string" ? param.replace(/,/g, '|') : "png|jpe?g|gif";
1090
+ return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i"));
1091
+ },
1092
+
1093
+ // http://docs.jquery.com/Plugins/Validation/Methods/equalTo
1094
+ equalTo: function(value, element, param) {
1095
+ // bind to the blur event of the target in order to revalidate whenever the target field is updated
1096
+ // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead
1097
+ var target = $(param).unbind(".validate-equalTo").bind("blur.validate-equalTo", function() {
1098
+ $(element).valid();
1099
+ });
1100
+ return value == target.val();
1101
+ }
1102
+
1103
+ }
1104
+
1105
+ });
1106
+
1107
+ // deprecated, use $.validator.format instead
1108
+ $.format = $.validator.format;
1109
+
1110
+ })(jQuery);
1111
+
1112
+ // ajax mode: abort
1113
+ // usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
1114
+ // if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
1115
+ ;(function($) {
1116
+ var pendingRequests = {};
1117
+ // Use a prefilter if available (1.5+)
1118
+ if ( $.ajaxPrefilter ) {
1119
+ $.ajaxPrefilter(function(settings, _, xhr) {
1120
+ var port = settings.port;
1121
+ if (settings.mode == "abort") {
1122
+ if ( pendingRequests[port] ) {
1123
+ pendingRequests[port].abort();
1124
+ }
1125
+ pendingRequests[port] = xhr;
1126
+ }
1127
+ });
1128
+ } else {
1129
+ // Proxy ajax
1130
+ var ajax = $.ajax;
1131
+ $.ajax = function(settings) {
1132
+ var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
1133
+ port = ( "port" in settings ? settings : $.ajaxSettings ).port;
1134
+ if (mode == "abort") {
1135
+ if ( pendingRequests[port] ) {
1136
+ pendingRequests[port].abort();
1137
+ }
1138
+ return (pendingRequests[port] = ajax.apply(this, arguments));
1139
+ }
1140
+ return ajax.apply(this, arguments);
1141
+ };
1142
+ }
1143
+ })(jQuery);
1144
+
1145
+ // provides cross-browser focusin and focusout events
1146
+ // IE has native support, in other browsers, use event caputuring (neither bubbles)
1147
+
1148
+ // provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
1149
+ // handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target
1150
+ ;(function($) {
1151
+ // only implement if not provided by jQuery core (since 1.4)
1152
+ // TODO verify if jQuery 1.4's implementation is compatible with older jQuery special-event APIs
1153
+ if (!jQuery.event.special.focusin && !jQuery.event.special.focusout && document.addEventListener) {
1154
+ $.each({
1155
+ focus: 'focusin',
1156
+ blur: 'focusout'
1157
+ }, function( original, fix ){
1158
+ $.event.special[fix] = {
1159
+ setup:function() {
1160
+ this.addEventListener( original, handler, true );
1161
+ },
1162
+ teardown:function() {
1163
+ this.removeEventListener( original, handler, true );
1164
+ },
1165
+ handler: function(e) {
1166
+ arguments[0] = $.event.fix(e);
1167
+ arguments[0].type = fix;
1168
+ return $.event.handle.apply(this, arguments);
1169
+ }
1170
+ };
1171
+ function handler(e) {
1172
+ e = $.event.fix(e);
1173
+ e.type = fix;
1174
+ return $.event.handle.call(this, e);
1175
+ }
1176
+ });
1177
+ };
1178
+ $.extend($.fn, {
1179
+ validateDelegate: function(delegate, type, handler) {
1180
+ return this.bind(type, function(event) {
1181
+ var target = $(event.target);
1182
+ if (target.is(delegate)) {
1183
+ return handler.apply(target, arguments);
1184
+ }
1185
+ });
1186
+ }
1187
+ });
1188
+ })(jQuery);
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: Hiroaki Miyashita
3
  Donate link: http://wpgogo.com/development/custom-field-template.html
4
  Tags: custom, fields, field, template, meta, custom field, custom fields, custom field template
5
  Requires at least: 2.1
6
- Tested up to: 3.2.1
7
- Stable tag: 1.9.4
8
 
9
  This plugin adds the default custom fields on the Write Post/Page.
10
 
@@ -105,6 +105,11 @@ See the default template and modify it.
105
 
106
  == Changelog ==
107
 
 
 
 
 
 
108
  = 1.9.4 =
109
  * Support of taxonomies in the category ID field.
110
 
3
  Donate link: http://wpgogo.com/development/custom-field-template.html
4
  Tags: custom, fields, field, template, meta, custom field, custom fields, custom field template
5
  Requires at least: 2.1
6
+ Tested up to: 3.3
7
+ Stable tag: 1.9.5
8
 
9
  This plugin adds the default custom fields on the Write Post/Page.
10
 
105
 
106
  == Changelog ==
107
 
108
+ = 1.9.5 =
109
+ * tinyMCE and quicktags in WordPress 3.3.
110
+ * Upgrade of jQuery Validation Plugin.
111
+ * Bugfix: multiple and fieldset options (Thanks, Colin Duwe).
112
+
113
  = 1.9.4 =
114
  * Support of taxonomies in the category ID field.
115