Zapatec.Form.Field.prototype.ajaxValidate = function(){
	// processing zpFormValidate feature
	if(!this.hasFeature("zpFormValidate")){
		return null;
	}

	var valid = this.validate();

	if(!(
			valid == null || // if field has no client-side errors
			valid != null &&
			(
				valid.length == 0 ||
				valid.length == 1 && // or has only one error, but it is error from this validator
				valid[0].validator == "zpFormValidate"
			)
		)
	){
		return null;
	}

	var submitUrl = this.getFeature("zpFormValidate");
	var submitMethod = this.getFeature("zpFormValidateMethod");
	var submitParam = this.getFeature("zpFormValidateParam");
	var submitQuery = this.getFeature("zpFormValidateQuery");

	// method by default is GET
	if(typeof(submitMethod) != 'string'){
		submitMethod = "GET"
	}

	// URL param name by default is equal to the field name
	if(typeof(submitParam) != 'string'){
		submitParam = this.field.name;
	}

	if(typeof(submitQuery) != 'string'){
		submitQuery = "";
	}

	submitQuery += "&" + encodeURIComponent(submitParam) + "=" + encodeURIComponent(this.getValue());

	if(submitUrl.indexOf("?") < 0){
		submitUrl += "?";
	}

	submitUrl += "&" + Math.random();

	if(submitMethod == 'GET'){
		submitUrl += "&" + submitQuery;
	}

	this.fetchingMark.className = "zpIsFetching " + Zapatec.Form.IGNORE_CLASSNAME;

	var self = this;

	if(this.config.formConfig.ajaxDebugFunc){
		this.config.formConfig.ajaxDebugFunc(this.getMessage('ajaxDebugSeparator'));
		this.config.formConfig.ajaxDebugFunc(this.getMessage('ajaxDebugValidateTitle', this.field.name));
		this.config.formConfig.ajaxDebugFunc(submitMethod + " " + submitUrl);
		this.config.formConfig.ajaxDebugFunc(this.getMessage('ajaxDebugQuery', ("GET" ? "" : submitQuery)));
	}

	Zapatec.Transport.fetch({
		url: submitUrl,
		content: submitMethod == "GET" ? null : submitQuery,
		method: submitMethod,
		onLoad: function(objText){
			if(self.config.formConfig.ajaxDebugFunc){
				self.config.formConfig.ajaxDebugFunc(self.getMessage('ajaxDebugResponse', objText.responseText));
			}

			self.fetchingMark.className = Zapatec.Form.IGNORE_CLASSNAME + "zpNotFetching";

			if (objText.responseText == null) {
				Zapatec.Log({description: self.getMessage('ajaxValidateNoResponseError', objText.responseText)});
				return null;
			}

			var objResponse = Zapatec.Transport.parseJson({strJson: objText.responseText});

			if(objResponse == null){
				Zapatec.Log({description: self.getMessage('ajaxValidateCantParseError', objText.responseText)});
				return null;
			}

			if(!objResponse.success){
				self.ajaxError = typeof(objResponse.generalError) != 'string' ||
					objResponse.generalError.length == 0 ?
						self.getMessage('ajaxValidateValidationError') : 
						objResponse.generalError;
			} else {
				self.ajaxError = null;
			}
			if(typeof(objResponse.callBack) != "undefined") {
				if(objResponse.callBack.length != 0){
					eval(objResponse.callBack);
				}
			}			
			self.validate();
		},
		onError : function(objError){
			var strError = '';

			if (objError.errorCode) {
				strError += objError.errorCode + ' ';
			}

			strError += objError.errorDescription;

			self.fetchingMark.className = Zapatec.Form.IGNORE_CLASSNAME + " zpNotFetching";
			alert(strError);
			self.ajaxError = null;

			if(self.config.formConfig.ajaxDebugFunc){
				self.config.formConfig.ajaxDebugFunc(self.getMessage('ajaxDebugResponseError', strError));
			}
		}
	});
};
