• 表格组件神器:bootstrap table详细使用指南


    1、bootstrap-table简介

    • 1.1、bootstrap table简介及特征:

             Bootstrap table是国人开发的一款基于 Bootstrap 的 jQuery 表格插件,通过简单的设置,就可以拥有强大的单选、多选、排序、分页,以及编辑、导出、过滤(扩展)等等的功能。目前在github上已经有2600多个Star,可见其受欢迎程度。其官方网站地址 为:http://bootstrap-table.wenzhixin.net.cn/。里面可以下载使用所需的JS和CSS文件,以及参考文档和例子。

    • 支持 Bootstrap 3 和 Bootstrap 2
    • 自适应界面
    • 固定表头
    • 非常丰富的配置参数
    • 直接通过标签使用
    • 显示/隐藏列
    • 显示/隐藏表头
    • 通过 AJAX 获取 JSON 格式的数据
    • 支持排序
    • 格式化表格
    • 支持单选或者多选
    • 强大的分页功能
    • 支持卡片视图
    • 支持多语言
    • 支持插件
    • 1.2、bootstrap table渲染数据到表格的方式:

    Bootstrap-Table显示数据到表格的方式有两种,一种是客户端(client)模式,一种是服务器(server)模式
    所谓客户端模式,指的是在服务器中把要显示到表格的数据一次性加载出来,然后转换成JSON格式传到要显示的界面中,在JavaWeb中可以保存在request中,然后转发到指定界面,在界面初始化的时候使用EL表达式获取,然后调用相关初始化的函数,将JSON字符串传进去即可显示。客户端模式较为简单,它是把数据一次性加载出来放到界面上,然后根据你设置的每页记录数,自动生成分页。当点击第二页时,会自动加载出数据,不会再向服务器发送请求。同时用户可以使用其自带的搜索功能,可以实现全局数据搜索。对于数据量较少的时候,可以使用这个方法。但是对于数据量大的系统,使用该方法会造成加载出一些很久之前的,用户不在关注的数据,使得加载速度变慢,增加了服务器的负担,浪费了资源。这时应该采用服务器模式。
    所谓服务器模式,指的是根据设定的每页记录数和当前要显示的页码,发送数据到服务器进行查询,然后再显示到表格中。该方法可以根据用户的需要动态的加载数据,节省了服务器的资源,但是不能使用其自带的全数据搜索功能。因为你加载的数据只是一页的数据,所以全数据搜索的范围也只在一页之中。
    客户端模式较为简单,读者可根据官方文档和例子自行实践。这里主要介绍服务器模式,并可以实现带参数的查询。

    2、bootstrap-table的引入

    关于Bootstrap Table的引入,一般来说还是两种方法:
       2.1、直接使用免费且稳定的cdn服务:
      如:Bootstrap中文网开源项目免费 CDN 服务,搜索自己所需要的较稳定的版本。

         

    • 首先,Bootstrap 的所有 JavaScript 插件都依赖 jQuery,因此 jQuery 必须在 Bootstrap 之前引入,目前使用稳定版本jquery.1.12.1.js.
    • 其次,Bootstrap Table是Bootstrap的一个组件,所以它是依赖Bootstrap的,我们首先需要添加Bootstrap的引用。直接在搜索框中搜索bootstrap,版本已经出来4的预览版,但还是建议使用比较稳定的Bootstrap3,目前最新的3.3.5。
    • 最后,就是Bootstrap Table的包了,直接在搜索框中搜索bootstrap-table,目前较好的版本为1.11.1,或者我们直接进到它的源码git clone https://github.com/wenzhixin/bootstrap-table,下载下来放到项目中即可。

    2.2、使用visual studio自带的包管理工具:Nuget
    NuGet的官方说明是:NuGet是一款Visual Studio的扩展,它可以简单的安装、升级开源库和工具。
    官网地址:http://www.nuget.org/
    从官网下载安装完成之后,就可以在vs中使用了。使用方法如下:
    右键点击解决方案,如图:

       选择 “管理解决方案的NuGet的程序包”,出现如图:

        

      依次搜索jquery ,bootstrap,bootstrap-table等放入本地文件夹。如果发现里面的版本较低,可以使用Bootstrap中文网开源项目免费 CDN 服务,获取最新的版本。

    3、代码详解

    3.1、在html页面引用相关组件,并定义好一个空的表格。

    复制代码
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="Cache-Control" content="no-cache">
        <title>登录信息</title>
        <!-- 1、Jquery组件引用-->
        <script src="../js/jquery.min.js?v=1.11.2"></script>
        <!-- 2、bootstrap组件引用-->
        <link href="../css/bootstrap.min.css?v=3.3.6" rel="stylesheet">
        <script src="../js/bootstrap.min.js?v=3.3.6"></script>
        <!-- 3、bootstrap-table组件引用-->
        <link href="../css/plugins/bootstrap-table/bootstrap-table.min.css?v=1.11.1" rel="stylesheet" />
        <script src="../js/plugins/bootstrap-table/bootstrap-table.min.js?v1.11.0"></script>
        <script src="../js/plugins/bootstrap-table/bootstrap-table-zh-CN.js?v1.11.0"></script><!--显示中文-->
        <!-- 4、其他-->
        <link href="../css/font-awesome.min.css" rel="stylesheet" />
        <link href="../css/style.min.css?v=4.1.0" rel="stylesheet">
        <link href="../css/customer_info.css?v=4.1.0" rel="stylesheet" />
        <script src="../js/plugins/layer/laydate/laydate.js"></script>
        <script src="../js/customer_info.js"></script>
    </head>
    <body class="gray-bg">
        <div class="wrapper wrapper-content" id="userLogin">
            <div id="dateSearch">
                <span><strong>开始日期: </strong></span>
                <input type="text" class="laydate-icon startDate"  placeholder="开始日期">
                <span><strong>结束日期: </strong></span>
                <input type="text" class="laydate-icon endDate"  placeholder="结束日期">
                <span><strong>用户ID: </strong></span>
                <input type="text" class="default-input form-control imuserid"   placeholder="请输入用户id">
                <button type="button" class="btn btn btn-info search"> <i class="fa fa-search"></i> 搜索</button>
            </div>
            <div class="row" id="infoArea">
                <div class="col-sm-12" style="padding: 0 10px;">
                    <ul class="nav nav-tabs" id="navList">
                        <li data-name = "loginLogTab" class="active"><a data-toggle="tab" href="#loginLogTab"><i class="fa fa-user"></i>登录信息</a> </li>
                        <li data-name = "receiveLogTab" class=""><a data-toggle="tab" href="#receiveLogTab"><i class="fa fa-briefcase"></i> 订购信息</a> </li>
                        <li data-name = "socketInputTab" class=""><a data-toggle="tab" href="#socketInputTab"><i class="fa fa-briefcase"></i> 反馈信息</a> </li>
                        <li data-name = "socketOutputTab" class=""><a data-toggle="tab" href="#socketOutputTab"><i class="fa fa-briefcase"></i> 出行信息</a> </li>
                    </ul>
                    <div class="tab-content" id="tabContent">
                          <div id="toolbar" class="btn-group">
                                <button id="btn_add" type="button" class="btn btn-info btn-sm rightSize">
                                    <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>新增
                                </button>
                                <button id="btn_edit" type="button" class="btn btn-info btn-sm rightSize">
                                    <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>修改
                                </button>
                                <button id="btn_delete" type="button" class="btn btn-info btn-sm rightSize">
                                    <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>删除
                                </button>
                            </div>
                        <div id="loginLogTab" class="tab-pane active">
                            <div class="table-responsive">
                                <table id="loginLog-table"></table>
                            </div>
                        </div>
                        <div id="receiveLogTab" class="tab-pane">
                            <div class="table-responsive">
                                <table id="receiveLog-table"></table>
                            </div>
                        </div>
                        <div id="socketInputTab" class="tab-pane">
                            <div class="table-responsive">
                                <table id="sockctInput-table"></table>
                            </div>
                        </div>
                        <div id="socketOutputTab" class="tab-pane">
                            <div class="table-responsive">
                                <table id="sockctOutput-table"></table>
                            </div>
                        </div>
                    </div>
                     
                </div>
            </div>
       </div>
    </body>
    </html>
    
    
    复制代码

    引入需要的文件之后,我们最重要的就是定义一个空的table,如上的 <table id="loginLog-table"></table>。
    当然Bootstrap table还提供了另外两种简单的用法,直接通过$table.bootstrapTable({data: data}),具体参考form-data.html;
    或者直接在table标签里面定义 <table data-toggle="table" data-url="../json/data1.json">,类似“data-...”等相关属性,具体参考table-style.html;这两种方法都不用在js里面注册就可以实现数据的加载,

    但博主觉得这种用法虽然简单,但不太灵活,所以咱们还是统一使用在js里面初始化的方式来使用table组件。

    3.2、Js初始化

    复制代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    var queryParams = function (params) {
          var param = {
              pageIndex: Math.ceil(params.offset / params.limit) + 1,
              pageSize: params.limit,
              order: params.order,
              ordername: params.sort,
              startDateTime: $("#dateSearch .startDate").val(),
              endDateTime: $("#dateSearch .endDate").val(),
              search: $("#dateSearch .imuserid").val()
          };
          return param;
      }
     
      var responseHandler = function (e) {
          console.log(e);
          if (e.data && e.data.length > 0) {
              return { "rows": e.data, "total": e.count };
          }
          else {
              return { "rows": [], "total": 0 };
          }
          
      }
      var uidHandle = function (res) {
          var html = "<a href='#'>"+ res + "</a>";
          return html;
      }
      var operateFormatter = function (value, row, index) {//赋予的参数
          return [
              '<button class="btn btn-info btn-sm rightSize detailBtn" type="button"><i class="fa fa-paste"></i> 详情</button>',
              '<button class="btn btn-danger btn-sm rightSize packageBtn" type="button"><i class="fa fa-envelope"></i> 通知</button>'
          ].join('');
      }
      self.dataInit = function (name) {
          var url, columns, tableName;
          switch (name) {
              case 'loginLogTab':
                  tableName = "loginLog-table";
                  columns = [
                      {
                          checkbox: true
                      },
                      {
                          field: 'uid',
                          title: '用户编号',
                          align: 'center',
                          formatter: uidHandle,//自定义方法设置uid跳转链接
                          300
                      }, {
                          field: 'name',
                          title: '姓名',
                          align: 'center',
                          sortable:false   //本列不可以排序
                      }, {
                          field: 'sex',
                          title: '性别',
                          align: 'center'
                      }, {
                          field: 'age',
                          title: '年龄',
                          align: 'center',
                          sortable: true,
                          clickToSelect: false,
                          sortName: "age",
                          order:"asc"
                      }, {
                          field: 'area',
                          title: '户籍所在地',
                          align: 'left',
                          halign:'center' //设置表头列居中对齐
                      }, {
                          field: 'loginWay',
                          title: '登录方式',
                          align: 'center'
                      }, {
                          field: 'status',
                          title: '状态',
                          align: 'center'
                      },{
                          field: 'createTime',
                          title: '登录时间',
                          align: 'center',
                           90
                      }, {
                          field: 'orderService',
                          title: '购买服务',
                          align: 'center'
                      }, {
                          field: 'connectorIP',
                          title: '连接器IP',
                          align: 'center'
                      }, {
                          field: 'connectorPort',
                          title: '连接器端口',
                          align: 'center'
                      }, {
                          field: 'operate',
                          title: '操作',
                          align: 'center',
                          valign: 'middle',
                          formatter: operateFormatter //自定义方法,添加操作按钮
                      }
                  ];
                  break;
              case 'receiveLogTab':
                  //省略
                  break;
              case 'socketInputTab':
                  //省略
                  break;
              case 'socketOutputTab':
                  //省略
                  break;
          }
          $('#' + tableName).empty();
          $('#' + tableName).bootstrapTable('destroy').bootstrapTable({
              url: '../data/login_info2.json',   //url一般是请求后台的url地址,调用ajax获取数据。此处我用本地的json数据来填充表格。
              method: "get",                     //使用get请求到服务器获取数据
              dataType: "json",
              contentType: 'application/json,charset=utf-8',
              toolbar: "#toolbar",                //一个jQuery 选择器,指明自定义的toolbar 例如:#toolbar, .toolbar.
              uniqueId: "id",                    //每一行的唯一标识,一般为主键列
              height: document.body.clientHeight-165,   //动态获取高度值,可以使表格自适应页面
              cache: false,                       // 不缓存
              striped: true,                      // 隔行加亮
              queryParamsType: "limit",           //设置为"undefined",可以获取pageNumber,pageSize,searchText,sortName,sortOrder 
                                                  //设置为"limit",符合 RESTFul 格式的参数,可以获取limit, offset, search, sort, order 
              queryParams: queryParams,
              sidePagination: "server",           //分页方式:client客户端分页,server服务端分页(*)
             // sortable: true,                     //是否启用排序;意味着整个表格都会排序
              sortName: 'uid',                    // 设置默认排序为 name
              sortOrder: "asc",                   //排序方式
              pagination: true,                   //是否显示分页(*)
              search: true,                       //是否显示表格搜索,此搜索是客户端搜索,不会进服务端,所以,个人感觉意义不大
              strictSearch: true,
              showColumns: true,                  //是否显示所有的列
              showRefresh: true,                  //是否显示刷新按钮
              showToggle:true,                    //是否显示详细视图和列表视图
              clickToSelect: true,                //是否启用点击选中行
              minimumCountColumns: 2,          //最少允许的列数 clickToSelect: true, //是否启用点击选中行
              pageNumber: 1,                   //初始化加载第一页,默认第一页
              pageSize: 10,                    //每页的记录行数(*)
              pageList: [10, 25, 50, 100],     //可供选择的每页的行数(*)
              paginationPreText: "Previous",
              paginationNextText: "Next",
              paginationFirstText: "First",
              paginationLastText: "Last",
              responseHandler: responseHandler,
              columns: columns,
              onLoadSuccess: function (data) { //加载成功时执行
                  console.log(data);
              },
              onLoadError: function (res) { //加载失败时执行
                  console.log(res);
              }
          });
      }
    复制代码

    表格的初始化也很简单,定义相关的参数即可。上面一些博主觉得重要的参数都加了注释,如果你的表格也有太多的页面需求,直接用必须的参数就能解决。
    同样,在columns参数里面其实也有很多的参数需要设置,比如列的排序,对齐,宽度等等。这些博主觉得比较简单,不会涉及表格的功能,看看API就能搞定。

         3.3、页面效果图展示:

          

         

    4、其他常用且高级功能

        4.1、实现表格奇偶行,背景颜色隔行显示;

        单一的表格数据显示,看上去有些单调。通过设置表格奇偶行背景颜色隔行显示,会让表格更加生动。实际应用中经常会遇到。实现方法通过添加列方法,如图:

       

    复制代码
    var rowStyle = function (row, index) {
        var classes = ['success', 'info'];
        if (index % 2 === 0) {//偶数行
            return { classes: classes[0]};
        } else {//奇数行
            return {classes: classes[1]};
        }
    }
    复制代码

      效果如图:

         

     4.2、实现表格行列合并;

       表格的行列合并功能不用引用其他的js文件,只需要在html页面使用table的colspan和rowspan即可实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    <table id="receiveLogs-table"
         class="table table-hover"  
           data-pagination="true"
           data-show-refresh="false" 
           data-show-toggle="false" 
           data-showColumns="false"
           data-toggle="table"
           data-row-style="rowStyle"
           <strong>data-url="../data/login_info.json"</strong>>
        <thead>
        <tr>
            <th colspan="5" data-valign="middle" data-halign="center">用户基本信息</th>
            <th colspan="6" data-valign="middle" data-halign="center">用户购买信息</th>
            <th rowspan="2" data-field="operate" data-valign="middle" data-halign="center" data-formatter="operateFormatter">操作</th>
        </tr>
        <tr>
            <th data-field="uid" data-align="center" data-formatter="setCode">用户编号</th>
            <th data-field="name" data-align="center">姓名</th>
            <th data-field="sex" data-align="center">性别</th>
            <th data-field="age" data-align="center" data-sortable="true">年龄</th>
            <th data-field="area" data-align="center">户籍所在地</th>
     
            <th data-field="loginWay" data-align="center">登录方式</th>
            <th data-field="status" data-align="center">状态</th>
            <th data-field="createTime" data-align="center">登录时间</th>
            <th data-field="orderService" data-align="center">购买服务</th>
            <th data-field="connectorIP" data-align="center">连接器IP</th>
            <th data-field="connectorPort" data-align="center">连接器端口</th>
        </tr>
        </thead>
    </table>

      要添加操作按钮和奇偶行背景颜色隔行显示,需要添加相应的js方法,如下:

        

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    function operateFormatter(value, row, index) {//赋予的参数
        return [
            '<button class="btn btn-info btn-sm rightSize detailBtn" type="button"><i class="fa fa-paste"></i> 详情</button>',
            '<button class="btn btn-danger btn-sm rightSize packageBtn" type="button"><i class="fa fa-envelope"></i> 通知</button>'
        ].join('');
    }
     
    var rowStyle = function (row, index) {
        var classesArr = ['success', 'info'];
        if (index % 2 === 0) {//偶数行
            return { classes: classesArr[0] };
        } else {//奇数行
            return { classes: classesArr[1] };
        }
    }
    window.operateFormatter = operateFormatter;
    window.rowStyle = rowStyle;

      效果如图:

    5、遇到的问题及解决方法

      5.1、当请求返回的数据结果不是固定的“total”,"rows"的格式时,如何渲染表格数据?
        我们运用$('#' + tableName).bootstrapTable({ url: '../data/login_info.json'}),请求json数据,必须要求json数据格式为固定的key值,即必须按照“total”,"rows"的格式才能填充数据到表格,如图所示:

         

    但是,当接口返回的数据格式,不是固定的“total”,"rows"时,我们需要用到一个转换函数responseHandler,将数据指引到“total”,"rows"上去。
    即用login_info2.json和参数responseHandler实现数据填充。
    login_info2.json的数据格式,如图:

        添加的responseHandler的方法,如图:

        

      

      将返回结果通过方法引导,也能实现数据的填充。

         5.2、Bootstrap Table自带的搜索功能,在服务器模式和客户端模式的应用说明:

    由于实际应用中,一般请求服务端,返回的数据会很多,所以一般都会用服务器模式加载数据。故通过 search: true显示的内部模糊匹配功能不常用。当然服务器模式加载的数据也可以实现搜索功能,即将数据传入后台,后台处理之后返回前端。
    但是如果你需要对多个字段进行模糊匹配,那么就意味着你的后台需要去对多个数据字段进行like操作,这样查询效率肯定低下。所以,如果需要模糊匹配的字段很多,这个search在实际项目中是用不上的。综上,博主还是觉得只有在客户端分页的时候,这个搜索的作用比较明显。

    复制代码
     var queryParams = function (params) {
          var param = {
              pageIndex: Math.ceil(params.offset / params.limit) + 1,
              pageSize: params.limit,
              search:$("#dateSearch .imuserid").val()
          };
          return param;
       }
    复制代码

        5.3、Bootstrap Table的排序,在服务器模式和客户端模式的应用说明:
        在客户端模式时,排序功能有效。在服务器模式下,通过 sortable: true所设置的排序功能作用也不大,因为它只会排序当前页,不会排序所有的数据;服务器模式要实现排序功能,需要添加排序字段order和ordername给后台,后台处理之后返回前端。

    复制代码
    var queryParams = function (params) {
        var param = {
            pageIndex: Math.ceil(params.offset / params.limit) + 1,
            pageSize: params.limit,
            order: params.order,
            ordername: params.sort
        };
        return param;
    }
    复制代码

    5.4、关于通过“get”方式请求本地.json文件时出现中文乱码的问题:
    在请求本地login_info2.json数据时,请求方式method:'get',设置为“post”时,出现“405”报错;同时,我发现从json文件请求的数据,返回到页面时,出现中文乱码的情况;但是页面上已经设置了<meta charset="utf-8">,同时ajax请求时,也设置了内容返回的字符编码:contentType: 'application/json,charset=utf-8',但还是出现乱码,经过网上查找,找到解决方法是:
    记事本打开json文件,另存为,将编码选择为utf-8,存储替换原来的文件就行了。如图:

        

    6、总结:

      博主也是在做后台管理系统时,初次设计到bootstrap table表格组件,觉得它有自己的优势:

    1. 界面采用扁平化的风格,用户体验比较好,更好兼容各种客户端。这点也是最重要的。
    2. 开源、免费。国人最喜欢的就是免费了。呵呵。
    3. 相对Jqgrid、easyUI而言,比较轻量级。功能不能说最全面,但基本够用。

    7、参考的相关api文档

    原文:http://www.cnblogs.com/wdlhao/p/6694083.html

  • 相关阅读:
    【个人博客设计】
    复杂多边形光栅化算法
    xmake 描述语法和作用域详解
    协程分析之context上下文切换
    tbox协程使用之切换与等待
    记boost协程切换bug发现和分析
    跨平台自动构建工具v1.0.2 发布
    xmake从入门到精通9:交叉编译详解
    xmake从入门到精通9:交叉编译详解
    跨平台c开发库tbox:内存库使用详解
  • 原文地址:https://www.cnblogs.com/yanglang/p/6697657.html
Copyright © 2020-2023  润新知