基于Bootstrap与jQuery实现可编辑表格的插件详解

作者:阿沐

时间:2026-10-30

浏览:241

本文介绍基于Bootstrap和jQuery开发的editTable.js插件,支持表格行的编辑、添加与删除操作。详细解析了operatePos、handleFirst、editableCols等配置参数,以及saveCallback、addCallback等回调函数的用法,帮助开发者快速实现后台管理系统的表格交互功能。

文章目录

editTable.js 插件概述与配置参数

editTable.js 是一个基于 jQuery 的插件,旨在为 Bootstrap 表格提供行编辑、新增行及删除行的功能。该插件支持通过配置参数来定制行为,例如指定操作列的位置等。

operatePos 参数用于定义操作按钮所在的列索引,索引从 0 开始计数。若设置为 -1,则默认将最后一列作为操作列。此列中包含编辑当前行、在当前行下方添加新行以及删除当前行的功能按钮。

handleFirst 参数用于控制表格的第一行是否允许进行编辑操作。设置为 true 表示第一行可编辑,设置为 false 则不可编辑。

edit、save、cancel、add、confirm、del 这六个参数分别对应界面上显示的操作文本。默认情况下,它们分别显示为“编辑”、“保存”、“取消”、“添加”、“确认”和“删除”。开发者可根据需要自定义这些显示文字。

editableCols 参数用于指定哪些列允许被编辑,索引同样从 0 开始,以数组形式传入,例如 [1, 2] 表示第 2 和第 3 列可编辑。若传入字符串 "all",则表示所有列均可编辑。需要注意的是,程序会自动排除已设置为操作列的列,即使它们在 editableCols 列表中。

order 参数用于定义表格中显示的操作类型及其排列顺序。该参数接受一个数组,元素可以是 edit、add 或 del。若传入空数组,默认仅显示编辑操作,等同于 ["edit"]。若未指定 order 参数,则默认显示所有功能(编辑、添加、删除),顺序为编辑 -> 添加 -> 删除。开发者可以自定义顺序,例如 ["add", "edit", "del"]。

saveCallback 是在启用编辑功能时,用户点击“保存”按钮后触发的回调函数。用户需在使用编辑功能时配置此参数。在该函数中,可以通过 ajax 将编辑后的数据(存储在 data 数组中)提交至服务器。当 ajax 保存成功时,应调用回调函数中的 isSuccess 方法,以将界面状态从可编辑切换为不可编辑。

addCallback 和 delCallback 的作用机制与 saveCallback 类似,分别对应于“添加”和“删除”操作完成后的回调处理。

插件核心代码实现

editTable.js 插件的核心代码实现如下:


/** 
 * Created by DreamBoy on 2016/4/19. 
 */ 
$(function() { 
 $.fn.handleTable = function (options) { 
 //1.Settings 初始化设置 
 var c = $.extend({ 
  "operatePos" : -1, //-1表示默认操作列为最后一列 
  "handleFirst" : false, //第一行是否作为操作的对象 
  "edit" : "编辑", 
  "save" : "保存", 
  "cancel" : "取消", 
  "add" : "添加", 
  "confirm" : "确认", 
  "del" : "删除", 
  "editableCols" : "all", //可编辑的列,从0开始 
  //"pos" : 0, //位置位于该列开头,还是结尾(左侧或右侧) 
  "order" : ["edit", "add", "del"], //指定三个功能的顺序 
  "saveCallback" : function(data, isSuccess) { //这里可以写ajax内容,用于保存编辑后的内容 
  //data: 返回的数据 
  //isSuccess: 方法,用于保存数据成功后,将可编辑状态变为不可编辑状态 
  //ajax请求成功(保存数据成功),才回调isSuccess函数(修改保存状态为编辑状态) 
  }, 
  "addCallback" : function(data, isSuccess) { 
  //isSuccess: 方法,用于添加数据成功后,将可编辑状态变为不可编辑状态 
  }, 
  "delCallback" : function(isSuccess) { 
  //isSuccess: 方法,用于删除数据成功后,将对应行删除 
  } 
 }, options); 
 
 //表格的列数 
 var colsNum = $(this).find('tr').last().children().size(); 
 
 //2.初始化操作列,默认为最后一列,从1算起 
 if(c.operatePos == -1) { 
  c.operatePos = colsNum - 1; 
 } 
 
 //3.获取所有需要被操作的行 
 var rows = $(this).find('tr'); 
 if(!c.handleFirst) { 
  rows = rows.not(":eq(0)"); 
 } 
 
 //4.获取放置“操作”的列,通过operatePos获取 
 var rowsTd = []; 
 var allTd = rows.children(); 
 for(var i = c.operatePos; i <= allTd.size(); i += colsNum) { 
  if(c.handleFirst) { //如果操作第一行,就把放置操作的列内容置为空 
  allTd.eq(i).html(""); 
  } 
  rowsTd.push(allTd.eq(i)[0]); 
 } 
 
 //6.修改设置 order 为空时的默认值 
 if(c.order.length == 0) { 
  c.order = ["edit"]; 
 } 
 
 //7.保存可编辑的列 
 var cols = getEditableCols(); 
 
 //8.初始化链接的构建 
 var saveLink = "", cancelLink = "", editLink = "", addLink = "", confirmLink = "", delLink = ""; 
 initLink(); 
 
 //9.初始化操作 
 initFunc(c.order, rowsTd); 
 
 /** 
  * 创建操作链接 
  */ 
 function createLink(str) { 
  return "<a href=\"javascript:void(0)\" style=\"margin:0 3px\">" + str + "</a>"; 
 } 
 /** 
  * 初始各种操作的链接 
  */ 
 function initLink() { 
  for(var i = 0; i < c.order.length; i++) { 
  switch (c.order[i]) { 
   case "edit": 
   //“编辑”链接 
   editLink = createLink(c.edit); 
   saveLink = createLink(c.save); 
   cancelLink = createLink(c.cancel); 
   break; 
   case "add": 
   //“添加”链接 
   addLink = createLink(c.add); 
   //“确认”链接 
   confirmLink = createLink(c.confirm); 
   //“取消”链接 
   cancelLink = createLink(c.cancel); 
   break; 
   case "del": 
   //“删除”链接 
   delLink = createLink(c.del); 
   break; 
  } 
  } 
 } 
 
 /** 
  * 获取可进行编辑操作的列 
  */ 
 function getEditableCols() { 
  var cols = c.editableCols; 
  if($.type(c.editableCols) != "array" && cols == "all") { //如果是所有列都可以编辑的话 
  cols = []; 
  for(var i = 0; i < colsNum; i++) { 
   if(i != c.operatePos) { //排除放置操作的列 
   cols.push(i); 
   } 
  } 
  } else if($.type(c.editableCols) == "array") { //有指定选择编辑的列的话需要排序放置“编辑”功能的列 
  var copyCols = []; 
  for(var i = 0; i < cols.length; i++) { 
   if(cols[i] != c.operatePos) { 
   copyCols.push(cols[i]); 
   } 
  } 
  cols = copyCols; 
  } 
  return cols; 
 } 
 
 /** 
  * 根据c.order参数设置提供的操作 
  * @param func 需要设置的操作 
  * @param cols 放置操作的列 
  */ 
 function initFunc(func, cols) { 
  for(var i = 0; i < func.length; i++) { 
  var o = func[i]; 
  switch(o) { 
   case "edit": 
   createEdit(cols); 
   break; 
   case "add": 
   createAdd(cols); 
   break; 
   case "del": 
   createDel(cols); 
   break; 
  } 
  } 
 } 
 
 /** 
  * 创建“编辑一行”的功能 
  * @param operateCol 放置编辑操作的列 
  */ 
 function createEdit(operateCol) { 
  $(editLink).appendTo(operateCol).on("click", function() { 
  if(replaceQuote($(this).html()) == replaceQuote(c.edit)) { //如果此时是编辑状态 
   toSave(this); //将编辑状态变为保存状态 
  } else if(replaceQuote($(this).html()) == replaceQuote(c.save)) { //如果此时是保存状态 
   var p = $(this).parents('tr'); //获取被点击的当前行 
   var data = []; //保存修改后的数据到数据内 
   for(var i = 0; i < cols.length; i++) { 
   var tr = p.children().eq(cols[i]); 
   var inputValue = tr.children('input').val(); 
   data.push(inputValue); 
   } 
 
   $this = this; //此时的this表示的是 被点击的 编辑链接 
   c.saveCallback(data, function() { 
   toEdit($this, true); 
   }); 
  } 
  }); 
  var afterSave = []; //保存修改前的信息,用于用户点击取消后的数值返回操作 
  //修改为“保存”状态 
  function toSave(ele) { 
  $(ele).html(c.save); //修改为“保存” 
  $(ele).after(cancelLink); //添加相应的取消保存的“取消链接” 
  $(ele).next().on('click', function() { 
   //if($(this).html() == c.cancel.replace(eval("/\'/gi"),"\"")) { 
   toEdit(ele, false); 
   //} 
  }); 
 
  //获取被点击编辑的当前行 tr jQuery对象 
  var p = $(ele).parents('tr'); 
 
  afterSave = []; //清空原来保存的数据 
  for(var i = 0; i < cols.length; i++) { 
   var tr = p.children().eq(cols[i]); 
   var editTr = "<input type=\"text\" class=\"form-control\" value=\"" + tr.html() + "\"/>"; 
   afterSave.push(tr.html()); //保存未修改前的数据 
   tr.html(editTr); 
  } 
  } 
  //修改为“编辑”状态(此时,需要通过isSave标志判断是 
  // 因为点击了“保存”(保存成功)变为“编辑”状态的,还是因为点击了“取消”变为“编辑”状态的) 
  function toEdit(ele, isSave) { 
  $(ele).html(c.edit); 
  if(replaceQuote($(ele).next().html()) == replaceQuote(c.cancel)) { 
   $(ele).next().remove(); 
  } 
 
  var p = $(ele).parents('tr'); 
 
  for(var i = 0; i < cols.length; i++) { 
   var tr = p.children().eq(cols[i]); 
   var value; 
   if(isSave) { 
   value = tr.children('input').val(); 
   } else { 
   value = afterSave[i]; 
   } 
 
   tr.html(value); 
  } 
  } 
 } 
 
 /** 
  * 创建“添加一行”的功能 
  * @param operateCol 
  */ 
 function createAdd(operateCol) { 
  $(addLink).appendTo(operateCol).on("click", function() { 
  //获取被点击“添加”的当前行 tr jQuery对象 
  var p = $(this).parents('tr'); 
  var copyRow = p.clone(); //构建新的一行 
  var input = "<input type=\"text\"/>"; 
  var childLen = p.children().length; 
  for(var i = 0; i < childLen; i++) { 
   copyRow.children().eq(i).html("<input type=\"text\" class=\"form-control\"/>"); 
  } 
 
  //最后一行是操作行 
  var last = copyRow.children().eq(c.operatePos); 
  last.html(""); 
  p.after(copyRow); 
 
  var confirm = $(confirmLink).appendTo(last).on("click", function() { 
   var data = []; 
   for(var i = 0; i < childLen; i++) { 
   if(i != c.operatePos) { 
    var v = copyRow.children().eq(i).children("input").val(); 
    data.push(v); 
    copyRow.children().eq(i).html(v); 
   } 
   } 
   c.addCallback(data, function() { 
   last.html(""); 
   //------------这里可以进行修改 
   initFunc(c.order, last); 
   }); 
  }); 
 
  $(confirm).after(cancelLink); //添加相应的取消保存的“取消链接” 
  $(confirm).next().on('click', function() { 
   copyRow.remove(); 
  }); 
  }); 
 } 
 
 /** 
  * 创建“删除一行”的功能 
  * @param operateCol 
  */ 
 function createDel(operateCol) { 
  $(delLink).appendTo(operateCol).on("click", function() { 
  var _this = this; 
  c.delCallback(function() { 
   $(_this).parents('tr').remove(); 
  }); 
  }); 
 } 
 
 /** 
  * 将str中的单引号转为双引号 
  * @param str 
  */ 
 function replaceQuote(str) { 
  return str.replace(/\'/g, "\""); 
 } 
 }; 
}); 

使用注意事项与示例演示

在实际使用中,需注意以下两点:首先,目标表格必须包含可被 jQuery 选择器选中的标识;其次,在放置“操作”按钮的列中,必须预留一个空的 <td></td> 标签,用于渲染操作按钮。

以下是具体的使用示例:

项目的目录结构如下:

editTable.js 插件概述与配置参数

主文件 index.html 的代码示例:


<!DOCTYPE html> 
<html lang="en"> 
<head> 
 <meta charset="UTF-8"> 
 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 
 <meta name="viewport" content="width=device-width, initial-scale=1"> 
 <title>表格</title> 
 <link rel="stylesheet" href="css/bootstrap.min.css" type="text/css"> 
 <!--<link href="assets/font-awesome/css/font-awesome.css" rel="stylesheet" />--> 
 <!--[if lt IE 9]> 
 <script src="js/html5shiv.js"></script> 
 <script src="js/respond.min.js"></script> 
 <![endif]--> 
</head> 
<body> 
 <div class="container"> 
 <div class="bs-example" data-example-id="hoverable-table"> 
  <table class="table table-hover editable"> 
  <thead> 
  <tr> 
   <th>#</th> 
   <th>Test</th> 
   <th>First Name</th> 
   <th>Last Name</th> 
   <th>Username</th> 
   <th>Operations</th> 
  </tr> 
  </thead> 
  <tbody> 
  <tr> 
   <th scope="row">1</th> 
   <td></td> 
   <td>Mark</td> 
   <td>Otto</td> 
   <td>@mdo</td> 
   <td><!--<a href="javascript:void(0)" class="edit"></a>--></td> 
  </tr> 
  <tr> 
   <th scope="row">2</th> 
   <td></td> 
   <td>Jacob</td> 
   <td>Thornton</td> 
   <td>@fat</td> 
   <td><!--<a href="javascript:void(0)" class="edit"></a>--></td> 
  </tr> 
  <tr> 
   <th scope="row">3</th> 
   <td></td> 
   <td>Larry</td> 
   <td>the Bird</td> 
   <td>@twitter</td> 
   <td><!--<a href="javascript:void(0)" class="edit"></a>--></td> 
  </tr> 
  </tbody> 
  </table> 
 </div> 
 </div> 
 
 <script src="js/jquery-1.11.1.min.js"></script> 
 <script src="js/bootstrap.min.js"></script> 
 <script src="editTable.js"></script> 
 <script> 
 $(function() { 
  //$('.edit').handleTable({"cancel" : "<span class='glyphicon glyphicon-remove'></span>"}); 
  $('.editable').handleTable({ 
  "handleFirst" : true, 
  "cancel" : " <span class='glyphicon glyphicon-remove'></span> ", 
  "edit" : " <span class='glyphicon glyphicon-edit'></span> ", 
  "add" : " <span class='glyphicon glyphicon-plus'></span> ", 
  "save" : " <span class='glyphicon glyphicon-saved'></span> ", 
  "confirm" : " <span class='glyphicon glyphicon-ok'></span> ", 
  "operatePos" : -1, 
  "editableCols" : [2,3,4], 
  "order": ["add","edit"], 
  "saveCallback" : function(data, isSuccess) { //这里可以写ajax内容,用于保存编辑后的内容 
   //data: 返回的数据 
   //isSucess: 方法,用于保存数据成功后,将可编辑状态变为不可编辑状态 
   var flag = true; //ajax请求成功(保存数据成功),才回调isSuccess函数(修改保存状态为编辑状态) 
   if(flag) { 
   isSuccess(); 
   alert(data + " 保存成功"); 
   } else { 
   alert(data + " 保存失败"); 
   } 
 
   return true; 
  }, 
  "addCallback" : function(data,isSuccess) { 
   var flag = true; 
   if(flag) { 
   isSuccess(); 
   alert(data + " 增加成功"); 
   } else { 
   alert(data + " 增加失败"); 
   } 
  }, 
  "delCallback" : function(isSuccess) { 
   var flag = true; 
   if(flag) { 
   isSuccess(); 
   alert("删除成功"); 
   } else { 
   alert("删除失败"); 
   } 
  } 
  }); 
 }); 
 </script> 
</body> 
</html> 

运行后的初始界面效果如下:

editTable.js 插件概述与配置参数

点击“编辑”按钮后,表格进入编辑模式:

用户可以直接在单元格中修改数据:

editTable.js 插件概述与配置参数

修改完成后,点击“保存”按钮提交更改:

editTable.js 插件概述与配置参数

editTable.js 插件概述与配置参数

点击“添加”按钮,可以在表格末尾新增一行:

editTable.js 插件概述与配置参数

在新添加的行中输入所需数据:

editTable.js 插件概述与配置参数

点击“确认”按钮完成添加操作:

editTable.js 插件概述与配置参数

editTable.js 插件概述与配置参数

如果不需要新增的行,可以点击“取消”按钮移除多余的行:

editTable.js 插件概述与配置参数

如果大家还想深入学习,可以点击这里进行学习,再为大家附3个精彩的专题:

Bootstrap学习教程

Bootstrap实战教程

Bootstrap插件使用教程

以上就是本文的全部内容,希望对大家的学习有所帮助。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章