bootstrap-table行内编辑表格

前端表格插件说明

我们再前端处理表格时,经常会使用bootstrap插件;bootstarp可以完成一些基本的作用,若是我们需要一些高级的功能,如:分页,排序,搜索等功能时bootstrap就显得力不从心了,下面介绍两个专门用于前端表格处理的插件。
1、bootstrap-table: 这个应该时官方的文档,但是文档有很多广告,并且我没找到实例的源码,不过bootstrap-table还有一个说明文档,有很多实例和属性说明,并且还都是中文的:bootstrap-table演示
2、datatables文档:这个插件也可以完成分页,排序,搜索的功能,也可以看一下。
3、bootstrap-edit: 这个主要用于行内编辑表格,也有中文的说明文档: bootstrap-edit中文文档


下面通过一个实例来说明bootstrap-table的简单用法和行内编辑:

bootstrap-table简单使用

因为这些插件下载需要翻墙,这里我们这片文章中用到的插件信息都打包成一个压缩包了,可以直接下载即可:主要有以下四个文件,

[root@localhost bootstrap]# tree
.
├── bootstrap-3.3.7-dist.zip
├── bootstrap3-editable-1.5.1.zip
├── bootstrap-table_v1.13.zip
└── jquery.js

bootstrap-table初始化表格

1、引入需要的js文件和css文件,初始化表格,设置基本属性

<!--引入css文件 -->
<link rel="stylesheet" href="/static/bootstrap/bootstrap-3.3.7-dist/css/bootstrap.css">
<link rel="stylesheet" href="/static/bootstrap/bootstrap-table/css/bootstrap-table.min.css">
<!-- 引入js文件 -->
<script src="/static/js/jquery.js"></script>
<script src="/static/bootstrap/bootstrap-3.3.7-dist/js/bootstrap.js"></script>
<script src="/static/bootstrap/bootstrap-table/js/bootstrap-table.min.js"></script>

html中的body代码可以使用一个单纯的table标签即可,如下:

<div class="row" style="margin-left: 20%; margin-right: 20%">
    <table id="table"></table>
</div>

初始化的可以直接使用如下bootstrap-table即可:

<script type="text/javascript">
    var columns = [{
        field: 'id',
        title: "编号",
        visible: false,
    },{
        field: "env",
        title: "环境"
    },{
        field: "port",
        title: "端口",
    },{
        field: "ip",
        title: "ip地址",
    },{
        field: "db_name",
        title: "database名",
        sortable: true,
    }
    ];
    $("#table").bootstrapTable({
        <!-- 定义表格表头-->
        columns:columns,
        <!-- 从url中获取数据-->
        url: '/query/' ,
        <!-- 获取数据发送请求方式 -->
        method: 'GET',
        <!-- 数据和总数对应的字段 -->
        totalField: 'count',
        dataField: 'data',
        <!-- 分页设置 -->
        pagination: true,          #开启分页
        sidePagination: 'client',  #客户端分页
        pageList: [20,30,50],      #这里显示可选择每页显示的数据量
        pageSize: 10,              #每页默认显示10条数据,
        <!-- 搜索设置-->
        search:true,
        searchOnEnterKey: true,
        <!-- 是否启用排序-->
        sortable:true, #这个字段应该是设置到对应的字段上的,这里只是为了说明
    })
</script>

url查询说明
上面的使用url: '/query/'说明这里的数据是通过这个url查询得到的,后端返回的数据类型应该是json类型,具体格式如下:
注意这里的的count对应上面配置的totalField的值,data字段对应的就是dataField的值。
data中的字段类型需要和上面定义的columns中的字段一一对应 。

{
    "count": 3,
    "data": [
        {
            "id": 1,
            "env": "dev",
            "port": "3309",
            "ip": "10.9.68.41",
            "db_name": "embackend"
        },
        {
            "id": 2,
            "env": "dev",
            "port": "3309",
            "ip": "10.9.68.42",
            "db_name": "live_contents_jzy"
        },
        {
            "id": 3,
            "env": "dev",
            "port": "3309",
            "ip": "10.9.68.42",
            "db_name": "usertipdb"
        }
    ]
}

在这里使用了后端返回的方式,如果数据量不是很多的话,可以直接的上面的html中定义data变量,把需要展示的数据写入到html中。在上面的bootstarp-table演示的文档中有这种形式的实例。

服务端分页

上面的分页是在client端分页完成的,在数据量不是很多时,客户端分页可以节省很多工作量,特别时那个search的模糊搜索功能,我觉得很有用,但是若是如果数据量变得很大的话加载就会变得很慢,这个时候我们就需要用到服务端分页。
前端分页数据一次性加载完毕,如果我们对页面行内进行编辑的话;那么编辑的渲染只会渲染第一页,跳转到第二页之后,因为不会自动执行编辑渲染操作,第二页就无法编辑。因此下面行内编辑页面中使用的是服务端分页

下面给出一个服务端分页设置的实例,如下:

pagination: true,
sidePagination: 'server',     #设置服务的分页
pageNumber:1,                 #设置默认为第一页
pageList: [20,30,50],         #和上面一样,可以改变当前页面展示多少条数据
pageSize: 10,                 #默认每个页显示10条数据
queryParamsType: 'limit',     #发送符合restful格式的参数,默认为limit
queryParams:function(params){
    return {
        pageSize: params.limit,  #传递的是每页显示数据多少条
        pageOffset: params.offset,  #偏移量
    }
},

参数queryParms表示向后端传递的参数,其值是一个函数;当表格初始化时和点击下一页以及搜索时,会产传递这里数据到后端服务中。
通过google的F12可以发现传递的参数如下:

http://192.168.1.121:8000/query/?pageSize=10&pageOffset=10

因为选择的时get请求,所以通过url就可以看到传递的参数。
在js的queryParams中可以通过console.log(params)命令打印出params参数的具体有哪些值。
然后根据传到后端的参数返回需要的数据。
这里使用django作为后端数据传输,需要知道怎么根据offset偏移量和limit计算出哪一个页的数据。后端代码如下:

def query(request):
    if request.method == "GET":
        search_info = {"count":10, "data": []}
        # 计算偏移数据
        offset = int(request.GET.get("pageOffset", 10))
        limit = int(request.GET.get("pageSize", 10))
        start_index = int(offset/limit)
        start_row = start_index * limit
        end_row = start_row + limit
        print(start_row, end_row)
        dbinfo_obj = dbinfo.objects.all()
        query_obj = dbinfo_obj[start_row:end_row]
        search_info["count"] = dbinfo_obj.count()
        for item in query_obj:
            tmp_dict = dict()
            tmp_dict["id"] = item.id
            tmp_dict["env"] = item.env
            tmp_dict["port"] = item.port
            tmp_dict["ip"] = item.ip
            tmp_dict["db_name"] = item.db_name
            search_info["data"].append(tmp_dict)
        return JsonResponse(search_info)

前端的页面如下形式:[说明一点后端传递的总数据count要大于每页显示的数据,不然不会显示下面的分页按钮]
在这里插入图片描述

服务端分页加搜索功能

在使用服务端分页之后,bootstrap-table自带的搜索功能也将无法使用,这个时候就需要自己定义一个搜索。
bootstarp-table自带的搜索功能(前端分页时使用的),默认是模糊搜索,并且可以搜索所有的字段。在页面的最上方加一个搜索框,代码如下:

    <div class="panel">
        <div class="panel-body" style="padding-bottom: 1px;">
                <div class="form-group" >
                    <div class="col-sm-3" style="margin-left: 20%">
                        <!-- 自定义搜索框 -->
                        <input type="text" name="searchString" id="searchString_id" class="form-control" placeholder="请输入搜索内容" onkeydown="" />
                    </div>
                    <div class="col-sm-1">
                        <button type="button" class="btn btn-primary btn-w-m" onclick="searchClick()">
                            <span class="glyphicon glyphicon-search" id="queryBtn"></span> 搜索
                        </button>
                    </div>
                </div>
        </div>
    </div>
</div>

上面有提到queryParams函数里面定义的就是向后端传递的参数,这里需要做的就是把搜索框中的值作为搜索条件传给后端,因此在前端的实现可以这样写:

<-- 初始化这里的 -->
queryParams:function(params){
    console.log(params)
    return {
        pageSize: params.limit,
        pageOffset: params.offset,
        searchString: $("#searchString_id").val()
    }
}
<-- 再给前端的click定义要给函数 -->
function searchClick() {
    keyword = $("#searchString_id").val();
    $("table").bootstrapTable('refresh') 
}

这里完成之后,点击界面的搜索按钮,就会向后端传入searchString参数,这时候传递的url如下:

http://192.168.1.121:8000/query/?pageSize=10&pageOffset=20&searchString=123

在这里插入图片描述问题 如果这样写的这里会有个问题;例如:选择第三页,然后点击搜索,这时候前端会把当前的页面偏移量也传给后端,如果后端根据偏移量计算当前值是会出错的。

http://10.9.8.23/dbApply/mysql/query?queryType=db&pageSize=20&pageIndex=3&searchString=live_contents

解决办法 刷新的时候使用refreshOptions参数而不是refresh参数,这两个参数的区别在于refresh 在现有配置的情况下刷新。有关两个属性的区别可以查看详情
重写searchClick方法如下:

$("table").bootstrapTable('refreshOptions', { pageNumber:1,pageSize:30 });

这样每次搜索时会把pageNumber设置为1,后端处理时就不会过滤掉数据了。
后端处理就是根据传递的参数,返回数据;返回数据的格式和上面的一样。

行内编辑实现

表格的td标签并不能实现行内编辑,若要实现行内编辑,则需要一个a或者span标签。

需求:对上面表格中ip列和库名列进行编辑

1、在ip列和库名列的td标签中加入span标签,这个可以借助bootstrap-table的formatter属性,需要注意的时需要给每一行一个唯一id并且传到后端,这样在后端我们才可以知道前端修改的是哪一行记录。

formatter属性的值是一个函数,并且传入了三个参数,可以使用console.log打印出参数,查看三个参数的值,在变量cocolumns中设置ip的属性如下:

{
    field: "ip",
    title: "ip地址",
    formatter: function (value, row, index) {
        console.log(value, row, index)
    }

使用google浏览器的调试界面,可以看到打印出的三个参数的值如下:
在这里插入图片描述

value的值就是当前的字段值,上面图片中的ip地址
row的值是一个对象,表示的是这一行记录的对象
id值是表示的第几行,这个id值和row对象中的哪个id不一样,row中的哪个id是自己定义的,这里的id是bootstrap-table中的

这个属性可以在渲染td标签,把渲染之后的标签return返回即可:

{
    field: "ip",
    title: "ip地址",
    formatter: function (value, row, index) {
        return "<span id='ip' data-pk=" + row.id + " style='border: none' class='glyphicon glyphicon-edit'>" + value + "</span>"
    }
},{
    field: "db_name",
    title: "database名",
    sortable: true,
    formatter: function (value, row, index) {
        return "<span id='db_name' data-pk=" + row.id + " style='border: none' class='glyphicon glyphicon-edit'>" + value + "</span>"
    }
}

展示界面如下:这样就给td标签添加了一个span标签
在这里插入图片描述
2、引入bootstarp-edit的css文件和js文件,实现行内编辑
引入之后,所有此次需要引入的css和js文件如下:

<!--引入css文件 -->
<link rel="stylesheet" href="/static/bootstrap/bootstrap-3.3.7-dist/css/bootstrap.css">
<link rel="stylesheet" href="/static/bootstrap/bootstrap-table/css/bootstrap-table.min.css">
<link rel="stylesheet" href="/static/bootstrap/bootstrap3-editable/css/bootstrap-editable.css">
<!-- 引入js文件 -->
<script src="/static/js/jquery.js"></script>
<script src="/static/bootstrap/bootstrap-3.3.7-dist/js/bootstrap.js"></script>
<script src="/static/bootstrap/bootstrap-table/js/bootstrap-table.min.js"></script>
<script src="/static/bootstrap/bootstrap3-editable/js/bootstrap-editable.min.js"></script>

上面的所需的文件引入之后,行内编辑实现就很简单,bootstrap-table有个onLoadSuccess事件,当表格加载完成之后,会触发这个事件。

onLoadSuccess:function () {
    $("#table span").editable({
        validate: function (value) {          /**不为空严重 **/
        if (!$.trim(value)) {
            return '不能为空';
        }
    }
    });
}

这个时候点击前端中相应的字段就可以编辑了:
在这里插入图片描述

这样的直接编辑,在刷新数据之后就会丢失,因此我们需要把数据传入到后端;上面的添加span标签时,给它添加了一些属性信息,这些属性信息,在这里会用到。

<span id='db_name' data-pk=" + row.id + " style='border: none' class='glyphicon glyphicon-edit'>" + value + "</span>

data-pk表示的时主键信息,这个属性值不要改变
id 表示的是这个字段的说明信息,后端会根据这个id判断你更改的是那个值
value 就是更改的值了

要传递到后端需要借助url属性,具体代码如下,

onLoadSuccess:function () {
    $("#table span").editable({
        validate: function (value) { //字段验证
        if (!$.trim(value)) {
            return '不能为空';
        }
    },
        url: function (params) {
            params.csrfmiddlewaretoken = "{{ csrf_token }}";
            console.log(params);
            $.ajax({
                url: "/learn/",
                type: "POST",
                data: params,
                dataType: "Json",
                success:function (data) {
                    console.log(data)
                }
            })
        }
    });
}

本质就是一个ajax请求,然后后端根据传入的数据,做update更新处理;后端逻辑不再处理,可以看下点击之后的ajax请求:
在这里插入图片描述
看到ajax传递的值中pk的值取自spandata-pk,name的值取自spanid的值,value的值就是spanvalue值。
最后的csrfmiddlewaretoken的值,是因为django的后端验证,发送POST请求必须要传递,若是使用的非django后端,可以不用传递。
由唯一键,变更的字段名,变更的字段值,就可以在后端确定一条记录并更改。

嵌套表格

bootstrap-table的嵌套表格主要用到detailview属性,只要在初始化表格时加入一个detailView: true,即可,如下:
在这里插入图片描述
这个属性会在表格的最前一列插入一列,点击+号就可以打开隐藏的列,隐藏的列默认时没有任何显示的,可以使用detailFormatter属性来定义隐藏的列该显示什么样的内容,注意这个属性的值是一个函数。

<!-- 嵌套表设置 -->
detailView: true,
detailFormatter: function (index, row) {
    var html = []
    $.each(row, function (key, value) {
      html.push('<p><b>' + key + ':</b> ' + value + '</p>')
    });
    return html.join('');
}

然后在前端展开表格,可以看到如下内容:
在这里插入图片描述
在这个例子中,只是对当前行的数据进行了加工然后换一种方式显示,并没有和后端交互。可以在函数中向后端发送一个ajax请求,然后展示相应的数据。

需求: 点击前面的+号,显示出当前主机的从库信息,这个时候就需要向后端请求数据;显示的从库信息也需要用表格展示。

<!-- 嵌套表设置 -->
detailView: true,
detailFormatter: "detailFormatter",

这里把detailFormatter属性值设置为一个函数,函数就是一个发送ajax请求,然后初始化表格的过程,如下:

/** 子表初始化 **/
function detailFormatter(index, row, $detail) {
    var sub_table = $detail.html('<table></table>').find('table');
    $(sub_table).bootstrapTable({
        url :"/query?queryType=subinfo",
        method: 'get',
        queryParams: { host: row.ip, port: row.port },
        dataField:"data",
        totalField:"count",
        formatNoMatches:function (index, row, $detail) {   /**没有数据返回时候的显示信息**/
            return "当前实例没有从库信息"
        },
        columns: [{
            field: "msg",
            title:"实例说明",
        },{
            field: "ip",
            title: "ip地址"
        },{
            field: "port",
            title: "端口",
        },{
            field: "idc",
            title: "idc",
        }]
    });
}

ajax请求根据传递的参数不同,返回不同的信息,这里返回数据结构和上面的bootstarp-table初始化所需的数据结构是一样的。
在这里插入图片描述
有关bootstrap-table的介绍就结束了,其实最上面的那个连接文档中有很详细的说明。

  • 6
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
回答: 在Bootstrap-Table中,可以使用sortName和sortOrder属性来实现表格的排序功能。当sortName属性设置为"sort",sortOrder属性设置为"desc"时,会生成一个order by子句,按照sort字段降序排列。例如,当使用以下代码初始化表格时: ``` $(function() { var options = { url: prefix + "/list", sortName: "sort", sortOrder: "desc", }; $.table.init(options); }); ``` 生成的sql语句为: ``` SELECT * FROM xxx order by sort desc LIMIT ? ``` 如果需要多个字段排序,可以在sortName属性中使用逗号分隔多个字段,并在sortOrder属性中留空。例如: ``` $(function() { var options = { url: prefix + "/list", sortName: "sort desc,id asc", sortOrder: "", }; $.table.init(options); }); ``` 生成的sql语句为: ``` SELECT * FROM xxx order by sort desc,id asc LIMIT ? ``` 需要注意的是,sortName属性中的字段名会被转换为下划线命名格式(驼峰命名转下划线),例如orderNum会被转换为order_num。所以在sortName属性中应该使用转换后的字段名。参考\[2\] #### 引用[.reference_title] - *1* *2* *3* [【若依(ruoyi)】Bootstrap-Table表格排序](https://blog.csdn.net/sayyy/article/details/122616970)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值