function validator_ajax(elem, url){
	var validator = $('<span class="validator">&nbsp;</span>');
	elem.after(validator);
	elem.data('validator', validator);

	// Connect the validator
	elem.change(function(){
		var elem=$(this);
		elem.data('validator').attr('class', 'validator');
		val=elem.val();
		if (val==''){
			return;
		}
		validator.addClass('waiting');
		$.ajax({
			url: url,
			dataType: 'json',
			data: {
				value: val
			},
			type: 'POST',
			context: elem,
			success: function(data) {
				$(this).data('validator').attr('class', 'validator').addClass((data.valid?'valid':'invalid'));
			}
		});
	});

	function timefunc(elem){
		return (function(){
			elem.change();
		})
	}

	elem.keyup(function(){
		var elem  = $(this);
		var timer = elem.data('timer');
		if (timer){
			clearTimeout(timer);
		};
		elem.data('validator').attr('class', 'validator');
		elem.data('timer', setTimeout(timefunc(elem), 1500));
	});
}

function validator_equal(elem1, elem2){
	elem1.data('sync_elem', elem2);
	elem2.data('sync_elem', elem1);

	var validator = $('<span class="validator">&nbsp;</span>');
	elem1.after(validator);
	elem1.data('validator', validator);
	elem2.data('validator', validator);

	function check_equal(){
		var elem1 = $(this);
		var elem2 = elem1.data('sync_elem');
		var	validator=elem1.data('validator');
		validator.attr('class', 'validator');
		if (elem1.val() || elem2.val()){
			validator.addClass(((elem1.val()==elem2.val())?'valid':'invalid'));
		}
	};
	elem1.keyup(check_equal);
	elem2.keyup(check_equal);
};

