在为HTML添加动态布局的时候,比如需要动态添加一个div的数量或者input,
通常的做法都是写一个function函数,然后把想要动态添加的div或者nput的HTML文本放在一个var变量中,之后使用click点击事件或者使用$.each/for循环进行批量添加。
这是一个解决方案,可是一旦需要添加的HTML文本多了起来,那么这种方式看起来就显得过于沉重,所以我们可以使用另一种方式。
我们日常写javaScript代码的时候使用的标签是这样的
<script type="text/javascript">
那么我们现在需要在script标签中写HTML,所以我们需要把type类型换成适配HTML的
<script type="text/html"></script>
我们可以把需要叠加的html文本放在这个标签内。
结果是这样的
<script type="text/html" id="divTemplate">
<div class="divFrame">
<label class="form-label col-xs-4 col-sm-3">
<span class="c-red">*</span>资质信息:
</label>
<div style="background-color: whitesmoke;height: 100%;margin-left:24%;margin-right: 40%;" class="row cl">
<div class="form-label col-xs-4 col-sm-12">
<button type="button" class="btn btn-danger radius" onclick="removeMaterial(this)">删除资质信息</button>
</div>
<div class="formControls col-xs-8 col-sm-9" style="margin-top: 20px;">
<div style="display: flex;">
<label>
<span class="c-red">*</span>资质名称:
</label>
<input type="text" class="input-text" style="width: 80%;" placeholder="请填写资质名称" name="qualificationName">
</div>
</div>
<div class="formControls col-xs-8 col-sm-9" style="margin-top: 20px;">
<div style="display: flex;">
<label>
<span class="c-red">*</span>资质等级:
</label>
<input type="text" class="input-text" style="width: 80%;" value="" placeholder="请填写资质等级" name="level">
</div>
</div>
<div class="formControls col-xs-8 col-sm-10" style="margin-top: 20px;">
<div>
<div style="display: flex;">
<label style="width: 20%;">
<span class="c-red">*</span>资质图片:
</label>
<div id="scImg" style="display: flex;width: 75%;">
<div class="img" id="img1">
<input type="hidden" name="urlStr" class="urlStr" id="img">
<div id="[divImg]" class="uploader-list"></div>
<div class="[filePicker1]" onClick="bindUpload('[divImg]');" style="margin-right: 5px;">选择图片</div>
</div>
<div class="coordinate[addNum]"></div>
<div>
<a id="[addNum]" onclick="addImg(this)" class="btn btn-success radius">添加</a>
<a id="[removeNum]" onclick="removeImg(this)" class="btn btn-danger radius">删除</a>
</div>
</div>
</div>
</div>
</div>
<div class="formControls col-xs-8 col-sm-9" style="margin-top: 20px;padding-bottom: 20px;">
<div style="display: flex">
<label style="padding-left:8%;width:12%">备注:</label>
<textarea name="remark" style="height:150px;width: 400px;" placeholder="请填写资质备注"></textarea>
</div>
</div>
</div>
</div>
</script>
这么多html需要动态添加,真让人头疼。但还好javaScript提供了我们这种方式,使代码看起来不至于眼花缭乱,望而生畏。
现在HTML内嵌入到了javaScript标签中,可是HTML内置于javaScript标签中是等同于不存在的,也就是我们无法使用任何选择器获取html里的属性
我们要怎么使用javaScript里面的HTML代码段呢?
我们需要给javaScript标签起一个唯一标识,比如我上面的javaScript标签标识是
id="divTemplate"
<script type="text/html" id="divTemplate">
有了唯一标识我们就可以获取script里面的HTML代码了,获取方式如下
var _html = document.getElementById("divTemplate").innerHTML;
好的,这个时候可能会发现遇到了另一个问题,HTML标签的属性名称都是一样的,如果我要动态添加10个这种HTML,那么所有的属性名都是一样的,如果用在后台新增上面,取值的时候该怎么取呢?
你应该会想到,通过【祖、父、子、兄、弟】节点获取,无论添加多少都无所谓
那么向我上面这种既需要纵向动态添加HTML文本,又需要在动态添加的HTML里横向动态添加的HTML的需求,下面是需要在动态添加的HTML文本里面横向添加的HTML文本
效果图是这样的
每个资质信息里面的图片一定得是独立不能是互斥的。
这时候因为纵向需要有纵向的坐标,横向需要有横向的坐标,再通过【祖、父、子、兄、弟】节点也不是那么容易获取到(比较麻烦)
因此必须要改动这些HTML中需要用到的属性名称,然后再【祖、父、子、兄、弟】节点就容易获取了。
然而这些HTMl文本是写在javaScript标签里面的。不能像写在for循环里面一样每次添加都可以动态添加其坐标作为属性名的一部分。
这时我们可以这样解决。
1、定义一个number类型的变量num,每次点击添加按钮的时候num+1
2、然后使用正则表达式全局匹配javaScript中的HTML
3、将匹配到的属性名替换为自己需要的属性名,因为num是动态的,所以属性名加上num一定是不重复的。
代码如下:
/**
* 添加资质信息
*/
var num = 1;
function addMaterial(){
if(num <10){
num++;
var _html = document.getElementById("divTemplate").innerHTML;
var reg = new RegExp("\\[([^\\[\\]]*?)\\]", 'igm');
var source = _html.replace(reg, function (node, key) {
return {
"divImg":"divImg"+num,
"filePicker1":"filePicker1"+num,
"addNum":"X"+num,
"removeNum":"X"+num
}[key];
})
$(".thisBeforeAddMaterial").before(source);
fileUpload("1"+num);
}else{
layer.msg("最多只能添加十条资质信息!");
}
}
thisBeforeAddMaterial是一个span占位符标签,每次在这个占位符之前添加,保证添加的顺序为正序(写到这里我忽然觉得倒叙的体验是不是比较友好一些...算了不管了,反正都要划到最下面点提交按钮)
动态添加的坐标如下:
以下是动态删除的方法
/**
* 删除资质信息
* @param ele
*/
function removeMaterial(ele){
if(num >1){
num--;
$(ele).parents(".divFrame").remove();
}
}
OK,写到这里纵向添加就已经完成了,取值方式如下:
/**
* 取资质信息数据
*/
function getGrowthValueData(){
var df = $(".divFrame");
var hz_qualification_information = new Array();
$.each(df,function(index,row){
var imgChildren = $(row).find("div[class='img']");
//取图片路径
var imgs = new Array();
$.each(imgChildren,function(i,r){
var imgPath = $(r).children("input").val();
if('' != imgPath){
imgs.push(imgPath);
}
})
var qualificationName = $(row).find("input[name='qualificationName']").val();
var level = $(row).find("input[name='level']").val();
var remark = $(row).find("textarea[name='remark']").val();
if(index >0 && qualificationName == '' && level == '' && imgs.length<1){
return;
}
var obj = {
qualificationName :qualificationName,
qualificationLevel:level,
/*qualificationPicture:JSON.stringify(imgs),*/
qualificationPicture:imgs,
remarks:remark
};
hz_qualification_information.push(obj);
})
return hz_qualification_information;
}
结果集格式如下:
校验方式如下:
//-------------------------------校验企业资质信息 开始-------------------------------------------------------------------
var growth = getGrowthValueData();
var qFlag = true;
$.each(growth,function(index,row){
var qualificationName = row.qualificationName;
var qualificationLevel = row.qualificationLevel;
var qualificationPictures = row.qualificationPicture;
if('' == qualificationName){
layer.msg("请填写资质名称!");
qFlag = false;
return qFlag;
}
if('' == qualificationLevel){
layer.msg("请填写资质等级!");
qFlag = false;
return qFlag;
}
if(qualificationPictures.length < 1){
layer.msg("请至少上传一张资质图片!");
qFlag = false;
return qFlag;
}
})
if(qFlag){
flag = true;
}
//-------------------------------校验企业资质信息 结束-------------------------------------------------------------------
return flag;
动态添加图片,因为html文本不算多,我就直接写在了函数里面
/**
* 添加图片按钮
*/
var imgNum = 1;
function addImg(ele) {
var id = $(ele).prop("id");
imgNum++;
if(imgNum >= 2){
$("#"+id).hide();
}
var adv = id+imgNum;
$(".coordinate"+id).before("" +
"<div class=\"img\" id=\"adv" + id + "\">" +
"<input type=\"hidden\" name=\"urlStr\" class=\"urlStr\" id='img'>" +
"<div id=\"divImg1" + imgNum + "\" class=\"uploader-list\">" + "</div>" +
"<div class=\"filePicker" + adv + "\" onClick=\"bindUpload('divImg1" + imgNum + "');\" style=\"margin-right: 5px;\">选择图片</div>" +
"</div>"
);
fileUpload(adv);
}
//删除图片
function removeImg(ele){
var id = $(ele).prop("id");
$("#adv"+id).remove();
if(imgNum > 1){
imgNum--;
}
if(imgNum < 3){
$("#"+id).show();
}
}
最后说下使用Ajax提交到后台,这种复杂对象的提交需要添加contentType
/**
* 新增接单方用户 请求后台
*/
function insert(result){
$.ajax({
type: 'POST',
url: context + 'receiveUser/add',
contentType:'application/json;charset=utf-8',
data: JSON.stringify(result),
dataType: 'JSON',
success: function (data) {
if (data.data) {
modaldemo(data);
}else{
layer.msg(data.msg);
}
},
error: function (data) {
layer.msg(data.msg);
},
});
}
后台是一个对象接收