zl程序教程

您现在的位置是:首页 >  前端

当前栏目

javascript实现动态模态绑定grid过程代码

JavaScript代码 实现 过程 动态 绑定 模态 Grid
2023-06-13 09:15:46 时间
<html>
<head>
<styletype="text/css">
.grid{border:1pxsolid#808080;border-spacing:0;width:500px;border-collapse:collapse}
.gridth,.gridtd{border:0;text-align:center;}
.gridtr{height:25px;line-height:25px;}
.gridtr.odd{background:#d0d0d0}
.grid.btn{width:80px;text-align:center}
</style>

<scripttype="text/javascript">
(function(){
//
varutil={
next:functionnext(ele){
if(ele){
varn=ele.nextSibling;
if(n&&n.nodeType===1){
returnn;
}
returnnext(n);
}
},
parseJSON:function(str){
if(typeofJSON!=="undefined"){
returnJSON.parse(str);
}
returneval("("+str+")");
},
parseArray:function(obj){
if(!obj){
returnobj;
}
varresult=[];
if(typeofobj.length!=="undefined"){
try{
vararr=Array.prototype.slice.call(obj,0);
result=arr;
}catch(e){
for(vari=0;i<obj.length;i++){
try{
vartarget=obj[i];
}catch(e){
if(obj.item){
vartarget=this.item(i);//nodeList
}
}
if(typeoftarget!=="undefined"){
result.push(target);
deletetarget;
}
}
}
}
returnresult;
},
isFunction:function(fn){
returntypeoffn==="function";
},
trim:function(str){
if(typeofstr!=="string"){
returnstr;
}
returnstr.replace(/^\s+|\s+$/g,"");
},
offset:functionoffset(ele){
varresult={top:0,left:0};
if(!ele||ele.nodeType!==1){
returnresult;
}
result.top=Number(ele.offsetTop||(ele.style.top||"0").replace(/[^\d]+$/,""));
result.left=Number(ele.offsetLeft||(ele.style.left||"0").replace(/[^\d]+$/,""));
if(ele.parentNode){
varr=offset(ele.parentNode);
result.top+=r.top;
result.left+=r.left;
}
returnresult;
}
};

//事件处理
varEvent={
on:function(eventType,fn){
varelement=this;
if(this.addEventListener){
this.addEventListener(eventType,fn,false);
}elseif(this.attachEvent){
//将事件缓冲到该标签上,已解决this指向window(现fn内this指向element)和移除匿名事件问题
var_EventRef="_"+eventType+"EventRef";
if(!element[_EventRef]){
element[_EventRef]=[];
}
var_EventRefs=element[_EventRef];
varindex;
for(indexin_EventRefs){
if(_EventRefs[index]["realFn"]==fn){
return;
}
}
varnestFn=function(){
fn.apply(element,arguments);
};
element[_EventRef].push({"realFn":fn,"nestFn":nestFn});
element.attachEvent("on"+eventType,nestFn);
}
},
remove:function(eventType,fn){
varelement=this;
if(this.removeEventListener){
this.removeEventListener(eventType,fn,false);
}elseif(this.detachEvent){
var_EventRef="_"+eventType+"EventRef";
if(!element[_EventRef]){
element[_EventRef]=[];
}
var_EventRefs=element[_EventRef]
varindex;
varnestFn;
for(indexin_EventRefs){
if(_EventRefs[index]["realFn"]==fn){
nestFn=_EventRefs[index]["nestFn"];
if(index==_EventRefs.length-1){
element[_EventRef]=_EventRefs.slice(0,index);
}else{
element[_EventRef]=_EventRefs.slice(0,index).concat(_EventRefs.slice(index+1,_EventRefs.length-1));
}
break;
}
}
if(nestFn){
element.detachEvent("on"+eventType,nestFn);
}
}
}
};

//extend
(function(){
//删除数组中指定下标出的元素
Array.prototype.remove=function(index){
varo=this[index];
if(typeofo!=="undefined"){
if(index==0){
this.shift();
}elseif(index===this.length-1){
this.pop();
}else{
vararr1=this.slice(0,index);
vararr2=this.slice(index+1);
this.length=0;
this.concat(arr1,arr2);
}
}
}
//删除数组中所有的元素
Array.prototype.clear=function(){
this.length=0;
}
//each
Array.prototype.each=function(fn){
if(!util.isFunction(fn)){
return;
}
for(vari=0;i<this.length;i++){
if(typeofthis[i]!=="undefined"){
fn.call(this[i],i);
}
}
}

//
varcollection=this.collection=function(){
this.__data={};
this.length=0;
}
collection.prototype={
add:function(obj){
this.__data[this.length++]=obj;
},
get:function(index){
returnthis.__data[index];
},
remove:function(index){
varobj=this.__data[index];
if(typeofobj!=="undefined"){
this.length--;
}
deletethis.__data[index];
},
clear:function(){
this.__data={};
this.length=0;
},
each:function(fn){
varindex=0;
for(varkinthis.__data){
if(k&&typeofthis.__data[k]!=="undefined"){
fn.call(this.__data[k],index++);
}
}
},
toArray:function(){
vararr=[];
this.each(function(){
arr.push(this);
});
returnarr;
}
};
})();
//
vargrid=this.grid=function(table,options){
grid.prototype._init.call(this,table,options);
}
grid.prototype={
_init:function(table,options){
if(typeoftable==="undefined"||!table){
throw"tableisundefinedornull";
}
if(table.nodeType!==1||!/^table$/i.test(table.tagName)){
throw"tablemustbe"table"element.";
}
table.guid=++grid.guid;
this.__cache={};
varself=this;
varheader=this.__cache["header"]=loadHeader();//header
this.__root=header.parentNode;
vartemplateRow=this.__cache["template"]=loadTemplate();//模板行
this.__cache["dataFormat"]=loadDataFormat();//数据模板
this.__cache["dataRows"]=newcollection();//数据行
this.__cache["customCache"]=newcollection();//用户缓存数据
this.__editRow=null;//当前编辑行
this.__saveContainer=createSaveButton();//保存按钮
this.__cache["commandHandles"]={//commandhandels
removeRow:function(){
varrowIndex=this.getAttribute("index");
self.removeRow.apply(self,[rowIndex]);
},
newLine:function(){
self.newLine();
}
};
this.__regCommand=function(commandName,row){//注册command
if(row){
vararg=row.getAttribute("index");
this.setAttribute("index",arg||false);
}
this.commandName=commandName;
Event.remove.call(this,"click",exec);
Event.on.call(this,"click",exec);
}
this.__removeRowCallback=function(){//改变行的背景样式
varrows=this.__cache["dataRows"];
varcustomCache=this.__cache["customCache"];
vararr=rows.toArray(),dataArr=[];
varrowIndex,row,data;

rows.clear();
arr.each(function(i){
rowIndex=this.getAttribute("index");
data=customCache.get(rowIndex);
dataArr.push(data);
this.setAttribute("index",i.toString());
rows.add(this);
if(i%2==1){//基数行
if(!/\sodd\s|\sodd$/g.test(this.className)){
this.className=(this.className||"")+"odd";
}
}elseif(/\sodd\s|\sodd$/g.test(this.className)){
this.className=this.className.replace(/\sodd\s|\sodd$/g,"");
}
i++;
});

customCache.clear();
dataArr.each(function(){
customCache.add(this);
});
}

//事件处理
options=options||{};
this.onDataBinding=options.onDataBinding||this.onDataBinding;
this.onRowBinding=options.onRowBinding||this.onRowBinding;
this.onRowBinded=options.onRowBinded||this.onRowBinded;

functionloadHeader(){
vartr=table.firstChild;
if(tr&&tr.nodeType!=1){
tr=util.next(tr);
}
if(!/tr/i.test(tr.tagName)){//如果第一个元素不是tr,则浏览器支持tbody
tr=tr.firstChild;
if(tr.nodeType!=1){
tr=util.next(tr);
}
}
returntr;
}

functionloadTemplate(){
tr=util.next(header);//获取模板行
returntr;
}

functionloadDataFormat(){
varnodes=templateRow.childNodes,ele,data,result={},attr;
nodes=util.parseArray(nodes);
nodes.each(function(i){
ele=this;
if(ele&&ele.nodeType==1){
attr=ele.data||ele.getAttribute("data");
if(attr){
data=util.parseJSON(attr);
ele.field=data.field;
result[ele.field]=data;
}
}
});
returnresult;
}

functioncreateSaveButton(){
vardiv=document.createElement("div");
div.style.position="absolute";
div.style.display="none";
div.style.width="auto";
varbtn=document.createElement("button");
btn.innerHTML=btn.innerText=btn.textContent=btn.value="Save";
try{
btn.type="button";
}catch(e){
btn.setAttribute("type","button");
}
div.appendChild(btn);

varbtnCancel=document.createElement("button");
btnCancel.innerHTML=btnCancel.innerText=btnCancel.textContent=btnCancel.value="Cancel";
try{
btnCancel.type="button";
}catch(e){
btnCancel.setAttribute("type","button");
}
div.appendChild(btnCancel);

document.body.appendChild(div);
Event.on.call(btn,"click",function(){
self.save();
});
Event.on.call(btnCancel,"click",function(){
div.style.display="none";
if(self.__editRow){
self.__editRow.parentNode.removeChild(self.__editRow);
self.__editRow=null;
}
});

returndiv;
}

functionexec(){
if(self.__editRow){//如果当前处于编辑模式,则禁用所有command
return;
}
varcommandName=this.commandName;
varhandler=self.__cache["commandHandles"][commandName];
if(handler){
handler.call(this);
}
}

//去除模板行
templateRow.parentNode.removeChild(templateRow);

//处理表格中的command事件
varelements=header.getElementsByTagName("*");
elements=util.parseArray(elements);
elements.each(function(){
if(this.nodeType===1){
varcommandName=this.command||this.getAttribute("command");
if(commandName){
self.__regCommand.call(this,commandName,header);
}
}
});
},
//bangding
bind:function(data){
this.clear();
if(data&&data.length>0){
varself=this;
data.each(function(){
self.append(this);
});
}
},
//清理表,删除所以除header以外的数据行
clear:function(){
varrows=this.__cache["dataRows"],row;
rows.each(function(){
row=this;
if(row){
row.parentNode.removeChild(row);
}
});
rows.clear();//清理rows
},
//删除指定的行
removeRow:function(rowIndex){
varrows=this.__cache["dataRows"];
varrow=rows.get(rowIndex);
if(row){
vardata=this.__cache["customCache"][rowIndex];
row.parentNode.removeChild(row);
rows.remove(rowIndex);
//通知用户数据行被移除
if(util.isFunction(this.onRowRemoved)){
this.onRowRemoved(data,row);
}
}
this.__removeRowCallback();
},
//添加行
append:function(data){
if(!data){
return;
}
vartemplate=this.__cache["template"];
varrows=this.__cache["dataRows"];
varrowIndex=rows.length;
vartr=template.cloneNode();
varcustomCache=this.__cache["customCache"];
customCache.add(data);
//将数据行添加到table
this.__root.appendChild(tr);
varself=this;
vartd,//数据单元格
dataFormat,//数据格式化器
value;//单元格中的给定的数据
tr.setAttribute("index",rowIndex.toString());
//更改样式
if(rowIndex%2==1){
tr.className=(tr.className||"")+"odd";
}
//通知行数据绑定开始
if(util.isFunction(this.onRowBinding)){
this.onRowBinding(rowIndex,tr);
}

vartemplateTD=template.firstChild;
while(templateTD){
td=templateTD.cloneNode(true);
tr.appendChild(td);
if(td.nodeType==1&&templateTD.field){
dataFormat=this.__cache["dataFormat"][templateTD.field];
td.removeAttribute("data");
td.field=templateTD.field;
value=data[dataFormat.field];
//通知单元格数据绑定事件
value=this.onDataBinding(dataFormat.field,value,td,data);
if(value!==false){//如果返回false,则不用做赋值操作
switch(dataFormat.render){
case"innerHTML":
td.innerHTML=typeofvalue=="undefined"||value==null?"":value;
break;
case"innerText":
default:
td.innerText=td.textContent=typeofvalue=="undefined"||value==null?"":value;
break;
}
}
}
templateTD=templateTD.nextSibling;
}
rows.add(tr);

//处理command
varelements=tr.getElementsByTagName("*"),ele,attr;
elements=util.parseArray(elements);
elements.each(function(){
ele=this;
if(ele.nodeType==1&&(ele.command||ele.getAttribute("command"))){
attr=ele.command||ele.getAttribute("command");
self.__regCommand.call(ele,attr,tr);
}
});

//通知行数据绑定完成
if(util.isFunction(this.onRowBinded)){
this.onRowBinded(rowIndex,tr);
}
},
//手动产生新的输入行
newLine:function(){
if(this.__editRow){//如果当前有存在编辑行,则直接返回,每次最多限制编辑一行数据
return;
}
vartemplate=this.__cache["template"];
varrow=this.__editRow=template.cloneNode(false);
vartemplateTD=template.firstChild;
vartextareaList=[];

while(templateTD){
td=templateTD.cloneNode(true);
row.appendChild(td);
if(td.nodeType==1){
if(templateTD.field){
td.field=templateTD.field;
td.innerHTML="";
vardataFormat=this.__cache["dataFormat"][templateTD.field];
vartextarea=null;
if(dataFormat.render=="innerHTML"){
textarea=document.createElement("textarea");
}else{
textarea=document.createElement("input");
textarea.type="text";
}
textarea.style.display="none";
td.appendChild(textarea);
textareaList.push(textarea);
}
}
templateTD=templateTD.nextSibling;
}
//将数据行添加到table
this.__root.appendChild(row);

varheight=row.offsetHeight,
width=row.offsetWidth,
offset=util.offset(row);

textareaList.each(function(){
this.style.height=(0.8*height)+"px";
this.style.width=(0.8*this.parentNode.offsetWidth)+"px";
this.style.display="";
});

varleft=offset.left+width+5;
vartop=offset.top;
this.__saveContainer.style.top=top+"px";
this.__saveContainer.style.left=left+"px";
this.__saveContainer.style.height=this.__saveContainer.style.lineHeight=height+"px";
this.__saveContainer.style.display="block";
},
//保存手动产生的数据行数据
save:function(){
if(!this.__editRow){
return;
}

varrow=this.__editRow;
vartd=row.firstChild;
vardata={};
while(td){
if(td.nodeType===1&&td.field){
vardataFormat=this.__cache["dataFormat"][td.field];
vartextarea=null;
if(dataFormat.render=="innerHTML"){
textarea=td.getElementsByTagName("textarea")[0];
}else{
textarea=td.getElementsByTagName("input")[0];
}
value=textarea.value;
switch(dataFormat.dataType){
case"number":
value=util.trim(value);
value=Number(value.length==0?0:value);
break;
default:
break;
}
data[td.field]=value;
}
td=td.nextSibling;
}
this.__editRow.parentNode.removeChild(this.__editRow);
this.__editRow=null;
this.__saveContainer.style.display="none";

//通知用户正在保存数据
if(util.isFunction(this.onSaving)){
this.onSaving(data);
}

this.append(data);
},
getRowData:function(rowIndex){
returnthis.__cache["customCache"].get(rowIndex);
},

//数据绑定到指定cell时的事件
onDataBinding:function(field,value,cell,data){
returnvalue;
},
//当数据行绑定开始时的事件
onRowBinding:function(rowIndex,row){
},
//当数据行绑定完成时的事件
//@paramrow{DOMelementtr}
onRowBinded:function(rowIndex,row){
},
//当编辑的数据被保存时的事件
onSaving:function(data){
},
//当数据行被移除时的通知事件
onRowRemoved:function(data,row){
}
};

grid.guid=0;
})();


</script>
</head>

<body>
<tableid="table_demo"class="grid">
<trclass="odd">
<th>ID</th>
<th>Name</th>
<th>Descpription</th>
<th><buttontype="button"command="newLine"class="btn">NewLine</button></th>
</tr>
<tr>
<tddata="{"field":"id","dataType":"number","render":"innerText"}">1</td>
<tddata="{"field":"name","dataType":"string","render":"innerText"}">WorkingService</td>
<tddata="{"field":"description","dataType":"string","render":"innerHTML"}">WorkingService</td>
<td>
<buttontype="button"command="removeRow"class="btn">Delete</button>
</td>
</tr>
</table>
<scripttype="text/javascript">
vartable=document.getElementById("table_demo");
varg=newgrid(table,{
onDataBinding:function(field,value){
returnvalue;
},
onRowBinded:function(rowIndex,row){}
});
g.bind([
{id:0,name:"kilin"},
{id:1,name:"kilin1"},
{id:2,name:"kilin2"},
{id:3,name:"kilin3"}
]);
</script>
</body>
</html>