<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>vendors/img/ajax-loader.gif</filename>
    </added>
    <added>
      <filename>views/js_validate/field.ctp</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,18 +1,43 @@
 &lt;?php
 class JsValidateController extends JsValidateAppController {
 	var $name = 'JsValidate';
-  var $helpers = array('JsValidate.Validation');
-  
+  var $helpers = array('Javascript', 'JsValidate.Validation');
+  var $components = array('RequestHandler');
+	
   function beforeFilter() {
-    if (Configure::read('debug') &lt; 1) {
-      die(__('Debug setting does not allow access to this url.', true));
-    }
+
   }
+	
+	function field($fieldId) {
+		Configure::write('debug', 0);
+		
+		$modelName = array_shift(array_keys($this-&gt;data));
+		$Model = ClassRegistry::init($modelName);
+		$Model-&gt;data = $this-&gt;data;
+		
+		$fieldName = array_shift(array_keys(array_shift($this-&gt;data)));
+		
+		$output = array('field' =&gt; $fieldId);
+		$output['result'] = $Model-&gt;validates(array('fieldList' =&gt; array($fieldName)));
+
+		$errors = $Model-&gt;validationErrors;
+		if($errors) {
+			$output['message'] = array_pop($errors);
+		}
+		
+		$this-&gt;set('output', $output);
+	}
   
 	function test() {
+		if (Configure::read('debug') &lt; 1) {
+      die(__('Debug setting does not allow access to this url.', true));
+    }
 	}
 
 	function test_min() {
+		if (Configure::read('debug') &lt; 1) {
+      die(__('Debug setting does not allow access to this url.', true));
+    }
 	}
 }
 </diff>
      <filename>controllers/js_validate_controller.php</filename>
    </modified>
    <modified>
      <diff>@@ -14,7 +14,13 @@
   var options = null;
   $.fn.validate = function(rules, opts) {
     options = $.extend({}, $.fn.validate.defaults, opts);
-    
+		
+		$.each(opts.watch, function(fieldId) {
+			$(&quot;#&quot; + opts.watch[fieldId]).change(function() {
+				$.fn.validate.ajaxField($(this));
+			});
+		});
+
     return this.each(function() {
       $this = $(this);
       $this.submit(function() {
@@ -153,21 +159,54 @@
     
     return true;
   };
+	
+	$.fn.validate.ajaxField = function($field) {
+		$.fn.validate.clearError($field);
+		$.fn.validate.ajaxBeforeFilter($field);
+
+		var data = new Object;
+		data[$field.attr(&quot;name&quot;)] = $field.val();
+		$.post(options.root + &quot;js_validate/field/&quot; + $field.attr(&quot;id&quot;), data,
+			function(validates) {
+				$.fn.validate.ajaxAfterFilter($(&quot;#&quot; + validates.field));
+				if(!validates.result) {
+					$.fn.validate.setError(validates.field, validates.message);
+				}
+			},
+			&quot;json&quot;);
+	}
+	
+	$.fn.validate.ajaxBeforeFilter = function($field) {
+		$field.after(&quot;&lt;img class=\&quot;ajax-loader\&quot; src=\&quot;&quot; + options.root + &quot;js_validate/img/ajax-loader.gif\&quot;&gt;&quot;);
+	}
+
+	$.fn.validate.ajaxAfterFilter = function($field) {
+		$field.siblings(&quot;.ajax-loader&quot;).remove();
+	}
+	
+	$.fn.validate.clearError = function($field) {
+		if(typeof $field == &quot;string&quot;) {
+			$field = $(&quot;#&quot; + field);
+		}
+		
+		$field.removeClass(&quot;form-error&quot;)
+					.parents(&quot;div:first&quot;).removeClass(&quot;error&quot;)
+					.children(&quot;.error-message&quot;).remove();		
+	}
   
   $.fn.validate.setError = function(field, message) {
-    //add the form-error class to the input
     $(&quot;#&quot; + field).addClass(&quot;form-error&quot;)
                   .parents(&quot;div:first&quot;).addClass(&quot;error&quot;)
                   .append('&lt;div class=&quot;error-message&quot;&gt;'  + message +  '&lt;/div&gt;');
   };
-  
+	
   $.fn.validate.beforeFilter = function() {
     if(options.messageId != null) {
       $(&quot;#&quot; + options.messageId).html(&quot;&quot;)
                                 .slideDown();
     }
     
-    $(&quot;.error-message&quot;).hide();
+    $(&quot;.error-message&quot;).remove();
     $(&quot;input&quot;).removeClass(&quot;form-error&quot;);
     $(&quot;div&quot;).removeClass(&quot;error&quot;)
   };  </diff>
      <filename>vendors/js/jquery.validation.js</filename>
    </modified>
    <modified>
      <diff>@@ -29,9 +29,9 @@ class ValidationHelper extends Helper {
   var $whitelist = false;
 
   function bind($modelNames, $options=array()) {
-    $defaultOptions = array('form' =&gt; 'form', 'inline' =&gt; true, 'messageId' =&gt; null);
+    $defaultOptions = array('form' =&gt; 'form', 'inline' =&gt; true, 'messageId' =&gt; null, 'root' =&gt; Router::url('/'), 'watch' =&gt; array());
     $options = am($defaultOptions, $options);
-    $pluginOptions = array_intersect_key($options, array('messageId' =&gt; true));
+    $pluginOptions = array_intersect_key($options, array('messageId' =&gt; true, 'root' =&gt; true, 'watch' =&gt; true));
 
     //load the whitelist
     $this-&gt;whitelist = Configure::read('javascriptValidationWhitelist');
@@ -96,9 +96,15 @@ class ValidationHelper extends Helper {
           }
         }
       }
+			
+			if(!empty($pluginOptions['watch'])) {
+				$pluginOptions['watch'] = $this-&gt;__fixWatch($modelName, $pluginOptions['watch']);
+			}			
     }
+		
 
-    if ($options['form']) {
+		
+		if ($options['form']) {
       $js = sprintf('$(function() { $(&quot;%s&quot;).validate(%s, %s) });',
                     $options['form'],
                     $this-&gt;Javascript-&gt;object($validation),
@@ -240,5 +246,18 @@ class ValidationHelper extends Helper {
 
     return array('rule' =&gt; $rule, 'params' =&gt; $params);
   }
+
+	function __fixWatch($modelName, $fields) {
+		foreach($fields as $i =&gt; $field) {
+			if (strpos($field, '.') !== false) {
+				list($model, $field) = explode('.', $field);
+				$fields[$i] = ucfirst($model) . ucfirst($field);
+			} else {
+				$fields[$i] = $modelName . ucfirst($field);
+			}
+		}
+		
+		return $fields;
+	}
 }
 ?&gt;
\ No newline at end of file</diff>
      <filename>views/helpers/validation.php</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>732b8adae5e728a43568580393fb39cd8557a0f9</id>
    </parent>
  </parents>
  <author>
    <name>Matt Curry</name>
    <email>matt@pseudocoder.com</email>
  </author>
  <url>http://github.com/mcurry/js_validate/commit/af33da75a8a631176831929b95dfcd9b38a207c4</url>
  <id>af33da75a8a631176831929b95dfcd9b38a207c4</id>
  <committed-date>2009-07-07T20:32:01-07:00</committed-date>
  <authored-date>2009-07-07T20:32:01-07:00</authored-date>
  <message>built in ajax validation</message>
  <tree>1abb98002d8f98d01acc67caf4b414cceda407c2</tree>
  <committer>
    <name>Matt Curry</name>
    <email>matt@pseudocoder.com</email>
  </committer>
</commit>
