javascript编辑表格二

1、在上一节的基础上加入了获取当前编辑行的行号

2、添加了keyup导航功能

3、说明文档升级 

4、添加了单击某行编辑此行的功能

上代码

function New(aClass, aParams)    //通用创建函数
{
    var empty = {};
    jQuery.extend(empty, aClass, aParams);
    return empty;
};
/*
约定:1.函数手写字母大写的是公有函数,小写的是私有函数
      2.
*/
WSGrid =
{ //_this.private_tr
TableId:'',
private_tr:null,//表格上当前编辑的行,要隐藏的行
private_editTr:null,//根据属性“wsEditable='true'”获取的编辑行
private_templateTr:null,//行模版
private_table:null,//Init方法根据TableId获取的table的jquery对象
private_sumTr:null,//计算行在tfoot下_this.private_sumTr
private_dbname:[],//可编辑的控件ws_dbname
/*
描述:各个字段如何取值,设置
ws_getaid:function(v,flag):从界面上取值
ws_setaid:function(v,value,flag):设置界面上的值
ws_getEditaid:function(v,flag):从控件上取值
ws_setEditaid:function(v,value,flag):设置控件上的值
*/
GetSetFuncs:{},
/*
功能:行数变化时调整编辑行是否显示
*/
adjustUi:function()
{
var _this=this;
var li_length=_this.private_table.find("tbody tr[ws_edit !='true']").length;
//如果没有普通行则隐藏编辑行
if(li_length<=0)
{
_this.private_editTr.hide();
}
else
{
if(li_length==1)
{
_this.private_editTr.show();
}
}
},
/*
功能:初始化,根据tableid获取table存放在变量table中
算法:1.获取table
2.获取当前编辑的editTr和tr
*/
Init:function()
{
var _this=this;
//1.获取table
_this.private_table=$("#"+_this.TableId);
//2.获取当前编辑的editTr和tr
_this.iniGetEditTr();
},
/*
功能:获取当前编辑的editTr和对应的隐藏的行
算法:1.获取editTr、获取编辑模版上可编辑的控件的ws_dbname放在数组private_dbname中
2.设置编辑的行(隐藏的行)--因为是初始化所以用不含[ws_edit='true']属性的最后一行作为隐藏的行
3.获取模版行
4.设置编辑界面
*/
iniGetEditTr:function()
{
var _this=this;
var li_currrow;
//1.获取editTr、获取编辑模版上可编辑的控件的ws_dbname放在数组private_dbname中
_this.private_editTr=_this.private_table.find("tbody tr[ws_edit='true']");//编辑界面editTr
$.each(_this.private_editTr.find("[ws_ctrl='true'][tagName!='TD']"),function(k,v){_this.private_dbname[k]=$(v).attr('ws_dbname');});
_this.private_templateTr=_this.private_table.find("thead tr[ws_template='true']");//行模版
_this.private_sumTr=_this.private_table.find("tfoot tr[ws_sum='true']");//合计行
//2.设置编辑的行(隐藏的行)
li_currrow=_this.private_editTr.attr('rowIndex');
li_currrow=li_currrow - 1;
//4.设置编辑界面
_this.setCurrTr(li_currrow);
//行数变化时调整编辑行是否显示
_this.adjustUi();
},
/*
功能:设置为当前行
算法:1.根据rowIndex获取tr,隐藏此行
    2.把隐藏的行的值设置到编辑控件上
    3.将editTr移动到隐藏行的后面
参数:row:rowIndex
*/
setCurrTr:function(row)
{
var _this=this;
//1.根据行号获取tr,隐藏此行
_this.private_tr=_this.private_table.find("tbody tr[rowIndex='"+row+"']");
_this.private_tr.hide();
//2.把隐藏的行的值设置到编辑控件上
_this.setValToEditCtrl();
//3.将editTr移动到隐藏行的后面
$(_this.private_tr).after(_this.private_editTr);
},
/*
描述:编辑新行之前,先保存数据,然后显示原编辑行
算法:1.把当前的控件上的值写到tr对应的界面(非编辑)上
2.显示原编辑的行
*/
setLastTr:function()
{
var _this=this;
//1.把当前的控件上的值写到tr对应的界面(非编辑)上
_this.setValToTD();
//2.显示原编辑的行
_this.private_tr.show();
},
/*
功能:获取自定义函数
*/
getCustomFunc:function(funcname)
{
var _this=this;
var rtn_func=null;
$.each(_this.GetSetFuncs,function(k,v)
{
if(k==funcname)
{
rtn_func=v;
return false;
}
});
return rtn_func;
},
/*
功能:从TD中获取val或者text
算法:1.从qryObj中获取相关属性     
    2.判断是否有自定义取值函数,如果有则调用自定义函数,否则按照默认取值
    3.flag=0:取value,flag=1:取text
*/
getTD:function(qryObj,flag)
{
var _this=this;
var func=null;
var ls_rtn;
var ls_ws_val,ls_ws_text,ls_ws_dbname,ls_custom_name;
//1.从qryObj中获取相关属性
//ls_ws_val=qryObj.attr("ws_val");
//ls_ws_text=qryObj.attr("ws_text");
ls_ws_dbname=qryObj.attr("ws_dbname");
ls_custom_name='ws_get'+ls_ws_dbname;
//2.判断是否有自定义取值函数,如果有则调用自定义函数,否则按照默认取值
func=_this.getCustomFunc(ls_custom_name);
if(!func)          
        {
        //3.按照默认取值(flag=0:取value,flag=1:取text)
        if(flag==0)
{
ls_rtn=qryObj.attr('ws_val');
}
else
{
ls_rtn=qryObj.attr('ws_text');
}
        }
        else
        {
        ls_rtn=func(qryObj,flag);
        }
        return ls_rtn;
},
/*
功能:设置TD的val或者text
算法:1.从qryObj中获取相关属性     
    2.判断是否有自定义取值函数,如果有则调用自定义函数,否则按照默认设置
    3.flag=0:设value,flag=1:设置text
*/
setTD:function(qryObj,val,flag)
{
var _this=this;
var func=null;
var ls_ws_dbname,ls_custom_name;
//1.从qryObj中获取相关属性
ls_ws_dbname=qryObj.attr("ws_dbname");
ls_custom_name='ws_set'+ls_ws_dbname;
//2.判断是否有自定义函数,如果有则调用自定义函数,否则按照默认方法
func=_this.getCustomFunc(ls_custom_name);
if(!func)          
        {
        //3.按照默认取值(flag=0:设value,flag=1:设text)
        if(flag==0)
{
if(qryObj.attr("tagName") == "TD")
{
qryObj.attr('ws_val',val);
}
else
{
//如果是checkbox
if(qryObj.attr("type")=='checkbox')
{
if(val.toString() == 'true')
{
qryObj.attr('checked','checked');
}
else
{
qryObj.removeAttr("checked");
}
qryObj.attr("ws_val",val);
}
else//如果是input或者select
{
qryObj.attr("value",val);
qryObj.attr("ws_val",val);
}
}
}
else
{
if(qryObj.attr("tagName") == "TD")
{
qryObj.attr('ws_text',val);//设置ws_text
qryObj.text(val);//设置td的显示内容
}
else
{
qryObj.attr('ws_text',val);//设置ws_text
}
}
        }
        else
        {
        func(qryObj,val,flag);
        }        
},
/*
功能:从编辑控件中获取val或者text
算法:1.从qryObj中获取相关属性     
    2.判断是否有自定义取值函数,如果有则调用自定义函数,否则按照默认取值
    3.flag=0:取value,flag=1:取text
*/
getEdit:function(qryObj,flag)
{
var _this=this;
var func=null;
var ls_rtn;
var ls_ws_val,ls_ws_text,ls_ws_dbname,ls_custom_name;
//1.从qryObj中获取相关属性
//ls_ws_val=qryObj.attr("ws_val");
//ls_ws_text=qryObj.attr("ws_text");
ls_ws_dbname=qryObj.attr("ws_dbname");
ls_custom_name='ws_getEdit'+ls_ws_dbname;
//2.判断是否有自定义取值函数,如果有则调用自定义函数,否则按照默认取值
func=_this.getCustomFunc(ls_custom_name);
if(!func)          
        {
        //3.按照默认取值(flag=0:取value,flag=1:取text)
        if(flag==0)
{
if(qryObj.attr("tagName") == "TD")
{
ls_rtn=qryObj.attr('ws_val');
}
else
{
//如果是checkbox
if(qryObj.attr("type")=='checkbox')
{
ls_rtn=qryObj.attr('checked');
}
else//如果是input或者select
{
ls_rtn=qryObj.attr("value");
}
}
}
else
{
if(qryObj.attr("tagName") == "TD")
{
ls_rtn=qryObj.text();
}
else
{
  switch(qryObj.attr("type"))
  {
  case 'checkbox':
    ls_rtn='';
    break
  case 'select-one':
    ls_rtn=qryObj.find("option:selected").text();
    break
  default:
    ls_rtn=qryObj.attr("value");
  }
}
}
        }
        else
        {
        ls_rtn=func(qryObj,flag);
        }
        return ls_rtn;
},
/*
功能:设置编辑控件的val或者text
算法:1.从qryObj中获取相关属性     
    2.判断是否有自定义函数,如果有则调用自定义函数,否则按照默认设置
    3.flag=0:设value,flag=1:设置text
*/
setEdit:function(qryObj,val,flag)
{
var _this=this;
var func=null;
var ls_ws_dbname,ls_custom_name;
//1.从qryObj中获取相关属性
ls_ws_dbname=qryObj.attr("ws_dbname");
ls_custom_name='ws_setEdit'+ls_ws_dbname;
//2.判断是否有自定义函数,如果有则调用自定义函数,否则按照默认方法
func=_this.getCustomFunc(ls_custom_name);
if(!func)          
        {
        //3.按照默认取值(flag=0:设value,flag=1:设text)
        if(flag==0)
{
if(qryObj.attr("tagName") == "TD")
{
qryObj.attr('ws_val',val);
}
else
{
//如果是checkbox
if(qryObj.attr("type")=='checkbox')
{
if(val == 'true')
{
qryObj.attr('checked','checked');
}
else
{
qryObj.removeAttr("checked");
}
qryObj.attr("ws_val",val);
}
else//如果是input或者select
{
qryObj.attr("value",val);
qryObj.attr("ws_val",val);
}
}
}
else
{
if(qryObj.attr("tagName") == "TD")
{
qryObj.attr('ws_text',val);//设置ws_text
qryObj.text(val);//设置td的显示内容
}
else
{
qryObj.attr('ws_text',val);//设置ws_text
}
}
        }
        else
        {
        func(qryObj,val,flag);
        } 
},
/*
功能描述:把this.editTr上的控件的值写到TD上
算法:1.获取界面tr界面(非编辑)元素
2.获取editTr上属性为[ws_ctrl='true']的元素
3.将属性的值设置到tr界面(非编辑)上  
*/
setValToTD:function()
{
var _this=this;
var ls_ws_ctrl_val,ls_ws_ctrl_txt;//editTr上ws_ctrl控件的值和txt
var ls_ws_dbname;
var qryObj=null;
//1.获取界面tr界面(非编辑)元素
var tds=_this.private_tr.find("[ws_dbname]");//包含有ws_dbname属性的元素
//2.获取editTr上属性为[ws_ctrl='true']的元素
$.each(_this.private_editTr.find("[ws_ctrl='true']"),function(k,v){
//2.1从编辑控件上获取val和txt
ls_ws_ctrl_val=_this.getEdit($(v),0);
ls_ws_ctrl_txt=_this.getEdit($(v),1);
//2.2设置非编辑界面的val和txt
qryObj=$(tds[k]);
_this.setTD(qryObj,ls_ws_ctrl_val,0);
_this.setTD(qryObj,ls_ws_ctrl_txt,1);
});
},
/*
功能:把表格上的td上的值写到this.editTr的控件上
算法:
1.获取this.editTr的控件
2.获取tr下td的ws_val的值,设置到editTr中td的ws_val和控件的value上  
*/
setValToEditCtrl:function()
{
var _this=this;
var ls_val,ls_txt;//td上的ws_val和text
var lc_ctrl,lc_td;
//1.获取this.editTr的控件
var editTr_ctrls=_this.private_editTr.find("[ws_ctrl='true']");
//2.获取tr下td的ws_val的值,设置到editTr中td的ws_val和控件的value上
var tds=_this.private_tr.find("[ws_dbname]");
$.each(tds,function(k,v){
//2.1从界面上取值---------------------------------此处要提供虚函数:从界面(非编辑)上取值
lc_td=$(v);
ls_val=_this.getTD(lc_td,0);//从界面(非编辑)取值
ls_txt=_this.getTD(lc_td,1);//从界面(非编辑)取text
//2.2设置到editTr中控件的value上------------------此处要提供虚函数:将从从界面(非编辑)上取值的值设置到编辑行的控件上
lc_ctrl =$(editTr_ctrls[k]);
_this.setEdit(lc_ctrl,ls_val,0);//设置编辑控件的值
_this.setEdit(lc_ctrl,ls_txt,1);//设置编辑控件的text
});
},
/*
功能:根据界面上显示的行顺序号获取rowIndex
*/
getRowIndex:function(showRow)
{
var _this=this;
var showTr=_this.private_table.find("tbody tr[ws_edit !='true']:eq("+showRow+")");
if(showTr.html()==null)
{
alert('此行不存在');
return -1;
}
return showTr.attr('rowIndex');
},
/*
功能:获取当前正在编辑的行号
*/
GetRow:function()
{
var _this=this;
var showTr=_this.private_tr;
return showTr.attr('sectionRowIndex');
},
/*
功能:编辑某一行
算法:1.保存上次编辑的行的数据,显示上次编辑时隐藏的行
2.设置新的编辑的行
3.焦点设置到第一个input上
参数:row:rowIndex
*/
EditRow:function(row)
{
var _this=this;
//1.保存上次编辑的行的数据,显示上次编辑时隐藏的行
_this.setLastTr();
//2.设置新的编辑的行,将新编的行隐藏,数据写到编辑行上,将编辑的界面放到隐藏行的后面
_this.setCurrTr(row);
//3.焦点设置到第一个input上
_this.private_editTr.find("input[ws_dbname]:eq(0)").focus();
},
//----------------------------------------------
/*
功能:删除一行
参数:row:界面上的序号(不是rowIndex)
算法:1.判断是否有输入参数
    2.如果没有输入参数则取当前编辑行的rowIndex
    3.如果有输入参数则转换为rowIndex
    4.如果删除的行是正在编辑的行则编辑的行跳转到下一行:nextTr
    5.如果下一行为null,则取上一行:nextTr
    6.如果通过4.5获取nextTr不为null则,此行设置为编辑行,否则什么也不做
    7.删除要删除的行
    8.行数变化时调整编辑行是否显示
*/
DelRow:function(row)
{
var _this=this;
var li_curr,li_del;
var nextTr=null,li_nextTr;
//1.判断是否有输入参数
if(!row)
{
//2.如果没有输入参数则取当前编辑行的rowIndex
row=_this.private_tr.attr('rowIndex');
}
else
{
//3.如果有输入参数则转换为rowIndex
row=_this.getRowIndex(row);
}
//获取要删除的行
var deltr=_this.private_table.find("tbody tr[rowIndex='"+row+"']");//
li_curr=_this.private_tr.attr('rowIndex');
li_del=deltr.attr('rowIndex');
//4.如果删除的行是正在编辑的行则编辑的行跳转到下一行:nextTr
if(li_del==li_curr)
{
li_nextTr = li_curr + 2;
nextTr=_this.private_table.find("tbody tr[rowIndex='"+li_nextTr+"']");
if(nextTr.html()==null)
{
// 5.如果下一行为null,则取上一行:nextTr
li_nextTr = li_curr - 1;
nextTr=_this.private_table.find("tbody tr[rowIndex='"+li_nextTr+"']");
}
//6.如果通过4.5获取nextTr不为null则,此行设置为编辑行,否则什么也不做
if(nextTr.html()!=null)
{
_this.EditRow(li_nextTr);
}
}
//7.删除要删除的行
deltr.remove();
//8.行数变化时调整编辑行是否显示
_this.adjustUi();
},
/*
功能:添加一行
算法:1.判断tbody可见行数
    2.如果为0则插在隐藏的编辑行之前
    3.如果不为0则插在可见行最后一行之后
    4.编辑新插入的行
    5.返回可见行的行号
*/
AddRow:function()
{
var _this=this;
var l_newtr=null;
//1.判断tbody可见行数
var li_length=_this.private_table.find("tbody tr[ws_edit !='true']").length;
if(li_length==0)
{
//2.如果为0则插在隐藏的编辑行之前
l_newtr=_this.private_templateTr.clone(true).insertBefore(_this.private_editTr);
}
else
{
//3.如果不为0则插在可见行最后一行之后
var l_last=_this.private_table.find("tbody tr[ws_edit !='true']").last();
l_newtr=_this.private_templateTr.clone(true).insertAfter(l_last);
}
//4.编辑新插入的行
_this.EditRow(l_newtr.attr('rowIndex'));
//行数变化时调整编辑行是否显示
_this.adjustUi();
li_length=_this.private_table.find("tbody tr[ws_edit !='true']").length;
return li_length - 1;
},
/*
功能:修改某行某列的值或text
参数:row:界面上的序号(不是rowIndex)
    colNmae:ws_dbname
    val:值或者text
    flag:0:表示值,1:表示text
算法:1.根据序号获取rowIndex  
    2.根据rowIndex和dbname获取qryObj对象
    3.调用setTD:function(qryObj,val,flag)方法设置数据
    4.如果设置的行是当前编辑的行要把值设置到编辑控件上_this.setEdit(qryObj,val,flag);
*/
SetItem:function(row,dbname,val,flag)
{
var _this=this;
var qryObj=null;
var li_curr;
//1.根据序号获取rowIndex
row=_this.getRowIndex(row);
   //2.根据rowIndex和dbname获取qryObj对象
   qryObj=_this.private_table.find("tbody tr[rowIndex='"+row+"']").find("[ws_dbname='"+dbname+"']");    
   //3.调用setTD:function(qryObj,val,flag)方法设置数据
   _this.setTD(qryObj,val,flag);    
   //4.如果设置的行是当前编辑的行要把值设置到编辑控件上
   li_curr=_this.private_tr.attr('rowIndex');    
   if(li_curr==row)
   {    
    //获取编辑控件上的qryObj对象
    qryObj=_this.private_editTr.find("[ws_dbname='"+dbname+"']");
    _this.setEdit(qryObj,val,flag);    
   }
},
/*
功能:获取某行某列的值或text
参数:row:界面上的序号(不是rowIndex)
    colNmae:ws_dbname
    flag:0:表示值,1:表示text
算法:1.根据序号获取rowIndex
    2.判断取值的行是不是当前编辑的行
    3.如果是当前正在编辑的行则从编辑控件上取值
    4.如果不是正在编辑的行则从非编辑界面上取值
*/
GetItem:function(row,dbname,flag)
{
var _this=this;
var qryObj=null;
var li_curr;
var ls_rtn=null;
//1.根据序号获取rowIndex
row=_this.getRowIndex(row);
//2.判断取值的行是不是当前编辑的行
li_curr=_this.private_tr.attr('rowIndex');    
   if(li_curr==row)
   {
    //3.如果是当前正在编辑的行则从编辑控件上取值
    qryObj=_this.private_editTr.find("[ws_dbname='"+dbname+"']");
    ls_rtn=_this.getEdit(qryObj,flag);
   }
   else
   {
    //4.如果不是正在编辑的行则从非编辑界面上取值
    qryObj=_this.private_table.find("tbody tr[rowIndex='"+row+"']").find("[ws_dbname='"+dbname+"']");
    ls_rtn=_this.getTD(qryObj,flag);
   }
   return ls_rtn;
},
/*
功能:计算合计字段的值
参数:dbname:ws_dbname
算法:1.判断是否有输入参数
    2.没有输入参数则计算全部合计字段--暂时没有实现
    3.有输入参数则计算指定的合计字段
*/
SumCol:function(dbname)
{
var _this=this;
var ldc_sum=0.00;
//1.判断是否有输入参数
if(!dbname)
{
//2.没有输入参数则计算全部合计字段--暂时没有实现
return ;
}
else
{
//3.有输入参数则计算指定的合计字段
var tds=_this.private_table.find("tbody tr[ws_edit !='true']").find("[ws_dbname='"+dbname+"']");
$.each(tds,function(k,v){
ldc_sum+=parseFloat($(v).attr('ws_val'));
});
var sumTd=_this.private_sumTr.find("[ws_dbname='"+dbname+"']");
sumTd.text(ldc_sum);
}
},
/*
功能:单据某行就编辑此行
算法:在非编辑行和模版上上添加单击事件,单击时编辑此行
    原因:非编辑行添加事件是因为初始化有数据是,非编辑界面行上是没有事件的
         模版行上添加事件是因为后续添加行都是模版行clone(true)克隆出来的,所以在模版上添加事件,就等于给后续添加的行上添加了事件
*/
ClickTrEditTr:function()
{
var _this=this;
//在非编辑行和模版上上添加单击事件,单击时编辑此行
_this.private_table.find("tbody tr[ws_edit !='true'],thead tr[ws_template='true']").bind('click',function(){
                var l_this=this;//此处的this是指单击到的某行                 
                _this.EditRow($(l_this).attr('rowIndex'));                                                
            });
},
/*
功能:获取下一个可编辑的控件的dbname
*/
getNextEditCtrlDbname:function(dbname)
{
var _this=this;
var ls_rtn="";
var li_cnt=_this.private_dbname.length;
for(var i=0;i<li_cnt;i++)
{
if(_this.private_dbname[i]==dbname)
{
if(i < (li_cnt - 1))
{
ls_rtn=_this.private_dbname[i + 1];
}
else
{
ls_rtn="";
}
break;
}
}
return ls_rtn;
},
/*
功能://在编辑模版行上设置回车、left、right、up、down事件
在编辑模版行的input上设置回车、left、right、up、down事件
*/
KeyUpNav:function()
{
var _this=this;
_this.private_editTr.find("[ws_ctrl='true'][tagName!='TD']").bind('keyup',function(event){
                var l_this=this; 
                var li_curr_rowIndex=_this.private_tr.attr("rowIndex");
                var li_next_rowIndex;                             
                var ls_dbname=$(l_this).attr('ws_dbname');
                var nextTr=null;
                var ls_nextdbname="";                
                
                var keycode = event.which;
                //console.info(keycode);
                switch(keycode)
                {
                    case 13://回车  
                    ls_nextdbname=_this.getNextEditCtrlDbname(ls_dbname);
                    if(ls_nextdbname=="")
                    {
                    //跳到下一行
                    li_next_rowIndex=li_curr_rowIndex + 2;
                    nextTr=_this.private_table.find("tbody tr[rowIndex='"+li_next_rowIndex+"']");
if(nextTr.html()!=null)
{
_this.EditRow(li_next_rowIndex);
}
                    }
                    else
                    {
                    //跳到下一个编辑控件
                    _this.private_editTr.find("[ws_dbname='"+ls_nextdbname+"']").focus();
                    }
                        break;
                    case 37://left
                        break;
                    case 39://right
                        break;
                    case 38://up
                    li_next_rowIndex=li_curr_rowIndex - 1;
                    nextTr=_this.private_table.find("tbody tr[rowIndex='"+li_next_rowIndex+"']");
if(nextTr.html()!=null)
{
_this.EditRow(li_next_rowIndex);
_this.private_editTr.find("[ws_dbname='"+ls_dbname+"']").focus();
}
                        break;
                    case 40://down
                    li_next_rowIndex=li_curr_rowIndex + 2;
                    nextTr=_this.private_table.find("tbody tr[rowIndex='"+li_next_rowIndex+"']");
if(nextTr.html()!=null)
{
_this.EditRow(li_next_rowIndex);
_this.private_editTr.find("[ws_dbname='"+ls_dbname+"']").focus();
}
                        break;
                    case 9://tab                    
                        break;
                }               
            });
}

}; 

 4、源文件

原文地址:https://www.cnblogs.com/kuailewangzi1212/p/2619237.html