分頁方式:
bootstrap-table提供兩種分頁方式,client和server,即客戶端和服務端分頁;
特點:
client端分頁:后台返回所有數據,前台翻頁時不再請求后台。
server端分頁:后台根據前台每次翻頁時傳遞的參數,進行切片查詢數據,每次只返回對應頁面的數據。
弊端:
client端分頁:
1、后台一次查詢所有數據,對服務器造成壓力交大;
2、當頁面存在bootstrap-switch時,由於我是在bootstrap-table中的onLoadSuccess加載完表格后渲染switch開關,
當使用client分頁時,只進行了一次后台查詢,也就是執行了一次onLoadSuccess函數,所以除了第一頁開關按鈕正常,其他頁面都沒有渲染出開關。
server端分頁:
暫無
實現代碼:
server端分頁,前台代碼:
<script type="text/javascript"> $('#mytab').bootstrapTable({ {#全部參數#} //請求后台的URL(*)或者外部json文件,json內容若為json數組[{"id": 0,"name": "Item 0","price": "$0"},{"id": 1,"name": "Item 1","price": "$1"}], //且鍵的名字必須與下方columns的field值一樣,同時sidePagination需要設置為client或者直接注釋掉,這樣前台才能讀取到數據,且分頁正常。 //當json文件內容為json對象時:{"total": 2,"rows": [{"id": 0,"name": "Item 0","price": "$0"},{"id": 1,"name": "Item 1","price": "$1"}]}, //分頁要寫為server,但是server如果沒有處理的話,會在第一頁顯示所有的數據,分頁插件不會起作用 {#url: "{% static 'guchen_obj.json' %}", #} url:"/account/user_management_data", //從后台獲取數據時,可以是json數組,也可以是json對象 dataType: "json", method: 'get', //請求方式(*) toolbar: '#toolbar', //工具按鈕用哪個容器 striped: true, //是否顯示行間隔色 cache: false, //是否使用緩存,默認為true,所以一般情況下需要設置一下這個屬性(*) pagination: true, //是否顯示分頁(*) sortable: true, //是否啟用排序 sortOrder: "asc", //排序方式 {#queryParams: oTableInit.queryParams,//傳遞參數(*)#} sidePagination: "server", //分頁方式:client客戶端分頁,server服務端分頁(*),數據為json數組時寫client,json對象時(有total和rows時)這里要為server方式,寫client列表無數據 pageNumber: 1, //初始化加載第一頁,默認第一頁 pageSize: 5, //每頁的記錄行數(*) pageList: [10, 25, 50, 100], //可供選擇的每頁的行數(*) {#search: true, //是否顯示表格搜索,此搜索是客戶端搜索,不會進服務端,所以,個人感覺意義不大#} strictSearch: true, showColumns: true, //是否顯示所有的列 showRefresh: true, //是否顯示刷新按鈕 minimumCountColumns: 2, //最少允許的列數 clickToSelect: true, //是否啟用點擊選中行 {#height: 500, //行高,如果沒有設置height屬性,表格自動根據記錄條數覺得表格高度#} uniqueId: "ID", //每一行的唯一標識,一般為主鍵列 showToggle: false, //是否顯示詳細視圖和列表視圖的切換按鈕 cardView: false, //是否顯示詳細視圖 detailView: false, //是否顯示父子表 idField: 'project_name', //指定主鍵 singleSelect: true, //開啟單選,想要獲取被選中的行數據必須要有該參數 //得到查詢的參數,會在url后面拼接,如:?rows=5&page=2&sortOrder=asc&search_kw=&_=1564105760651 queryParams: function (params) { //這里的鍵的名字和控制器的變量名必須一直,這邊改動,控制器也需要改成一樣的 var query_params = { rows: params.limit, //頁面大小 page: (params.offset / params.limit) + 1, //頁碼 sort: params.sort, //排序列名 sortOrder: params.order, //排位命令(desc,asc) //查詢框中的參數傳遞給后台 search_kw: $('#search-keyword').val(), // 請求時向服務端傳遞的參數 }; return query_params; }, columns: [ { checkbox:true //第一列顯示復選框 }, { field: 'member_code', //返回數據rows數組中的每個字典的鍵名與此處的field值要保持一致 title: '工號' }, { field: 'name', title: '姓名' }, { field: 'role', title: '角色' }, { field: 'create_time', title: '創建時間' }, { field: 'status', title: '狀態', formatter: user_status, }, { field: 'operate', title: '操作', width: 120, align: 'center', valign: 'middle', formatter: actionFormatter, }, ], onLoadSuccess: function(data){ {#獲取行數據的狀態#} console.log('渲染數據完成后,打印所有數據') console.log(data); {#獲取所有列表數據#} var data=$("#mytab").bootstrapTable("getData"); console.log('已獲取全部數據%s',data); {#根據每行數據的status值渲染開關#} for (var i=0;i<data.length;i++){ console.log(data[i].project_id,data[i].status) if (data[i].status == 1){ console.log('這個是開啟的') $("[id='project_status_switch_on']").bootstrapSwitch({ onText: "啟用", // 設置ON文本 offText: "禁用", // 設置OFF文本 onColor: "success",// 設置ON文本顏色(info/success/warning/danger/primary) offColor: "danger", // 設置OFF文本顏色 (info/success/warning/danger/primary) size: "small", // 設置控件大小,從小到大 (mini/small/normal/large) // 當開關狀態改變時觸發 onSwitchChange : function(event, state) { console.log(state); {#獲取該行的project_id#} var project_id = this.value; console.log(project_id); if (state == false) { status=1 {#alert("ON");#} console.log(status); set_status(project_id, status); } else { status=0 {#alert("OFF");#} set_status(project_id, status); } } }) }else{ console.log('這個是禁用的') $("[id='project_status_switch_off']").bootstrapSwitch({ onText: "啟用", // 設置ON文本 offText: "禁用", // 設置OFF文本 onColor: "success",// 設置ON文本顏色(info/success/warning/danger/primary) offColor: "danger", // 設置OFF文本顏色 (info/success/warning/danger/primary) size: "small", // 設置控件大小,從小到大 (mini/small/normal/large) // 當開關狀態改變時觸發 onSwitchChange : function(event, state) { console.log(state); {#獲取該行的project_id#} var project_id = this.value; console.log(project_id); if (state == false) { status=1 {#alert("ON");#} console.log(status); set_status(project_id, status); } else { status=0 {#alert("OFF");#} set_status(project_id, status); } } }) } } } }); //操作欄的格式化,value代表當前單元格中的值,row代表當前行數據,index表示當前行的下標 function actionFormatter(value, row, index) { var id = index; var data = JSON.stringify(row); var result = ""; {#result += "<a href='javascript:;' class='btn btn-xs green' onclick=\"EditViewById('" + id + "', view='view')\" title='查看'><span class='glyphicon glyphicon-search'></span></a>";#} {#result += "<a href='javascript:;' class='btn btn-xs blue' onclick=\"EditViewById('" + JSON.stringify(row) + "','" + id + "')\" title='編輯'><span class='glyphicon glyphicon-pencil'></span></a>";#} result += "<a href='javascript:;' class='btn btn-xs blue' onclick=\"EditViewById('" + row + "','" + id + "')\" title='編輯'><span class='glyphicon glyphicon-pencil'></span></a>"; {#result += "<a href='javascript:;' class='btn btn-xs blue' onclick=\"edit()\" title='編輯'><span class='glyphicon glyphicon-pencil'></span></a>";#} {#result += "<a href='javascript:;' class='btn btn-xs red' onclick=\"DeleteByIds('" + id + "')\" title='刪除'><span class='glyphicon glyphicon-remove'></span></a>";#} return result; } {#狀態欄格式化,根據該行數據的status的值控制checked屬性是否選中#} function user_status(value, row, index) { var data = JSON.stringify(row); //獲取該行數據 var data_json = JSON.parse(data); console.log(data_json); console.log('格式化最先被執行') {#for (var i=0;i<data_json.length;i++){#} {# console.log('第%s行的狀態為%s',i,data_json.status);#} if (data_json.status == 1) { console.log('設置為開啟') return "<input value='"+data_json.project_id+"' type='checkbox' checked id='project_status_switch_on' name='mycheck'>"; } else { console.log('設置為關閉') return "<input value='"+data_json.project_id+"' type='checkbox' id='project_status_switch_off' name='mycheck'>"; } } // 搜索查詢按鈕觸發事件 $(function() { $("#search-button").click(function () { $('#mytab').bootstrapTable(('refresh')); // 很重要的一步,刷新url! $('#search-keyword').val() }) }) //重置搜索條件 function clean(){ //先清空 $('#search-keyword').val(''); //清空后查詢條件為空了,再次刷新頁面,就是全部數據了 $('#mytab').bootstrapTable(('refresh')); // 很重要的一步,刷新url! } </script>
server端分頁,后台代碼:
def user_management_data(request): """ 如果是get請求則只展示用戶數據, post請求新增用戶 :param request: :return: """ if request.method == 'GET': search_kw = request.GET.get('search_kw', None) print search_kw # 獲取分頁參數用於查詢對應頁面數據,page為第幾頁,num為每頁數據條數,right_boundary為數據切片的右側邊界 page = request.GET.get('page') num = request.GET.get('rows') right_boundary = int(page)*int(num) print page,num,int(page)*int(num) # 如果搜索關鍵字不為空,則根據此關鍵字模糊查詢工號和姓名 if search_kw: page_user = User.objects.filter(Q(member_code__contains=search_kw) | Q(name__contains=search_kw))[int(num)*(int(page)-1):right_boundary] # 獲取查詢結果的總條數 total = User.objects.filter(Q(member_code__contains=search_kw) | Q(name__contains=search_kw)).count() print '查詢結果總數為:%s' % total else: # 根據前台傳來的分頁信息,頁碼(page)和每頁條數(rows),計算分頁后的user對象片段,例如前台傳來第2頁的參數, # rows=10,page=2,則服務端需要給前台返回[10:20]的數據片段,切片是左閉右開,所以最大只會取到下標為10到19,共10個數據 page_user = User.objects.all()[int(num)*(int(page)-1):right_boundary] # server端分頁時必須返回total和rows,total用於分頁時顯示總數 total = User.objects.all().count() # rows為具體數據 rows = [] # 遍歷查詢出的user對象,將對應數據放到rows中 for user in page_user: rows.append({'member_code': user.member_code, 'name': user.name, 'role': user.role_name.role_name, 'create_time': user.create_time, 'status': user.status}) print rows # return render(request, 'account/user_management.html', {'rows': json.dumps(rows, cls=DateEncoder)}) # 序列化數據,因為有datetime類型數據,所以使用自定義類DateEncoder序列化 return HttpResponse(json.dumps({'total': total, 'rows': rows}, cls=DateEncoder))