function FormAjax(formName) {
	this.form = document.forms[formName];
	
	var _handler = this;
	
	this.form.onsubmit = function () {
		if (_handler.onBeforeSubmit != null && _handler.onBeforeSubmit() == false) {
			return false;
		}
		
		return _handler.onSubmit();
	}
	
	this.onSubmit = function () {
		var data = new Object();
		
		for (var i = 0; i < this.form.elements.length; i++) {
			var element = this.form.elements[i];
			
			if (element.name.length == 0) {
				continue;
			}
			
			switch (element.type) {
				default :
					data[element.name] = element.value;
					break;
			}
		}
		
		var doc = null;
		
		if (document.implementation && document.implementation.createDocument) {
			doc = document.implementation.createDocument("", "", null);
		} else if (window.ActiveXObject) {
			doc = new ActiveXObject("Microsoft.XMLDOM");
		}
		
		doc.appendChild(doc.createElement('request'));
		doc.documentElement.setAttribute('type', 'json');
		doc.documentElement.appendChild(doc.createCDATASection(JSON.stringify(data)))
		
		var request = new Request();
		
		request.callbackXml = function (document) {
			_handler.onServerResponse(document);
		}
		
		request.execute(doc);
		
		if (this.onLoading != null) {
			this.onLoading();
		}
		
		return false;
	}
	
	this.onServerResponse = function (document) {
		var json = "var data = " + document.documentElement.firstChild.nodeValue + ";";
		eval(json);
		
		if (data.errors.common.length == 0 && data.errors.fields.length == 0) {
			if (this.onOk != null) {
				this.onOk();
			}
		} else {
			if (this.onError != null) {
				this.onError(data.errors);
			}
		}
	}
	
	this.onBeforeSubmit;
	this.onLoading;
	this.onOk;
	this.onError;
}