键值组件是FastAdmin开发的一项简洁实用的基础组件,在FastAdmin中很多模块都有使用到该组件,例如常规管理->系统配置->字典配置均使用此组件开发。
1、支持一维数组和二维数组数据源
2、支持添加、删除、排序
3、支持自定义列表模板
fieldlist组件支持一维数组和二维数组数据源,默认为一维数组数据源,如果需要使用二维数组数据源,请务必同时使用自定义模板功能才支持。
一维数组数据源示例:
<textarea name="row[configgroup]" class="form-control hide" cols="30" rows="5">
{
"basic":"基础配置",
"email":"邮件配置",
"dictionary":"字典配置",
"user":"会员配置",
"example":"示例分组"
}
</textarea>
二维数组数据源示例:
<textarea name="row[test]" class="form-control hide" cols="30" rows="5">
[
{"name":"张三","gender":"男","age":"23","score":"80"},
{"name":"李四","gender":"男","age":"26","score":"90"}
]
</textarea>
以下是键值组件常用的一维数组数据源使用方法:
<dl class="fieldlist" data-name="row[configgroup]">
<dd>
<ins>键名</ins>
<ins>键值</ins>
</dd>
<dd>
<a href="javascript:;" class="btn btn-sm btn-success btn-append"><i class="fa fa-plus"></i> 追加</a>
</dd>
<textarea name="row[configgroup]" class="form-control hide" cols="30" rows="5">{"basic":"基础配置","email":"邮件配置","dictionary":"字典配置","user":"会员配置","example":"示例分组"}</textarea>
</dl>
通过将以上代码放置在我们的表单中,然后使用Form.api.bindevent("form")或Form.events.fieldlist("form")进行初始化即可。
以上是最简洁的使用方法,fieldlist还有更强大的自定义功能来实现自定义模板和二维数组数据源,如下:
<dl class="fieldlist" data-name="row[test]" data-template="testtpl">
<dd>
<ins>姓名</ins>
<ins>性别</ins>
<ins>年龄</ins>
<ins>成绩</ins>
</dd>
<dd>
<a href="javascript:;" class="btn btn-sm btn-success btn-append"><i class="fa fa-plus"></i> 追加</a>
</dd>
<textarea name="row[test]" class="form-control hide" cols="30" rows="5">[{"name":"张三","gender":"男","age":"23","score":"80"},{"name":"李四","gender":"男","age":"26","score":"90"}]</textarea>
</dl>
<!--定义模板,模板语法使用Art-Template模板语法-->
<script type="text/html" id="testtpl">
<dd class="form-inline">
<input type="text" name="<%=name%>[<%=index%>][name]" class="form-control" value="<%=row['name']%>" size="10">
<input type="text" name="<%=name%>[<%=index%>][gender]" class="form-control" value="<%=row['gender']%>" size="30">
<input type="text" name="<%=name%>[<%=index%>][age]" class="form-control" value="<%=row['age']%>" size="30">
<input type="text" name="<%=name%>[<%=index%>][score]" class="form-control" value="<%=row['score']%>" size="30">
<span class="btn btn-sm btn-danger btn-remove"><i class="fa fa-times"></i></span> <span class="btn btn-sm btn-primary btn-dragsort"><i class="fa fa-arrows"></i></span>
</dd>
</script>
在自定义模板中有固定的变量,如<%=name%>、<%=index%>、<%=row['列名']%>,说明如下:
| 变量 | 说明 | 示例 | 结果 |
|---|---|---|---|
name | 字段名称,该值将会替换为data-name中的值 | <%=name%> | row[test] |
index | 渲染行的索引值,该值会递增,但并不保证连续 | <%=index%> | 0 |
row | 数组行的数据 | <%=row['gender']%> | 男 |
key | 键名的值,该值仅用于键值数组时使用 | <%=key%> | test |
value | 键值的值,该值仅用于键值数组时使用 | <%=value%> | value |
温馨提示:使用自定义模板时,二维数据请勿仅使用key和value这个键名,会导致被识别为键值数组。
fieldlist默认使用的是dl dd布局,此外还支持使用table来进行布局,达到更好的展示效果,如下:
<table class="table table-responsive fieldlist" data-name="row[test]" data-template="testtpl" data-tag="tr">
<tr>
<td>姓名</td>
<td>性别</td>
<td>年龄</td>
<td>成绩</td>
<td></td>
</tr>
<tr>
<td colspan="5"><a href="javascript:;" class="btn btn-sm btn-success btn-append"><i class="fa fa-plus"></i> 追加</a></td>
</tr>
<textarea name="row[test]" class="form-control hide" cols="30" rows="5">[{"name":"张三","gender":"男","age":"23","score":"80"},{"name":"李四","gender":"男","age":"26","score":"90"}]</textarea>
</table>
<!--定义模板,模板语法使用Art-Template模板语法-->
<script type="text/html" id="testtpl">
<tr class="form-inline">
<td><input type="text" name="<%=name%>[<%=index%>][name]" class="form-control" value="<%=row['name']%>" size="10"></td>
<td><input type="text" name="<%=name%>[<%=index%>][gender]" class="form-control" value="<%=row['gender']%>" size="30"></td>
<td><input type="text" name="<%=name%>[<%=index%>][age]" class="form-control" value="<%=row['age']%>" size="30"></td>
<td><input type="text" name="<%=name%>[<%=index%>][score]" class="form-control" value="<%=row['score']%>" size="30"></td>
<td><span class="btn btn-sm btn-danger btn-remove"><i class="fa fa-times"></i></span> <span class="btn btn-sm btn-primary btn-dragsort"><i class="fa fa-arrows"></i></span></td>
</tr>
</script>
可以看到我们我们给table添加了一个额外的属性data-tag="tr"
通过以上定义,可以任意自定义我们展示项的数据。
使用表格布局时必须使用自定义模板,且自定义模板中的第一个DOM元素必须是<tr>
如果我们需要在点击追加按钮以后再对新增的展示项绑定事件,我们可以在JS中通过监听事件来给新增的元素绑定事件,这种情况常用于我们自定义列表中有表单组件,如日期选择、上传按钮、动态下拉等情况下使用。
$(document).on("fa.event.appendfieldlist", '[data-name="row[test]"] .btn-append', function(e, obj){
//通用的表单组件事件绑定和组件渲染
Form.api.bindevent($(obj));
});
如果我们在JS中外部对fieldlist中的组件做了修改,此时我们需要手动触发下组件的change事件,如:
$("[data-name='row[test]'] input:first-child").trigger("change");
通过以上代码来触发input的change事件,此时我们隐藏的textarea值才会刷新,否则textarea仍然是旧的数据
如果我们通过JS手动修改了隐藏的textarea的值,此时需要重新渲染我们的fieldlist组件,我们可以通过
$("[data-name='row[test]'] textarea[name='test']").trigger("fa.event.refreshfieldlist");
来重新渲染我们的组件
如果我们希望在外部追加数据,可以通用调用追加按钮的点击事件并透传数据来实现
var data ={
"name":"王五",
"gender":"男",
"age":"22",
"score":"60"
};
$("[data-name='row[test]'] .btn-append").trigger("click", [data]);

html部分:
<style>
.upload-image {
background: url('/assets/img/plus.png') no-repeat center center;
background-size: 30px 30px;
height: 30px;
width: 30px;
border: 1px solid #ccc;
}
</style>
<dl class="fieldlist" data-template="leveltpl" data-name="row[{name}]" id="second-table">
<dd>
<ins>标题名称</ins>
<ins>描述文字</ins>
<ins>icon地址</ins>
<ins>按钮文字</ins>
<ins>跳转地址</ins>
</dd>
<dd><a href="javascript:;" class="btn btn-sm btn-success btn-append"><i class="fa fa-plus"></i> 追加</a></dd>
<textarea name="row[{name}]" class="form-control hide" cols="30" rows="5">{value}</textarea>
</dl>
<script id="leveltpl" type="text/html">
<dd class="form-inline">
<ins>
<input type="text" name="row[<%=name%>][<%=index%>][name]" class="form-control" value="<%=row['name']%>" placeholder="标题名称" size="10">
</ins>
<ins>
<input type="text" name="row[<%=name%>][<%=index%>][text]" class="form-control" value="<%=row['text']%>" placeholder="描述文字" size="10">
</ins>
<ins>
<input type="hidden" name="<%=name%>[<%=index%>][image]" id="c-image-<%=index%>" value="<%=row.image%>">
<button type="button" id="faupload-image" class="btn btn-danger faupload upload-image" data-input-id="c-image-<%=index%>" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp,image/webp" data-multiple="false" <%if(row.image){%>style="background-image: url('<%=row.image%>')"<%}%>></button>
</ins>
<ins>
<input type="text" name="row[<%=name%>][<%=index%>][gowhat]" class="form-control" value="<%=row['gowhat']%>" placeholder="按钮文字" size="10">
</ins>
<ins>
<input type="text" name="row[<%=name%>][<%=index%>][pages]" class="form-control" value="<%=row['pages']%>" placeholder="跳转地址" size="10">
</ins>
<span class="btn btn-sm btn-danger btn-remove"><i class="fa fa-times"></i></span>
<span class="btn btn-sm btn-primary btn-dragsort"><i class="fa fa-arrows"></i></span>
</dd>
</script>
js部分:
index: function () {
// 自定义上传图片
$(document).on("fa.event.appendfieldlist", "#second-table .btn-append", function (e, obj) {
//绑定上传组件
Form.events.faupload(obj);
//上传成功回调事件,变更按钮的背景
$(".upload-image", obj).data("upload-success", function (data) {
$(this).css("background-image", "url('" + Fast.api.cdnurl(data.url) + "')");
})
});
}