My favorites | Sign in
Project Home Downloads Wiki Issues Source
Project Information
Members

ARIESJS

As a developers we think of javascript and html, Ajax and a lot of other stuff. We use differernt frameworks like jQuery, YUI and Dojo to make our life easier. But there still we have no consistency around Javscript application development.

This library allows to think about ojects on higher level in client side development. It allows every javascript object to have its html representation and every html object to have methods to bring dhtml in.

Example

Here is an example - basic LoginForm component. There will be no validation yet and no labels but will be default text which will disappear when user clicks on input field. First we need to declare Class. Let it be LoginForm.

ARIES.Class("LoginForm",{
	/* Scope of following functions will be changed to input node */
	manipulateInput:{
		/* this function will set default value to field */
		setDefault:function(){
			if (this.value === "") {
				this.className="default";
				this.value = this.getAttribute("default");
			}
		},
		/* this function will clear default value to field */
		clearDefault:function(){
			if (this.getAttribute("default") == this.value) {
				this.value = "";
				this.className="";
			}
		},
		/* this function will set default value to password field 
		 * a little bit complicated code here is because IE doesn't
		 * support input.type change.
		 */
		password2text:function(){
			if(this.getAttribute("type")=="password"&&this.value==this.getAttribute("default")){
				if (this.previousSibling.name!='dummyText' + this.name) {
					
					/* create a fake input node with type=text to replace original password field */
					
					var tmpNode = document.createElement("input");
					tmpNode.setAttribute('type', 'text');
					tmpNode.setAttribute('name', 'dummyText' + this.name);
					tmpNode.className=this.className;
					tmpNode.value=this.value;
					this.style.display = "none";
					this.parentNode.insertBefore(tmpNode, this.nextSibling);

					var text2password=function(){
						if (this.previousSibling.type == 'password') {
							this.previousSibling.style.display = "block";
							this.style.display = "none";
							this.previousSibling.value="";
							this.previousSibling.focus();
							this.previousSibling.className="";
						}
					};
					/*
					 * Set event handlers to this fake input
					 */
					tmpNode.onclick=function(){
						text2password.apply(this);
					};
	
					
					tmpNode.onfocus=function(){
						text2password.apply(this);
					};

					
				}else{
					/* if there alredy is fake input, just hide original */
					tmpNode=this.previousSibling;
					tmpNode.value=this.value;
					this.style.display = "none";
					tmpNode.style.display = "block";
				}
			}
		}
	},
	init:function(){
		/* Loop every input element */
		var eltsArray=this.domObj.getElementsByTagName("input");
		for(i=0; i<eltsArray.length;i++){
			if(eltsArray[i].getAttribute("default")){
				var form=this;
				/* set default text on inputs */
				form.manipulateInput.setDefault.apply(eltsArray[i]);
				/* set default text for password fields */
				form.manipulateInput.password2text.apply(eltsArray[i]);
				
				/* set event handlers */
				eltsArray[i].onclick=function(){
					form.manipulateInput.clearDefault.apply(this);
					this.focus();
				};
				eltsArray[i].onfocus = function(){
					form.manipulateInput.clearDefault.apply(this);
				};
				eltsArray[i].onblur=function(){
					form.manipulateInput.setDefault.apply(this);
					form.manipulateInput.password2text.apply(this);
				};
				
			}
		}
	}
	});

Every ARIES object calls init method when html representation is ready. So if we need to initialize somehow this component we can do it by declaring init method. In the example we set up event handlers and default text on <input> tags.

To get instance of class above:

var loginForm=ARIES.Create("LoginForm");

Next step is to setTemplate.

var loginFormTemplate=['<form method=\"${this.get("method")}\" action=\"${this.get("action")}\">',
		'<div class="container">',
		'<h3>Login Form</h3>',
		'<input type="text" value="" name="userMail" default="enter mail!">',
		'<input type="password" value="" name="userPassword" default="enter password">',
		'<input type="submit" value="Log in">',
		'</div>',
		'</form>'].join('');

loginForm.setTemplate("main",loginFormTemplate);

The scope inside template is the scope of object. In our case loginForm. So to get ${this.get("method")} and ${this.get("action")} work well we need to define this variables.

loginForm.set("method","POST");
loginForm.set("action","/");

And attach the result to DOM

loginForm.attach(document.getElementById('form'));

Here you can check result of Example1

If we want to create a registration form, it is possible to extend LoginForm class. Also for registration it would be great to validate form.

ARIES.Class("LoginForm.RegisterForm",{
	/* Here we have rules to check fields */
	validationRules:{
			/* this checks if there is any data in input field */
			"required":[
			function(val){
				if(val=="true"){
					if(this.value&&this.value!=this.getAttribute("default")){
						return true;
					}else{
						return false;
					}
				}else{
					return true;
				}
				
				},"required field is missing!"],
			/* this compares two fields if they are equal */
			"equalto":[
			function(val){
				if(this.value==this.form[val].value){
					return true;
				}else{
					return false;
				}
			},"confirmation password is wrong!"],
			/* checks if the value have mail format */
			"ismail":[
			function(val){
				var filter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
				if (filter.test(this.value)) {
					return true;
				}else{
					return false;
				}
			}
			,"should be mail format!"],
			/* checks for minimum characters in the field */
			"min":[
			function(val){
				if(this.value.length>=val){
					return true;
				}else{
					return false;
				}
			}
			,"should contain minimum of {val} characters"]
		},
	validate:function(){
		var valErrorsStack=[];
		
		/* clear previously created error messages */
		var eltsArray=this.domObj.getElementsByTagName("input");
		for (i = 0; i < eltsArray.length; i++) {
			if(eltsArray[i].previousSibling.className=="msg"){
				eltsArray[i].parentNode.removeChild(eltsArray[i].previousSibling);
			}
			
			var elErr=false;
			for(rule in this.validationRules){ /* check every rule */
				if(eltsArray[i].getAttribute(rule)&&eltsArray[i].getAttribute(rule)!=""){
					if(!this.validationRules[rule][0].call(eltsArray[i],eltsArray[i].getAttribute(rule))&&!elErr){
						elErr=true;
						message=this.validationRules[rule][1].replace(/{val}/, eltsArray[i].getAttribute(rule));
						valErrorsStack.push({el:eltsArray[i],msg:message});
					}
				}
			}
		}
		
		if (valErrorsStack.length > 0) {
			/* create error messages above input field */
			for (i = 0; i<valErrorsStack.length; i++) {
				msgDiv=document.createElement("div");
				msgDiv.className="msg";
				msgDiv.innerHTML=valErrorsStack[i].msg;
				valErrorsStack[i].el.parentNode.insertBefore(msgDiv, valErrorsStack[i].el);
			}
			return false;
		}else{
			return true;
		}
	}
});

As you can see from code our RegisterForm class is inherited from LoginForm. So it already have init method and handles default text. Template for this class will be:

var registerForm=ARIES.Create("LoginForm.RegisterForm");

var registerFormTemplate=['<form method=\"${this.get("method")}\" action=\"${this.get("action")}\">',
		'<div class="container">',
		'<h3>Register Form</h3>',
		'<input type="text" value="" name="userName" default="enter login!" required="true" min="6">',
		'<input type="text" value="" name="userMail" default="enter mail!" required="true" ismail="true">',
		'<input type="password" value="" name="userPassword" default="enter password" required="true">',
		'<input type="password" value="" name="userCheckPassword" default="check password" equalto="userPassword">',
		'<input type="submit" value="Register" onclick="registerForm.validate();return false;">',
		'</div>',
		'</form>'].join('');


registerForm.setTemplate("main",registerFormTemplate);
registerForm.set("method","POST");
registerForm.set("action","/");

Here you can check result of Example2

As you see this library allows to create highly extensible structure of widgets.

Powered by Google Project Hosting