8detect
10/27/2017 - 5:46 PM

xform api sepcifications

xform api

$.fn.xformGet|SetVal:
	$.fn.xformSetVal({field:value},[set_default=true],[is_filled=true])
	//thử cái này được không ?
	$.fn.xformSetVal(formdata,[set_default=true],[is_filled=true])
	
	nếu set_default true : thì các fielddom.defaultValue|defaultSelected|defaultChecked = value
	nếu is_filled = true, bindFirst('change', if value != '' addClass(is_filled) else remove(is_filled)

	$.fn.xformGetVal() -> toàn bộ {field} 
	$.fn.xformGetVal(true) -> toàn bộ {field}
	//chú ý các field được lấy thông qua api .val()
	//do vậy khi render các x-control có nhiều field ngầm bên trong thì phải hiện thực
	//một <input type="text" class="transparent ( opacity=0) offscreen z-index:-1000"
	//để đảm bảo các api cơ bản mà jquery hỗ trợ
	
	chú ý SetVal sẽ trigger('change') nếu giá trị có thay đổi
	
	
	$.fn.xformGetVal("field,field,field") chỉ lấy field match danh sách mà thôi các field khác bỏ qua
	$.fn.xformGetVal("formdata") -> formdata obj
	$.fn.xformGetVal(true,postfilter({field:value}){this, return {...}})
	//chú ý postfilter phải trả về {field:value} nếu không xformGetVal() sẽ null

$.fn.xformFilters({
	field: "trim,fx",
	field:{
		fx:arg
	}
	
})
//hiện thực = onchange tuy nhiên priority phải thực hiện trước tiên tức dùng bindFirst
//trước mọi onchange

$.fn.xformRenders({})

//nếu không có nhiều nhu cầu render thì nên gọi trực tiếp các hàm fn.xxx để biến đổi control
//chú ý nên gọi sau filter và trước validator 

//xformvalidator chỉ nên gọi cho các field mà bản chất cần bổ sung validator mà html5 
//không hỗ trợ , còn lại thì không cần cứ đặc tả attribute trong field là ok
$.fn.xformValidators({
	field: {
		required:// chỉ cần add attribute vào là đủ không cần xử lý onchange !
		pattern:// chỉ cần add attribute vào là đủ không cần xử lý onchange !
		equalTo: // cần xử lý 
		greaterThan:// cần xử lý 
		lessThan:// cần xử lý 
		remote:{
			src:"" //server trả về response.success = true/false			
		}
		/*
xử lý cho remote

nếu field error thì sau khi set setCustomValidity('msg tùy ý') -> sẽ làm field:invalid
thì dò tìm .siblings('invalid-feedback').data('origin-invalid-feedback') nếu chưa có
nếu có rồi thì .siblings('invalid-feedback').html(response.field1.errmsg)
nếu field success
			
thì dò tìm siblings('invalid-feedback').data('origin-invalid-feedback') != null
nếu khác null siblings('invalid-feedback').html(siblings('invalid-feedback').data('origin-invalid-feedback'))
còn nếu == null thì khỏi thay đổi vì đơn giản remote chưa thực hiện mà trước đó chỉ có các validator
html5 hoạt động thôi
		*/
	}
});

Để đơn giản nên hạn chế remote validate vì sau khi submit thì trên server cũng phải validate lần
nữa vậy nên hạn chế hoặc bỏ remote validate 

$.fn.xformAttr({
	//bổ sung các thuộc tính cho form
	action: "/auth/authpost",
	title: "User Authentication",
	
	id: "x-form-auth",//id of form dom
	method: "POST",//def:true
	
});


$.fn.xformSubmit({
	/*
		khi gọi hàm này sẽ chặn default submit và thực hiện code sau
		$form.on('submit', function (e) {

                var $form = $(this);
                //mark for the first time submit, nếu không có đoạn này thì ngay lúc đầu các field ở trạng thái invalid
                $form.addClass('was-validated');
                
                //html5 check if valid or not. or somefield is being validating
                if ($form[0].checkValidity() == false ) {
                    e.preventDefault();
                    e.stopPropagation();
                    //find the first invalid then focus
                    $form.find(':invalid').first().focus();
                    e.stopImmediatePropagation(); //no more other submit handler
                    return;
                }
                //nếu có 1 field bất kỳ mà có trạng thái is_validating thì đợi 500ms sau gọi lại
                //có thể dùng promise $(field).data('validating-promise')
                else if ($form.find('.is_validating').length) {
                    e.preventDefault();
                    e.stopPropagation();
                    e.stopImmediatePropagation(); //stop other submit handlers from occurring
                    
                    window.setTimeout(function(){
                        $form.trigger('submit');
                    },500);
                    
                    return;
                }
				
				if (cfg.beforeSumit) 
				{
					if (!cfg.beforeSubmit.call(this)) 
					{	
						e.preventDefault();
						e.stopPropagation();
						return;
					}
					
				}				
				
				
				if (cfg.submit) cfg.submit.call(this);
				else {
					e.preventDefault();
                    e.stopPropagation();
					
					
					$form.data('submit-promise',$.ajax({
						
						done:cfg.done,
						fail:cfg.fail,
						progress:cfg.progress,
						success:cfg.success
					});
					
					
					
				}

            });
	
	*/,
	//nếu đặc tả thì phải return true thì form mới submit
	beforeSubmit:function(e){
		
		
		return true
	},
	submit:function(e){
		//nếu đặc tả submit thì các ajax handler dưới đây không xảy ra 
	},
	done:function(response,status){
		
	},
	fail:function(response,status){
		
	},
	progress:function(percent,time){
		
	},
	success:function(response,status){
		
		switch reponse.success

			true: response.success 
				
			
			false :
			
				if response.invalidFields then 
			
					$form.xformInvalidates({
						field1: {errcode:'',errmsg:''},
						field2: {errcode:'',errmsg:''},
					})
				else
					$.msgBox({title:'',msg:''});
		
		
	}
	
	
})


$.fn.xformValidity({
	field1: {errcode:'',errmsg:''},
	field2: {errcode:'',errmsg:''},
});
//thiết lập các dom.setCustomValidity('') -> sẽ làm field:valid 
//			dom.setCustomValidity('msg tùy ý') -> sẽ làm field:invalid 
//chú ý cũng giống Validators({field:{remote}})
//nếu field error thì sau khi set setCustomValidity('msg tùy ý') -> sẽ làm field:invalid
//thì dò tìm .siblings('invalid-feedback').data('origin-invalid-feedback') nếu chưa có
//nếu có rồi thì .siblings('invalid-feedback').html(response.field1.errmsg)

//show submitting progress
//hiển thị 1 layer với loading 
$.fn.xformProgress({
	veil:true,
	veilBgImg:"",
	veilBgColor:"",
	text:''
})

$.fn.xformDisableBtn({
	
});
$.fn.xformEnableBtn({
	
});


/*
*	CONFIG TỔNG QUÁT
*/

// mỗi part sẽ dùng các hàm api rời ở trên để xử lý
form:{
		action: "/auth/authpost",
		title: "User Authentication",
		
		id: "x-form-auth",//id of form dom
		method: "POST",//def:true
		
		
		beforesubmit:function(fields){
			var $form = this;
		},
		submit:function(fields){
			var $form = this;
		},
		//done luôn được gọi sau khi ajax thành công tức lỗi server hay đường truyền, hàm này không có sẵn
		done:function(response){
			var $form = this;
			//hiển thị thông điệp server lên panel hiển thị dưới form ( đừng để lên đầu như trước không hay )
			$form.find('.x-form-responder').html(...);
			//hoặc không thì dialog
			$.showModalDialog({...});
		},
		//fail được gọi khi ajax không thành công tức lỗi server hay đường truyền, hàm này có sẵn chỉ hiển thị dialog các thông điệp, nếu không thích thì override lại
		fail:function(response){
			var $form = this;
			//khi ajax không thành công
		}
		
		//cũng tương tự như error sau khi ajax trả về
		success:function(response){
			var $form = this;
			
			//tức response.success = true
			
			$form.find('.x-form-responder').html(...);
			//hoặc không thì dialog
			$.showModalDialog({...});
		},
		//set default value gồm .val() và cả thiết lập mức dom.defaultValue, .defaultChecked (cho checkbox ), .defaultSelected ( cho option )
		values:{
			field:'value',
			field1:{
				value:'value',
				//các arg khác nếu có
			}
		},
		
		//có thể dùng rời rạc với hàm $('form').xformFilter({field:{},field{}})
		filters:{
			field: 'trim,fx1,fx2' //các filter đơn giản không cần arg ví dụ : trim, capitatize, stripoff tag ...
			//hoặc
			field: {
				trim:arg1,
				fx1:argfx1
				//...
			}
		},
		//có thể dùng rời rạc với hàm $('form').xformRender({field:{},field{}})
		renders:{
			field:'fx',
			field:function(){
				hàm nhận this là $fieldEl
				this.xxx(các hàm biến đổi ví dụ datefield gì đó)(arg)
			},
			
		},
		
		//có thể dùng rời rạc với hàm $('form').xformValidator({field:{},field{}})
		validators:{
			field:{
				required:true,
				equalTo:'field'
				//...
				/*
					chú ý ta chỉ nên hiện thực các validator mà html5 không hỗ trợ
					còn lại tận dụng tính năm html5 đặc tả trong attribute của tag là đủ
					khi set valid/invalid tuân thủ chuẩn html5 
					dom.setCustomValidity('') -> sẽ làm field:valid 
					dom.setCustomValidity('msg tùy ý') -> sẽ làm field:invalid 
					
					để kiểm tra field có error không dùng dom.checkValidity
					The HTMLSelectElement.checkValidity() method checks whether the element has any constraints and whether it satisfies them. If the element fails its constraints, the browser fires a cancelable invalid event at the element, and then returns false.

					var result = [input,select,textarea,form].checkValidity() true/false
					
					form.checkValidity() chỉ trả về true khi mọi field bên trong nó true
					
					có thể dùng x-moz-errormessage="invalid-feedback" cho field 
					moz chỉ support cho firefox
					
					các thuộc tính chi tiết về lỗi các field mà html5 hỗ trợ :
					dom.ValidityState.*
ValidityState.badInput Read only
	Is a Boolean indicating the user has provided input that the browser is unable to convert.
ValidityState.customError Read only
	Is a Boolean indicating the element's custom validity message has been set to a non-empty string by calling the element's setCustomValidity() method.
ValidityState.patternMismatch Read only
	Is a Boolean indicating the value does not match the specified pattern.
ValidityState.rangeOverflow Read only
	Is a Boolean indicating the value is greater than the maximum specified by the max attribute.
ValidityState.rangeUnderflow Read only
	Is a Boolean indicating the value is less than the minimum specified by the min attribute.
ValidityState.stepMismatch Read only
	Is a Boolean indicating the value does not fit the rules determined by the step attribute (that is, it's not evenly divisible by the step value).
ValidityState.tooLong Read only
	Is a Boolean indicating the value exceeds the specified maxlength for HTMLInputElement or HTMLTextAreaElement objects. Note: This will never be true in Gecko, because elements' values are prevented from being longer than maxlength.
ValidityState.tooShort Read only
	Is a Boolean indicating the value fails to meet the specified minlength for HTMLInputElement or HTMLTextAreaElement objects.
ValidityState.typeMismatch Read only
	Is a Boolean indicating the value is not in the required syntax (when type is email or url).
ValidityState.valid Read only
	Is a Boolean indicating the element meets all constraint validations, and is therefore considered to be valid.
ValidityState.valueMissing Read only
	Is a Boolean indicating the element has a required attribute, but no value.
					
					https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation
					
Validation-related attributes
The following attributes are used to describe basic constraints:

Attribute	Input types supporting the attribute	Possible values	Constraint description	Associated violation
pattern	text, search, url, tel, email, password	A JavaScript regular expression (compiled with the ECMAScript 5 global, ignoreCase, and multiline flags disabled)	The value must match the pattern.	Pattern mismatch constraint violation
min	range, number	A valid number	The value must be greater than or equal to the value.	Underflow constraint violation
date, month, week	A valid date
datetime, datetime-local, time	A valid date and time
max	range, number	A valid number	The value must be less than or equal to the value	Overflow constraint violation
date, month, week	A valid date
datetime, datetime-local, time	A valid date and time
required	text, search, url, tel, email, password, date, datetime, datetime-local, month, week, time, number, checkbox, radio, file; also on the <select> and <textarea> elements	none as it is a Boolean attribute: its presence means true, its absence means false	There must be a value (if set).	Missing constraint violation
step	date	An integer number of days	Unless the step is set to the any literal, the value must be min + an integral multiple of the step.	Step mismatch constraint violation
month	An integer number of months
week	An integer number of weeks
datetime, datetime-local, time	An integer number of seconds
range, number	An integer
maxlength	text, search, url, tel, email, password; also on the <textarea> element	An integer length	The number of characters (code points) must not exceed the value of the attribute.	Too long constraint violation					
					
				*/
				msg:{
					required:'error msg',
					required:'@required', dùng bảng msg chung 
					//...
				}
			}
			
		},
		
		//tổng hợp cả values, filter,render và validator
		//nếu không thích tổng hợp
		//thì làm rời rạc ở trên từng cái tùy trường hợp
		fields: {
			username: {
				value: "",//set default value
				render: {
					fx: "renderfx",
					params : {
						pattern: "int"
					}
				},
				render : "renderfx" //all default
				/***/
				//cho phép filter được chain
				filter:[
					"filter1",
					{fx:'filtername',param1:'',param2:''},
					fx:function(params){
						
					}					
				],
				filter:"trim", //as shortcut
				/***/
				validator:{
					required:true,
					equalTo:fieldName,
					invalidFeedback:{
						required:'text',
						required:'@required' //dùng bảng invalidFeedbacks toàn cục
					}
					
				}
			},
			password: {
				validator: {
					filter: "trim",
					required: true
				},
				msg: {
					required: "Mật khẩu không được để trống",
					407: "Mật Khẩu Sai !"
				}
			},
			captcha:{



				key: "auth",//server session key
				render: {
					transform: "captcha",
					url: "/captcha",
					height: 58,
					width: 100,
					autosize: true
				},
				validator: {
					required: 1,
					_captcha: { //không nên kiểm tra captcha on blur field !
						url: "/captcha"
					}
				},
				msg: {
					required: "Captcha không được để trống",
					captcha: "Captcha không khớp",//validate on blur 
					407: "Captcha không khớp"//validate from server
				},

			},
			redirect: {
				type: "hidden"
			},

		},
		invalidFeedback: {
			"@succ": "Authenticated Successfully !",
			"@err": "Authentication Failed !",
			"@req": "This field is required !",
			"@pat": "Invalid format !"
		}

	},