template模板,Jquery插件[js]

/**
*data JSON data, example:
*
* . [{a:""},{b:""}]
* . {a:""}
* . {a:"", b:""}
* . {a:{b:""}}
* . {a:{b:[{},{}]}}
*
*/
$.fn.extend({ tpl : function(data, config){
/** 入口函数
*
*d = {
*     v:v1, //object, array, string, number, date,
*     k:k1, //key
*     t:t1, //type enum [o:object, a:array, s:string, n:number, d:date]
*     i:i1, //index
*     pv:pv1  //parent value
*     pk:pk1, //parent key
*    }
*
*/
function _fn(jml, d, c){

_fbd(jml, d, c);
var jm = _fml(jml, d, c);

if(d.t === "o"){//object
_fno(jm, d, c);
}else if(d.t === "a"){//array
_fna(jm, d, c);
}else if(d.t === "d"){//date
_fnd(jm, d, c);
}else if(d.t === "s"){//string
_fns(jm, d, c);
}else if(d.t === "n"){//number
_fnn(jm, d, c);
}else if(d.t === "b"){//boolean
_fnb(jm, d, c);
}
_fbd(jml, d, c);
}

/** object
*
*
*
*
*/
function _fno(jml, d, c){
var v = d.v;
//call object, array first
for(var k in v){
var t = $.type(v[k]).substring(0,1);
if(t === "o" || t === "a"){
var d1 = _fpd(v[k], k, d.i, v, d.k);//
_fn(jml, d1, c);
}
}

//call except object, array
for(var k in v){
var t = $.type(v[k]).substring(0,1);
if(t !== "o" && t !== "a"){
var d1 = _fpd(v[k], k, d.i, v, d.k);//
_fn(jml, d1, c);
}
}
}

/** array
*
*
*
*
*/
function _fna(jml, d, c){
var v = d.v;
var len = v.length;
var nx = false;
//call object, array first
for(var i = 0; i < len; i++){
var t = $.type(v[i]).substring(0,1);
if(t === "o"){
if(nx){
var jc; //clone from tpl
if(d.k !== null){
jc = tpl.find("[jdata=" + d.k + "]").clone();
jc.attr("clone", d.k);
}else{
jc = tpl.clone();
jc.attr("clone", 0);
}
jc.insertAfter(jml);
jml = jc;
}

var d1 = _fpd(v[i], d.k ? d.k : i, i, v, d.k);//

_fn(jml, d1, c);

d1 = _fpd(i, c.index, i, v, d.k);//index 伪列
_fn(jml, d1, c);

nx = true;

}else if(t === "a"){
throw "ERROR:Array element still is an array.数组中的元素不能还是数组.";
}
//TODO 值类型的数据, 例如: ["篮球","跑步"]
else if(t === "d" || t === "s" || t === "n" || t === "b"){
var d1 = _fpd(v[i], d.k, i, d.p, d.pk);//
d.t = t;
_fn(jml, d, c);
break;
}


}
}

function _fnd(jml, d, c){
_fnv(jml.find("[jdata=" + d.k + "]"), d, c);
_fnv(jml.filter("[jdata=" + d.k + "]"), d, c);
}

function _fns(jml, d, c){
_fnv(jml.find("[jdata=" + d.k + "]"), d, c);
_fnv(jml.filter("[jdata=" + d.k + "]"), d, c);
}

function _fnn(jml, d, c){
_fnv(jml.find("[jdata=" + d.k + "]"), d, c);
_fnv(jml.filter("[jdata=" + d.k + "]"), d, c);
}

function _fnv(jml, d, c){
jml.each(function(){
var jd = $(this);
//call before render function
var v = _fbr(jd, d, c);
var t = $.type(v).substring(0,1);
if(t === "o"){
if(v[v] === undefined || v[k] === undefined || v[i] === undefined || v[pv] === undefined || v[pk] === undefined){
throw "ERROR:Unaceptable JSON object";
}
d = v;
}

//call render function 如果render函数返回false,则不调用默认的render方法
v = _fr(jd, d, c);
t = $.type(v).substring(0,1);
if(t === "o"){
if(v[v] === undefined || v[k] === undefined || v[i] === undefined || v[pv] === undefined || v[pk] === undefined){
throw "ERROR:Unaceptable JSON object";
}
d = v;
v = true;
}else{
if(t !== "b"){
v = true;
}
}
if(v){
var n = jd[0].tagName;
var cl = cv[n];
if(cl === undefined){
cl = cv["c"];//common function
}
cl(jd, d, c);
}

//call after render function
v = _far(jd, d, c);
t = $.type(v).substring(0,1);
if(t === "o"){
if(v[v] === undefined || v[k] === undefined || v[i] === undefined || v[pv] === undefined || v[pk] === undefined){
throw "ERROR:Unaceptable JSON object";
}
d = v;
}
var jdata = jd.attr("jdata");
jd.removeAttr("jdata");
jd.attr("jdat", jdata);
});
}


/** bind data
*
*
*/
function _fbd(jml, d, c){
if(!d.k){
return;
}

var m = jml.filter("[jbind*=" + d.k + "]");
_$m(m, d);
m = jml.find("[jbind*=" + d.k + "]");
_$m(m, d);
}

function _$m(m, d){
if(m.length >= 1){
m.each(function(){
var jd = $(this);
var a = jd.attr("jbind").split(",");
var tt = t(d.v);
var l = jd.find("[jdata=" + d.k + "]").length;
var b = [];
for(var i = 0; i < a.length; i++){
if(a[i] === d.k){
if("a" === t(d.v)){
if(l >= 1){
if(jd.data(d.k) === undefined){
jd.data(d.k, d.v);
}else{
b[b.length] = a[i];
}
}else{
b[b.length] = a[i];
}
}else{
if(jd.data(d.k) === undefined){
jd.data(d.k, d.v);
}
}

}else{
b[b.length] = a[i];
}
}

if(b.length >= 1){
jd.attr("jbind", b.join(","));
}else{
jd.removeAttr("jbind");
}

var dx = jd.data();
var kx = [];
for(var k in dx){
kx[kx.length] = k;
}
if(kx.length >= 1){
jd.attr("jbin", kx.join(","));
}
});
}
}
/** shrink template
*
*
*/
function _fml(jml, d, c){
if(d.k){
var m = jml.find("[jdata=" + d.k + "]");
if(m.length >= 1){
return m;
}
}
return jml;
}

/** package 封装数据
*
*
*/
function _fpd(v, k, i, pv, pk){
var c = t(v);
return {v:v, k:k, t:c, i:i, pv:pv, pk:pk};
}

function t(d){
return $.type(d).substring(0,1);
}
/** before render
* attr: beforeRender
* return true|false
*/
function _fbr(jml, d, c){
return _fcf(jml, d, c, "jbeforeRender", "jdata");
}

/** render
* return true|false
*/
function _fr(jml, d, c){

return _fcf(jml, d, c, "jrender", "jdata");
}

/** after render
* return true|false
*/
function _far(jml, d, c){

return _fcf(jml, d, c, "jafterRender", "jdat");
}

/** call function
*
*
*
*/
function _fcf(jml, d, c, fn, w){
if(!d.k){
return true;
}
var b = jml.filter("[" + w + "=" + d.k + "][" + fn + "]");
var a = jml.find("[" + w + "=" + d.k + "][" + fn + "]");

var x = g(jml, d, c, b, fn);
var y = g(jml, d, c, b, fn);

return x && y;
}

function g(jml, d, c, b, fn){
var r = true;
b.each(function(i){
var jd = $(this);//jdom
var a = jd.attr(fn);
if(a !== undefined){
var v = eval(a).apply(jd, [jml, d, c]);
var u = t(v);
if(t === "o"){
if(v["v"] === undefined || v["k"] === undefined || v["i"] === undefined || v["pv"] === undefined || v["pk"] === undefined){
throw "ERROR:Unaceptable JSON object. " + a + " function return an unacceptable object.";
}
d = v;
}else if(u === "b"){
if(!v && r){
r = v;
}
}
jd.attr(fn.substring(0, fn.length - 1), a);
jd.removeAttr(fn);
}
});
return r;
}

function e(jml, m, c){
jml.filter("[jdata]").each(function(){
var jd = $(this);
var k = jd.attr("jdata");

var d = _fpd("", k, null, null, null);
_fn(jd, d, c);
});
jml.find("[jdata]").each(function(){
var jd = $(this);
var k = jd.attr("jdata");

var d = _fpd("", k, null, null, null);
_fn(jd, d, c);
});

jml.filter("[jbind]").each(function(){$(this).attr("jfailBind", $(this).attr("jbind"));$(this).removeAttr("jbind")});
jml.find("[jbind]").each(function(){$(this).attr("jfailBind", $(this).attr("jbind"));$(this).removeAttr("jbind")});

jml.filter("[jafterRender][jbin]:not([jbind])").each(function(){
var jd = $(this);
var a = jd.attr("jafterRender");
var d = jd.data();
var v = eval(a).apply(jd, [jd, d, c]);
});
for(var k in m){
ec(jml, m[k], k);
}

if(c.lastChildCss){//fix IE doesn't support last-child
jml.find("td > table").each(function(){
var jd = $(this);
if(c.lastChildCss.lastRowChildCss){
jd.find("tr:last-child > td").css(c.lastChildCss.lastRowChildCss);
}
if(c.lastChildCss.lastColChildCss){
jd.find("tr > td:last-child, tr > th:last-child").css(c.lastChildCss.lastColChildCss);
}
});
}
}

/**
* @param jml
* @param g attribute new
* @param m attribute old
*
*/
function ec(jml, g, m){
jml.filter("[" + m + "]").each(function(){
$(this).attr(g, $(this).attr(m));
$(this).removeAttr(m);
});
jml.find("[" + m + "]").each(function(){
$(this).attr(g, $(this).attr(m));
$(this).removeAttr(m);
});
}

var cv = {
c : function(jd, d, c){
if(c.debug){
console.log("fill " + d.v + " to :: " + jd[0].outerHTML);
}
var jrp = jd.attr("jreplace");
var v = d.v;
d.t = t(d.v);
if(d.t === "d"){
v = v.format(c.dateFormat);
}else if(d.t === "a"){
v = v.join(c.joinChar);
}
if(jrp !== undefined){
jd.find(jrp).repalceWith(v);
}else{
jd.append(v);
}

}
,IMG : function(jd, d, c){
if(c.debug){
console.log("fill " + d.v + " to :: " + jd[0].outerHTML);
}
jd.attr("src", d.v);
}
,INPUT : function(jd, d, c){
//type = hidden, text, file, radio, checkbox, button
var p = jd.parent().parent();

if(jd.is(":radio")){

if(jd.attr("name") === undefined){
//bind group click
var g = p.find("input:radio[jdata=" + d.k + "]:not([name]),input:radio[jdat=" + d.k + "]:not([name])");

if(g.length >= 2){
if(c.debug){
console.log("bind group click to radio, " + g.length + " radios[input:radio[jdata=" + d.k + "]:not([name])] binded click event.");
}
g.click(function(){
var s = $(this);
g.each(function(){
if($(this).is(s)){
$(this).prop("checked", true);
}else{
$(this).prop("checked", false);
}
});
});
}
}

var jdr = p.find("input:radio[jdata=" + d.k + "][value=" + d.v + "],input:radio[jdat=" + d.k + "][value=" + d.v + "]");
if(c.debug){
console.log("fill " + d.v + " to :: " + jdr[0].outerHTML);
}
g.each(function(){
if($(this).is(jdr)){
$(this).prop("checked", true);
}else{
$(this).prop("checked", false);
}
});

}else if(jd.is(":checkbox")){
var g = p.find("input:checkbox[jdata=" + d.k + "],input:checkbox[jdat=" + d.k + "]");
var v = d.v;
if(t(v) === "a"){
g.each(function(){
var h = false;
for(var x = 0; x < v.length; x++){
if($(this).val() === v[x]){
h = true;
break;
}
}
if(h){
$(this).prop("checked", true);
}else{
$(this).prop("checked", false);
}
});
}else{
if(jd.val() == d.v){
jd.prop("checked", true);
}else{
jd.prop("checked", false);
}
}

}else{
var v = d.v;
if(d.t === "d"){
v = v.format(c.dateFormat);
}
jd.val(v);
}
}
,SELECT : function(jd, d, c){
if(c.debug){
console.log("fill " + d + " to :: " + jd[0].outerHTML);
}
var v = d.v;
if(d.t === "d"){
v = v.format(c.dateFormat);
}
jd.val(v);
}
,TEXTAREA : function(jd, d, c){
if(c.debug){
console.log("fill " + d + " to :: " + jd[0].outerHTML);
}
var v = d.v;
if(d.t === "d"){
v = v.format(c.dateFormat);
}
jd.val(d.v);
}
};

var am = {jdat : "jdata", jbin : "jbind"};
var em = {jbeforeRende : "jbeforeRender", jrende : "jrender", jafterRende : "jafterRender"};
am = $.extend(am, em);

var jml = $($(this)[0]);
var tpl = jml.clone();
jml.attr("clone", "self");

var ia = $.type(data) === "array";
var da = _fpd(data, null, null, null, null);
var co = {debug : false, index : "index", dateFormat : "yyyy-MM-dd hh:mm:ss", joinChar:","
,lastChildCss : {lastRowChildCss:{"border-bottom" : "0px"}, lastColChildCss:{"border-right" : "0px"}}
};
co = $.extend(co, config);
_fn(jml, da, co);
if(ia){
jml = jml.parent().children().filter("[clone]");
}

e(jml, am, co);

return jml;
}});
// 对Date的扩展,将 Date 转化为指定格式的String
// 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符,
// 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
// 例子:
// (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
// (new Date()).Format("yyyy-M-d h:m:s.S")      ==> 2006-7-2 8:9:4.18
// format author: meizz
Date.prototype.format = function (fmt) {
    var o = {
        "M+": this.getMonth() + 1, //月份
        "d+": this.getDate(), //日
        "h+": this.getHours(), //小时
        "m+": this.getMinutes(), //分
        "s+": this.getSeconds(), //秒
        "q+": Math.floor((this.getMonth() + 3) / 3), //季度
        "S": this.getMilliseconds() //毫秒
    };
    if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o)
    if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    return fmt;
}

猜你喜欢

转载自zhaixp1949.iteye.com/blog/2263559