curd组件2:按钮实现
参考:https://blog.csdn.net/dixian4894/article/details/102209151上篇没有区分哪些字段可以编辑,而且如果像性别这种,在编辑的时候应该是个选择器,所以,在fields_config添加attr属性,并在attr赋值是否可编辑,编辑状态所用html标签,select的数据来源属性,一个例子如下:
{
"field_name": "性别",
"field_in_db": "gender",
"display": True,
"show_data": "!GENDER",
"attr": {
"editable": True,
"htmlLabel": "select",
"selectDataFrom":"GENDER"
}
}, 前端得到这些数据,便可实现,编辑,全选,反选,取消按钮,代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
<style>
.data-display{
margin: 200px;
}
</style>
</head>
<body>
<div class="data-display">
<div class="btn-group" role="group" aria-label="...">
<button id="SelectAll" type="button" class="btn btn-default">全选</button>
<button id="Reserve" type="button" class="btn btn-default">反选</button>
<button id="Cancel" type="button" class="btn btn-default">取消</button>
<button id="EditMode" type="button" class="btn btn-default">进入编辑模式</button>
<button id="Del" class="btn btn-default">批量删除</button>
<button id='save' type="button" class="btn btn-default">保存</button>
</div>
<table class="table table-bordered" id="Datatable">
<thead id="table_th"></thead>
<tbody id="table_td"></tbody>
</table>
</div>
</body>
<script src="/static/js/jquery-3.5.1.min.js"> </script>
<script>
$(function () {
initTable();
BindEditMode();
BindCheckboxEditMode();
BindSelectAll();
BindCancel();
BindReserve();
})
function initTable(){
$.ajax({
url:"getCurdData",
type:'POST',
dataType:'Json',
success:function (arg) {
initchoice(arg.choices_dict)
initThead(arg.fields_config)
initTbody(arg.data,arg.fields_config)
}
})
}
function initThead(field) {
tr_ele=$("<tr></tr>")
$.each(field,function (k,v) {
if(v["display"]){
th_ele=$("<th></th>")
th_ele.text(v["field_name"])
tr_ele.append(th_ele)
}
$("#table_th").append(tr_ele)
})
}
function initTbody(data,field) {
// 数据展示一般做法是,取出展示的字段,然后循环数据列表判断是否在里面,有则展示
// 但是这么做有个缺点是数据和字段的顺序要对应(因为是以数据为顺序,而字段顺序是可能变化的),而且不利于扩展
// 这里采用先循环数据列表,再循环field字段列表,根据字段的列表的顺序反选查找赋值
// 缺点是多次循环field比较耗性能,但是扩展能力变强了
$.each(data,function (data_k,data_v) {
tr_ele=$("<tr></tr>")
$.each(field,function (field_k,field_v) {
if(field_v.display){
td_ele=$("<td></td>")
//赋值attr
$.each(field_v.attr,function (attr_k,attr_v) {
td_ele.attr(attr_k,attr_v)
})
if(field_v["show_data"]==='@'){
td_ele.html(data_v])
}
else if(field_v["show_data"]==='!'){
var f_v=field_v["show_data"]
var choice_list=f_v.substring(1,f_v.length)
var choice_v=value_from_choice_list(data_v],window)
td_ele.html(choice_v)
}
else{
td_ele.html(field_v["show_data"])
}
tr_ele.append(td_ele)
}
})
$("#table_td").append(tr_ele)
})
}
function initchoice(choice_dict) {
$.each(choice_dict,function (i,j) {
// a='123'相当于window='123'
// 这里把choices列表转化为全局变量
window=j;
})
}
function value_from_choice_list(index,choice) {
//choice格式:{0: (2) ["male", "男"],}
//v="male",v="男"
ret=null
$.each(choice,function (k,v) {
if(v === index){
ret=v
//js 的return只能跳出当前循环,类似shell的break
// 所以额外赋值
return
}
})
return ret
}
function BindEditMode() {
$('#EditMode').click(function () {
//进入编辑模式,应该有个标记,才能区分进入与退出,这里用btn-info属性给button上色
//所以也用这个属性判断是否在编辑模式,有则是应退出,无则不是应进入
//也可以自己定义一个属性判断
if($(this).hasClass("btn-info"))
{
OutEditMode()
}else{
IntoEditMode()
}
})
}
function IntoEditMode() {
$('#EditMode').addClass("btn-info")
$('#EditMode').text("退出编辑模式")
//查找checkbox是否选中,有则查找对应tr进入编辑
$("#table_td").find(":checked").each(function () {
$cur_tr=$(this).parent().parent()
TrIntoEdit($cur_tr)
})
}
function OutEditMode() {
$('#EditMode').removeClass("btn-info")
$('#EditMode').text("进入编辑模式")
$("#table_td").find(":checked").each(function () {
$cur_tr=$(this).parent().parent()
TrOutEdit($cur_tr)
})
}
function TrIntoEdit(cur_tr) {
//给当前行加个颜色表示正在编辑
cur_tr.addClass("info")
// 查找tr下的td含有editable属性的元素进行渲染
cur_tr.find('').each(function () {
var htmllabel = $(this).attr('htmllabel')
if(htmllabel === 'select'){
//如果类型是select,获取列表值,渲染成select选择
var selectData=$(this).attr('selectDataFrom')
var select_ele=$("<select></select>")
var cur_select_v=$(this).html()
$.each(window,function (select_k,select_v) {
var option_ele=$("<option></option>")
option_ele.val(select_v)
option_ele.html(select_v)
if(cur_select_v === select_v){
option_ele.attr("selected",true)
}
select_ele.append(option_ele)
})
$(this).html(select_ele)
}else {
label_v=$(this).text()
input_ele=$("<input>")
input_ele.val(label_v)
$(this).html(input_ele)
}
})
}
function TrOutEdit(cur_tr) {
//当前行去掉颜色表示退出
cur_tr.removeClass("info")
// 查找tr下的td含有editable属性的元素进行渲染
cur_tr.find('').each(function () {
var htmllabel = $(this).attr('htmllabel')
if(htmllabel === 'select'){
//如果类型是select,获取选中的值,赋值
var select_ele = $(this).children().first()
var cur_select_v=select_ele.selectedOptions.innerHTML
$(this).html(cur_select_v)
}else {
var input_ele = $(this).children().first()
var cur_input_v=input_ele.val()
$(this).html(cur_input_v)
}
})
}
function BindCheckboxEditMode() {
// IntoEditMode的函数有个bug,如果先进入编辑模式,再点击checkbox按钮
// 当前行不会进入编辑模式,这是因为点击button比勾选快
// 所以需要对CheckBox进行编辑模式下的事件委托
$("#table_td").on('click',':checkbox',function () {
if ($("#EditMode").hasClass("btn-info")) {
cur_status = $(this).prop('checked');
var $cur_tr = $(this).parent().parent();
if(cur_status){
TrIntoEdit($cur_tr)
}else{
TrOutEdit($cur_tr)
}
}
})
}
function BindSelectAll() {
// 全选分两种,编辑模式下,要TrIntoEdit,普通则勾选即可
$('#SelectAll').click(function () {
// 全选只需处理未被选中的即可
$("#table_td").find(":checkbox").not(":checked").each(function () {
if($("#EditMode").hasClass("btn-info")){
$(this).prop('checked',true);
var $cur_tr = $(this).parent().parent();
TrIntoEdit($cur_tr)
}else{
$(this).prop('checked',true);
}
})
})
}
function BindReserve() {
// 反选需要两种情况,编辑模式下,如果选中则TrOutEdit,未选中则TrIntoEdit
// 普通则反选即可
$('#Reserve').click(function () {
$("#table_td").find(":checkbox").each(function () {
if($("#EditMode").hasClass("btn-info")){
var $cur_tr = $(this).parent().parent();
if($(this).prop('checked')){
$(this).prop('checked',false);
TrOutEdit($cur_tr)
}else{
$(this).prop('checked',true);
TrIntoEdit($cur_tr)
}
}else{
if($(this).prop('checked')){
$(this).prop('checked',false);
}
else{
$(this).prop('checked',true);
}
}
})
})
}
function BindCancel() {
// 取消跟全选相反,只需要处理选中的checkbox
// 也是两种情况,若编辑模式,则TrOutEdit,否则去掉勾选即可
$('#Cancel').click(function () {
$("#table_td").find(":checked").each(function () {
if($("#EditMode").hasClass("btn-info")){
$(this).prop('checked',false);
var $cur_tr = $(this).parent().parent();
TrOutEdit($cur_tr)
}else{
$(this).prop('checked',false);
}
})
})
}
</script>
</html> 在实现删除和保存的时候,需要改动的东西比较多,因为保存意味着更新,所以要知道旧值和新值,如果新旧不一样才更新,这意味着多加字段标记旧属性,修改赋值代码等,具体如下:在实现删除和保存的时候,需要改动的东西比较多,因为保存意味着更新,所以要知道旧值和新值,如果新旧不一样才更新,这意味着多加字段标记旧属性,修改赋值代码等,具体如下:
config属性赋值更新:
之前:
"attr": {
"editable":True,
"htmlLabel":""
}
之后:
"attr": {
"editable":True,
"origin_v":"@field_name",
"htmlLabel":""
}
initTbody函数修改:
tr赋值属性记录当前行id;
之前:
tr_ele=$("<tr></tr>")
之后:
tr_ele=$("<tr></tr>")
var old_data_id=data_v["id"]
tr_ele.attr("old_data_id",old_data_id)
td属性赋值更新:
//赋值attr
// 赋值field_in_db属性,用以在更新时找到对应数据库字段
td_ele.attr("field_in_db",field_v["field_in_db"])
$.each(field_v.attr,function (attr_k,attr_v) {
// "origin_v":"@field_name",属性赋值需转为数据库的值
if(attr_k==="origin_v")
{
attr_v=data_v]
td_ele.attr(attr_k,attr_v)
}else{
td_ele.attr(attr_k,attr_v)
}
})
TrIntoEdit函数修改:
之前:
cur_tr.addClass("info")
之后:
cur_tr.addClass("info")
// 标记当前行已编辑,表明可能数据变更,没有则没变更
cur_tr.attr("has-edit",true)
TrOutEdit退出赋新值:
之前:
var select_ele = $(this).children().first()
var cur_select_v=select_ele.selectedOptions.innerHTML
$(this).html(cur_select_v)
之后:
var select_ele = $(this).children().first()
var cur_select_v=select_ele.selectedOptions.innerHTML
$(this).html(cur_select_v)
// 赋新值属性
origin_v=$(this).prop("origin_v")
change_v=DBvalue_from_choice_list(cur_select_v,window)
if(origin_v != change_v){
$(this).attr("change_v",change_v)
}
添加save 按钮:
function BindSave() {
// 收集改变的行,每行为一条记录,从tr标签读取旧数据id
// 从td读取field_name作为key,读取chang_v为value,若无则不赋值
$('#Save').click(function () {
// 如果编辑模式下,相当于点了取消
$('#Cancel').click()
// 用update_list作为标记,告知后端传送的是更新的数据
var update_list=[]
$('#table_td').find('tr').each(function () {
record={}
id_v=$(this).attr("old_data_id")
record["id"]=id_v
$(this).children('').each(function(){
if($(this).attr("change_v")) {
field_k = $(this).attr("field_in_db")
field_v = $(this).attr("change_v")
record = field_v
}
})
update_list.push(record);
})
$.ajax({
url: "getCurdData",
type: 'POST',
data: {'update_list': JSON.stringify(update_list)},
dataType: 'json',
success:function (arg) {
if(arg.status=='ok'){
initTbody()
}
}
})
})
}
添加删除按钮:
function BindDel() {
// 删除按钮要获取当前选中行的数据库id,还要弹窗提示确认
$('#Del').click(function () {
del_list=[]
$('#table_td').find(":checked").each(function () {
record={}
// save找的是tr,这里是td,所以需parent
id_v=$(this).parent().parent().attr("old_data_id")
console.log($(this))
record["id"]=id_v
})
del_list.push(record)
var r=confirm("确定删除?");
if(r){
$.ajax({
url: "getCurdData",
type: 'POST',
data: {'del_list': JSON.stringify(del_list)},
dataType: 'json',
success:function (arg) {
if(arg.status=='ok'){
initTbody()
}
}
})
}
})
} 按钮都实现后,就可以提取共同的部分封装成js(增加功能:requestURL,用pager分页等),最终代码如下:
后端view(无实现保存和删除)
def getCurdData(request):
print(request.POST)
Gender_list=list(User.GENDER)
work_list=[('1', '开'), ('2', '关')]
fields_config=[
{
"field_name": "选项",
"field_in_db": "",
"display": True,
"show_data": "<input type='checkbox' />",
"attr":{
}
},
{
"field_name":"用户名",
"field_in_db":"username",
"display":True,
"show_data":"@field_name",
"attr": {
"editable":True,
"origin_v":"@field_name",
"htmlLabel":"",
}
},
{
"field_name": "密码",
"field_in_db": "password",
"display": True,
"show_data": "@field_name"
},
{
"field_name": "邮件",
"field_in_db": "email",
"display": True,
"show_data": "@field_name",
"attr": {
"editable": True,
"htmlLabel": "",
"origin_v":"@field_name",
}
},
{
"field_name": "性别",
"field_in_db": "gender",
"display": True,
"show_data": "!GENDER",
"attr": {
"editable": True,
"origin_v": "@field_name",
"htmlLabel": "select",
"selectDataFrom":"GENDER"
}
},
{
"field_name": "电话",
"field_in_db": "tel",
"display": True,
"show_data": "@field_name"
},
{
"field_name": "生日",
"field_in_db": "birthday",
"display": True,
"show_data": "@field_name"
},
{
"field_name": "别名",
"field_in_db": "name",
"display": True,
"show_data": "@field_name"
},
]
data_list=list(User.objects.all().values())
result={
"fields_config":fields_config,
"data":data_list,
"choices_dict":{
"GENDER":Gender_list,
"work":work_list,
}
}
return HttpResponse(json.dumps(result,cls=CJsonEncoder)) 删除和保存的POST数据如下:
<QueryDict: {'del_list': ['[{"id":"1"}]']}>
"POST /getCurdData HTTP/1.1" 200 1574
<QueryDict: {'update_list': ['[{"id":"1"},{"id":"2"}]']}> CURDbyLinzb.js
$(function () {
function initTable(pager){
// pager:提取第pager页的数据
$.ajax({
url:requestURL,
type:'GET',
data:{'pager':pager},
dataType:'Json',
success:function (arg) {
initchoice(arg.choices_dict)
initThead(arg.fields_config)
initTbody(arg.data,arg.fields_config)
}
})
}
function initThead(field) {
tr_ele=$("<tr></tr>")
$.each(field,function (k,v) {
if(v["display"]){
th_ele=$("<th></th>")
th_ele.text(v["field_name"])
tr_ele.append(th_ele)
}
$("#table_th").append(tr_ele)
})
}
function initTbody(data,field) {
// save按钮重载时,会重新生成,所以需清空
$('#table_td').empty();
// 数据展示一般做法是,取出展示的字段,然后循环数据列表判断是否在里面,有则展示
// 但是这么做有个缺点是数据和字段的顺序要对应(因为是以数据为顺序,而字段顺序是可能变化的),而且不利于扩展
// 这里采用先循环数据列表,再循环field字段列表,根据字段的列表的顺序反选查找赋值
// 缺点是多次循环field比较耗性能,但是扩展能力变强了
$.each(data,function (data_k,data_v) {
tr_ele=$("<tr></tr>")
// tr赋值属性,标记当前行在数据库中的id,为更新做旧数据标记
var old_data_id=data_v["id"]
tr_ele.attr("old_data_id",old_data_id)
$.each(field,function (field_k,field_v) {
if(field_v.display){
td_ele=$("<td></td>")
// td 赋值attr
// 赋值field_in_db属性,用以在更新时找到对应数据库字段
td_ele.attr("field_in_db",field_v["field_in_db"])
$.each(field_v.attr,function (attr_k,attr_v) {
// "origin_v":"@field_name",属性赋值需转为数据库的值
if(attr_k==="origin_v")
{
attr_v=data_v]
td_ele.attr(attr_k,attr_v)
}else{
td_ele.attr(attr_k,attr_v)
}
})
if(field_v["show_data"]==='@'){
td_ele.html(data_v])
}
else if(field_v["show_data"]==='!'){
var f_v=field_v["show_data"]
var choice_list=f_v.substring(1,f_v.length)
var choice_v=value_from_choice_list(data_v],window)
td_ele.html(choice_v)
}
else{
td_ele.html(field_v["show_data"])
}
tr_ele.append(td_ele)
}
})
$("#table_td").append(tr_ele)
})
}
function initchoice(choice_dict) {
$.each(choice_dict,function (i,j) {
// a='123'相当于window='123'
// 这里把choices列表转化为全局变量
window=j;
})
}
function value_from_choice_list(index,choice) {
//choice格式:{0: (2) ["male", "男"],}
//v="male",v="男"
ret=null
$.each(choice,function (k,v) {
if(v === index){
ret=v
//js 的return只能跳出当前循环,类似shell的break
// 所以额外赋值
return
}
})
return ret
}
function DBvalue_from_choice_list(index,choice) {
//choice格式:{0: (2) ["male", "男"],}
//v="male",v="男"
ret=null
$.each(choice,function (k,v) {
if(v === index){
ret=v
//js 的return只能跳出当前循环,类似shell的break
// 所以额外赋值
return
}
})
return ret
}
function BindEditMode() {
$('#EditMode').click(function () {
//进入编辑模式,应该有个标记,才能区分进入与退出,这里用btn-info属性给button上色
//所以也用这个属性判断是否在编辑模式,有则是应退出,无则不是应进入
//也可以自己定义一个属性判断
if($(this).hasClass("btn-info"))
{
OutEditMode()
}else{
IntoEditMode()
}
})
}
function IntoEditMode() {
$('#EditMode').addClass("btn-info")
$('#EditMode').text("退出编辑模式")
//查找checkbox是否选中,有则查找对应tr进入编辑
$("#table_td").find(":checked").each(function () {
$cur_tr=$(this).parent().parent()
TrIntoEdit($cur_tr)
})
}
function OutEditMode() {
$('#EditMode').removeClass("btn-info")
$('#EditMode').text("进入编辑模式")
$("#table_td").find(":checked").each(function () {
$cur_tr=$(this).parent().parent()
TrOutEdit($cur_tr)
})
}
function TrIntoEdit(cur_tr) {
//给当前行加个颜色表示正在编辑
cur_tr.addClass("info")
// 标记当前行已编辑,表明可能数据变更,没有则没变更
cur_tr.attr("has-edit",true)
// 查找tr下的td含有editable属性的元素进行渲染
cur_tr.find('').each(function () {
var htmllabel = $(this).attr('htmllabel')
if(htmllabel === 'select'){
//如果类型是select,获取列表值,渲染成select选择
var selectData=$(this).attr('selectDataFrom')
var select_ele=$("<select></select>")
var cur_select_v=$(this).html()
$.each(window,function (select_k,select_v) {
var option_ele=$("<option></option>")
option_ele.val(select_v)
option_ele.html(select_v)
if(cur_select_v === select_v){
option_ele.attr("selected",true)
}
select_ele.append(option_ele)
})
$(this).html(select_ele)
}else {
label_v=$(this).text()
input_ele=$("<input>")
input_ele.val(label_v)
$(this).html(input_ele)
}
})
}
function TrOutEdit(cur_tr) {
//当前行去掉颜色表示退出
cur_tr.removeClass("info")
// 查找tr下的td含有editable属性的元素进行渲染
cur_tr.find('').each(function () {
var htmllabel = $(this).attr('htmllabel')
var selectdata = $(this).attr('selectDataFrom')
if(htmllabel === 'select'){
//如果类型是select,获取选中的值,赋值
var select_ele = $(this).children().first()
var cur_select_v=select_ele.selectedOptions.innerHTML
$(this).html(cur_select_v)
// 赋新值属性
origin_v=$(this).attr("origin_v")
change_v=DBvalue_from_choice_list(cur_select_v,window)
if(origin_v != change_v){
$(this).attr("change_v",change_v)
}
}else {
var input_ele = $(this).children().first()
var cur_input_v=input_ele.val()
$(this).html(cur_input_v)
origin_v=$(this).attr("origin_v")
change_v=cur_input_v
if(origin_v != change_v){
$(this).attr("change_v",change_v)
}
}
})
}
function BindCheckboxEditMode() {
// IntoEditMode的函数有个bug,如果先进入编辑模式,再点击checkbox按钮
// 当前行不会进入编辑模式,这是因为点击button比勾选快
// 所以需要对CheckBox进行编辑模式下的事件委托
$("#table_td").on('click',':checkbox',function () {
if ($("#EditMode").hasClass("btn-info")) {
cur_status = $(this).prop('checked');
var $cur_tr = $(this).parent().parent();
if(cur_status){
TrIntoEdit($cur_tr)
}else{
TrOutEdit($cur_tr)
}
}
})
}
function BindSelectAll() {
// 全选分两种,编辑模式下,要TrIntoEdit,普通则勾选即可
$('#SelectAll').click(function () {
// 全选只需处理未被选中的即可
$("#table_td").find(":checkbox").not(":checked").each(function () {
if($("#EditMode").hasClass("btn-info")){
$(this).prop('checked',true);
var $cur_tr = $(this).parent().parent();
TrIntoEdit($cur_tr)
}else{
$(this).prop('checked',true);
}
})
})
}
function BindReserve() {
// 反选需要两种情况,编辑模式下,如果选中则TrOutEdit,未选中则TrIntoEdit
// 普通则反选即可
$('#Reserve').click(function () {
$("#table_td").find(":checkbox").each(function () {
if($("#EditMode").hasClass("btn-info")){
var $cur_tr = $(this).parent().parent();
if($(this).prop('checked')){
$(this).prop('checked',false);
TrOutEdit($cur_tr)
}else{
$(this).prop('checked',true);
TrIntoEdit($cur_tr)
}
}else{
if($(this).prop('checked')){
$(this).prop('checked',false);
}
else{
$(this).prop('checked',true);
}
}
})
})
}
function BindCancel() {
// 取消跟全选相反,只需要处理选中的checkbox
// 也是两种情况,若编辑模式,则TrOutEdit,否则去掉勾选即可
$('#Cancel').click(function () {
$("#table_td").find(":checked").each(function () {
if($("#EditMode").hasClass("btn-info")){
$(this).prop('checked',false);
var $cur_tr = $(this).parent().parent();
TrOutEdit($cur_tr)
}else{
$(this).prop('checked',false);
}
})
})
}
function BindSave() {
// 收集改变的行,每行为一条记录,从tr标签读取旧数据id
// 从td读取field_name作为key,读取chang_v为value,若无则不赋值
$('#Save').click(function () {
// 如果编辑模式下,相当于点了取消
$('#Cancel').click()
// 用update_list作为标记,告知后端传送的是更新的数据
var update_list=[]
$('#table_td').find('tr').each(function () {
record={}
id_v=$(this).attr("old_data_id")
record["id"]=id_v
$(this).children('').each(function(){
if($(this).attr("change_v")) {
field_k = $(this).attr("field_in_db")
field_v = $(this).attr("change_v")
record = field_v
}
})
update_list.push(record);
})
$.ajax({
url: requestURL,
type: 'POST',
data: {'update_list': JSON.stringify(update_list)},
dataType: 'json',
success:function (arg) {
if(arg.status=='ok'){
initTbody(1)
}
}
})
})
}
function BindDel() {
// 删除按钮要获取当前选中行的数据库id,还要弹窗提示确认
$('#Del').click(function () {
del_list=[]
$('#table_td').find(":checked").each(function () {
record={}
// save找的是tr,这里是td,所以需parent
id_v=$(this).parent().parent().attr("old_data_id")
if(id_v!=undefined) {
record["id"] = id_v
del_list.push(record)
}
})
var r=confirm("确定删除?");
if(r){
$.ajax({
url: requestURL,
type: 'POST',
data: {'del_list': JSON.stringify(del_list)},
dataType: 'json',
success:function (arg) {
if(arg.status=='ok'){
initTbody(1)
}
}
})
}
})
}
jQuery.extend({
'CreateCURD':function (url) {
requestURL = url;
initTable(1);
BindEditMode();
BindCheckboxEditMode();
BindSelectAll();
BindCancel();
BindReserve();
BindSave();
BindDel();
},
'TurnToPager':function (num) {
inittable(num);
}
})
}) 前端代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
<style>
.data-display{
margin: 200px;
}
</style>
</head>
<body>
<div class="data-display">
<div class="btn-group" role="group" aria-label="...">
<button id="SelectAll" type="button" class="btn btn-default">全选</button>
<button id="Reserve" type="button" class="btn btn-default">反选</button>
<button id="Cancel" type="button" class="btn btn-default">取消</button>
<button id="EditMode" type="button" class="btn btn-default">进入编辑模式</button>
<button id="Del" class="btn btn-default">批量删除</button>
<button id='Save' type="button" class="btn btn-default">保存</button>
</div>
<table class="table table-bordered" id="Datatable">
<thead id="table_th"></thead>
<tbody id="table_td"></tbody>
</table>
</div>
</body>
<script src="/static/js/jquery-3.5.1.min.js"> </script>
<script src="/static/js/CURDbyLinzb.js"> </script>
<script>
$(function () {
$.CreateCURD( 'getCurdData')
})
</script>
</html>
页:
[1]