动态添加html 页签"/>
js 动态添加html 页签
目录
一、情形:
二、处理:
三、实现:
四、总结:
一、情形:
7月份写的那版多页签切换列表是基于 button 标签 ,而且当前操作的永远都是同一个页签,通过点击事件刷新数据显示的。图示如下:
这就产生了几个问题:
1. 页签和对应页面的关联不够明显 ;
2. 当前页面数据没保存就点击下一个页签,当前页面数据丢失;
3、同时没法存在多个空的页签;
发现问题之后,第一时间脑袋想起以前面试过得问题:已经写完的代码你会去经常测试改进吗?虽然当时回答的是 会。可是实际上我从未主动去改进自己的代码,都是出了问题才去改。既然现在发现了,那就改吧。着重处理 发现的3个问题。
二、处理:
1、当前之重就是 处理 多个页面切换的问题,因为是后台传来数据,前台动态生成多个页面以及对应的表格。要处理每个页面的增删改查,就是要让各个页面和对应表格的id 不重复,众id就用随机数+当前时间 唯一生成。
2、页签的拼接 不能用写死<ui> </ui>在里面拼接li,我试过 ,li 会拼在 </ul> 后而不是 <ul>里 ,这让我很郁闷,于是上网找了个组件,把组件拼接代码 粘出来,放在js文件里,引入当前页面,需要拼接的时候调用就行,代码如下:
$.fn.addTabs = function (options) {//判断是否已存在指定ID的tab/*if ($("#" + options.id).length > 0) {throw "当前ID的Tab已存在.";}*/var snumber=options.sheetNumber;//构建li元素var li = $("<li />", {"class":"confli","id": options.id + "_li",});//构建a元素var a = $("<a />", {"data-toggle":"tab","href": "#" + options.id,"aria-expanded":"true","text": options.title,"click": function (e) {// e.preventDefault();$(this).tab("show");},});//合并li和a元素li.append(a);var ul = $(this);//合并ul和li元素ul.append(li);//添加完成显示当前li$(li).tab("show");//构建div内容元素var div = $("<div />", {"id": options.id,"class": "tab-pane fade in active",});//兼容纯文本和html片段typeof options.content == "string" ? div.append(options.content) : div.html(options.content);//var container = $(".tab-content");var container = $("#tab-content");container.append(div);//添加完成后显示div$(div).siblings().removeClass("active");
}
3、拼接 每个页面要有: li页签 ,div , a 标签
li 里 拼接 a标签 -->跳转到对应的div ,展示对应的handsontable 表格。
div 还有 对应的 增 删 改 按钮,方法只写一个,只要传值对应的id 就好。
4、页签的名字 改成 input 输入框 ,保持和页签联动。增删改 按钮变成 图标。
最后 后的页面 是这样:
三、实现:
1、点开页面,数据初次加载,需要从数据库 查询有几个页签,以及拼接展示页签的数据:
//初始化 sheet页表格
function initSheetTables(Pid){var confNames=[];$.ajax({async : false,cache:false,dataType:'json',type : 'POST', url : '<%=basePath%>/project/findConfNameByPid', data :{'projectVersionResourceID':Pid},success: function(result){confNames = result;if(confNames.length==0){//数据库为空 添加空的列表var randonNumber=Math.floor(Math.random()*999999);var count=new Date().getTime()+randonNumber;var liLength = $("#conf_ui li").length+1;var tableid="table_"+count;var inputid="configuration_"+count+"_input";var divs= '<div id="caseListFieldsDiv" class="col-xs-12">'+'<div class="input-group input-group-count" style="float:right;top:18px;" >'+'<div class="input-icon-group PingFangSC">'+'<div class="input-group" >'+'<span class=" addon-span pingFangSC-drawer-text pingFangSC-Typeface-r" >'+'<i class="localIcon icon-jia" id="conf_add" onClick="addConfs('+count+')" title="添加行"></i>'+' <i class="localIcon icon-shanchu" id="conf_del" onClick="delRows('+count+')" title="删除行" ></i>'+' <i class="localIcon icon-zai " id="conf_adds" onClick="saveMicroserviceConfigFun('+count+')" title="保存文件"></i>'+'</span>'+'</div>'+'</div>'+'</div>'+'<div id="microservicName" class="whole-margin-b">'+'<label for='+inputid+' class="divlabel-control">'+'<span style="color:red">*</span><span class="pingFangSC-drawer-text pingFangSC-Typeface-r">配置文件名称:</span> '+'</label>'+'<input id='+inputid+' class="divinput-control pingFangSC-drawer-text pingFangSC-Typeface-r" value="" onchange="changeSheetName(this)" />'+'</div>'+'<div id='+tableid+' class="table-content handsontable pingFangSC-table"></div>'+'</div> ';var tabs = $("#sheetDiv ul.nav-tabs");tabs.addTabs({"id": "configuration_" + count,"title": "新建配置文件-" + liLength,"sheetNumber":count,"content": divs});showtables(count);}else{//每次加载清空 html 重新加载$("#conf_ui").html("");for(var i=0;i<confNames.length;i++){confName=confNames[i];var tabs = $("#sheetDiv ul.nav-tabs");//id 唯一var randonNumber=Math.floor(Math.random()*999999);var count=new Date().getTime()+randonNumber;var tableid="table_"+count;var inputid="configuration_"+count+"_input";var divs= '<div id="caseListFieldsDiv" class="col-xs-12">'+'<div class="input-group input-group-count" style="float:right;top:18px;" >'+'<div class="input-icon-group PingFangSC">'+'<div class="input-group" >'+'<span class=" addon-span pingFangSC-drawer-text pingFangSC-Typeface-r" >'+'<i class="localIcon icon-jia" id="conf_add" onClick="addConfs('+count+')" title="添加行"></i>'+' <i class="localIcon icon-shanchu" id="conf_del" onClick="delRows('+count+')" title="删除行" ></i>'+' <i class="localIcon icon-zai " id="conf_adds" onClick="saveMicroserviceConfigFun('+count+')" title="保存文件"></i>'+'</span>'+'</div>'+'</div>'+'</div>'+'<div id="microservicName" class="table-content">'+'<label for='+inputid+' class="divlabel-control">'+'<span style="color:red">*</span><span class="pingFangSC-drawer-text pingFangSC-Typeface-r">配置文件名称:</span> '+'</label>'+'<input id='+inputid+' class="divinput-control" value="'+confName+'" onchange="changeSheetName(this)" />'+'</div>'+'<div id='+tableid+' class="table-content handsontable pingFangSC-table"></div>'+'</div> ';var content=divs.replace(new RegExp("microserviceTable","g"),tableid);tabs.addTabs({"id": "configuration_" + count,"title": confName,"sheetNumber":count,"content": content});//为每个页面表格 初始化 赋值showtables(count);initConfigTabData("table_"+count,confName);}/* if(confNames.length>0){initConfigTabData("table_"+(confNames.length-1),confName);} */}}});
}
2、之后 的增加 ,的删除 保存 功能 ,需要同步;两个地方,当前表格id,当前页签id 。
这三个id 都有关联:
先 生成随机数+时间: var count=new Date().getTime()+Math.floor(Math.random()*999999);
之后 li 的ld 都可以 用count 拿到 ,这样就可操作 对应的数据:
li_id :"configuration_"+count+"_li";
table_id="table_"+count;
inputid="configuration_"+count+"_input";
比如 :删除一行时,需要先将当前生成的 id 随机数+时间 传到 删除的方法,再根据 这个id 拼凑成对应的 tableid ,然后操作改table的数据,然后刷新该table。
3、新增一个页签: tabs 是 需要拼接li 的ui
var tabs = $("#sheetDiv ul.nav-tabs"); $("#addTabBut").on("click", function () {//id 唯一var randonNumber=Math.floor(Math.random()*999999);var count=new Date().getTime()+randonNumber;var liLength = $("#conf_ui li").length+1;var tableid="table_"+count;var inputid="configuration_"+count+"_input";var divs= '<div id="caseListFieldsDiv" class="col-xs-12">'+'<div class="input-group input-group-count" style="float:right;top:18px;" >'+'<div class="input-icon-group PingFangSC">'+'<div class="input-group" >'+'<span class=" addon-span pingFangSC-drawer-text pingFangSC-Typeface-r" >'+'<i class="localIcon icon-jia" id="conf_add" onClick="addConfs('+count+')" title="添加行"></i>'+' <i class="localIcon icon-shanchu" id="conf_del" onClick="delRows('+count+')" title="删除行" ></i>'+' <i class="localIcon icon-zai " id="conf_adds" onClick="saveMicroserviceConfigFun('+count+')" title="保存文件"></i>'+'</span>'+'</div>'+'</div>'+ '</div>'+ '<div id="microservicName" class="whole-margin-b" >'+'<label for='+inputid+' class="divlabel-control">'+'<span style="color:red">*</span><span class="pingFangSC-drawer-text pingFangSC-Typeface-r">配置文件名称:</span> '+'</label>'+'<input id='+inputid+' class="divinput-control pingFangSC-drawer-text pingFangSC-Typeface-r" value="" onchange="changeSheetName(this)" />'+'</div>'+'<div id='+tableid+' class="table-content handsontable pingFangSC-table"></div>'+'</div> ';// var nameId=divs.replace(new RegExp("microserviceTable","g"),tableid);tabs.addTabs({"id": "configuration_" + count,"title": "新建配置文件-" + liLength,"sheetNumber":count,"content": divs}); showtables(count);});
tabs.addTabs 调用的就是 前面抄的js,拼接li和div。
四、总结:
1、其他数据库操作和第一版一样,唯一的关键点在于:第一版是 单页面 单列表操作,这一版是 多页面 多列表;
多页面 意味着 你填入的数据没有保存,在切换页面后任然存在,这也和人的行为习惯保持一致,但多页面也造成了数据操作混乱,开发者需要解决不同页面操作数据而不影响其他页面的问题。我的解决思路是方法复用,不同页面传递不同参数,由参数确定操作对应页面数据。
2、整个需求:实现每个分布式项目配置文件的自动化,一处配制,多处调用;解放开发人员,每次项目上线不用再打电话处理配置文件的事了,运维人员一键就能搞定。 乍一看需求很复杂,其实细分下来,就3点重要:
一、一个项目对应多个配置文件;
二、初次加载,展示该项目下的所有配置文件以及其内容;(拼接页签)
三、配置文件的增删改查;(多页签数据操作)
3、页面的刷新: 尽量少用全页面刷新,多使用局部刷新;
比如:删除 某一条数据,只需要将当前这条数据从表格中删除,而不用让重新查一次数据库,页面重新加载。
更多推荐
js 动态添加html 页签
发布评论