bootstrap table クエリパラメータの再構築#
queryParams:function(params){
let filter = JSON.parse(params.filter);
let op = JSON.parse(params.op);
//検索条件の再構築
filter['game.game_mode'] = 0;
filter['game.play_mode'] = 0;
op['game.game_mode'] = '=';
op['game.play_mode'] = '=';
params.filter = JSON.stringify(filter);
params.op = JSON.stringify(op);
console.log(params);
return params;
}
テーブルのフッター統計とボタンをクリップボードにコピーするなどの小機能#
- Table.api.init 内に showFooter 設定を追加し、フッターを有効にする
- columns {field} に footerFormatter を追加し、統計表頭として使用する
- 統計が必要な列にコード footerFormatter(rows){
return sumFormatter(rows,this.field)
} - js メソッドとスクロールバーのコードを追加(スクロールバーがある場合、フッターがスクロールバーに従ってスクロールする)
- 上級者向けに、checkbox を監視し、ページは選択されたデータのみを統計する。checkData と table.bootstrapTable ('resetFooter') を使用する
define(['jquery', 'bootstrap', 'backend', 'table', 'form','layui'], function ($, undefined, Backend, Table, Form) {
var Controller = {
index: function () {
// テーブルパラメータの初期化
Table.api.init({
showFooter:true, //ここでの設定が有効
extend: {}
});
var table = $("#table");
//ポップアップのサイズを変更
$('.btn-edit').data('area',["75%","75%"])
// テーブルの初期化
table.bootstrapTable({
columns: [
[
{checkbox: true},
{field: 'id', title: __('Id')},
{field: 'operate', title: __('Operate'), table: table,
buttons: [
{
name: 'pwd',
text: __('Copy Account'),
icon: 'fa fa-copy',
classname: 'btn btn-xs btn-primary btn-ajax',
url: 'auth/admin/pwd?u={accname}',
success: function (data, ret) {
let info = 'バックエンドアドレス:' + data.url + '\nアカウント:' + data.username + '\nパスワード:' + data.pass;
//使用方法
var ct =new copy_txt();
ct.copy(info);//"xxx"をクリップボードにコピー
},
error: function (data, ret) {
console.log(data, ret);
Layer.alert(ret.msg);
return false;
},
visible: function (row) {
//trueを返すとボタンが表示され、falseを返すと非表示
if (row.account){
return true;
}else{
return false;
}
}
}
], events: Table.api.events.operate, formatter: Table.api.formatter.operate},
{field: 'userName', title: __('Nickname'), operate: 'LIKE',footerFormatter:totalTextFormatter},
{field: 'balance', title: __('Balance'),operate:false,operate:false,footerFormatter:function(rows){
return sumFormatter(rows,this.field)
}},
{field: 'frozen', title: __('Frozen Balance'),operate:false,operate:false,footerFormatter:function(rows){
return sumFormatter(rows,this.field)
}},
]
]
});
//checkboxを監視
table.on('check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table post-body.bs.table', function (e) {
checkData = Table.api.selecteddata(table);
table.bootstrapTable('resetFooter');
})
//特定の列を非表示にすることができます
if (!Config.show) {
table.bootstrapTable('hideColumn','statmidday.platformFee');
table.bootstrapTable('hideColumn','platformFee');
table.bootstrapTable('hideColumn','frozenPlatformFee');
}
//テーブル内のボタンを変更
table.on('post-body.bs.table',function () {
$('.btn-editone').data('area',["75%","75%"])
})
var copy_txt=function(){//コンポーネントなしでクリップボードにコピー
var _this =this;
this.copy=function(txt){
$("#input_copy_txt_to_board").val(txt);//値を設定
$("#input_copy_txt_to_board").removeClass("hide");//表示
$("#input_copy_txt_to_board").focus();//フォーカスを取得
$("#input_copy_txt_to_board").select();//選択
document.execCommand("Copy");
$("#input_copy_txt_to_board").addClass("hide");//非表示
}
//-----------
let html ='<textarea class="hide" id="input_copy_txt_to_board" /></textarea>';//隠れた要素を追加(改行可能)
//let html ='<input type class="hide" id="input_copy_txt_to_board" value="" />';//隠れた要素を追加
$("body").append(html);
}
//スクロールバーを監視
$(".fixed-table-body").on("scroll",function(){
var sl=this.scrollLeft;
$(this).next()[0].scrollLeft = sl;
})
// テーブルにイベントをバインド
Table.api.bindevent(table);
},
//ページのポップアップ編集ボックス、変更を送信し、バックエンドで現在のページを更新
keepamount: function () {
Form.api.bindevent("form[role='form']", function(res){
parent.location.reload();//ここで親ページをリフレッシュできます。他のコードに変更可能
});
},
api: {
bindevent: function () {
Form.api.bindevent($("form[role=form]"));
}
}
};
return Controller;
});
//フッター統計js 開始
function totalTextFormatter() {
return '合計:';
}
let checkData = [];
function sumFormatter(rows,value,format= false) {
if (checkData.length) {
rows = checkData;
}
var sum = 0;
for (var i=0;i<rows.length;i++) {
sum += Number(rows[i][value])
}
let result = 0;
if (format){
result = sum.toString();
}else {
result = toDecimal2(sum)
}
return result;
}
function toDecimal2(x) {
var f = Math.round(x * 100) / 100;
var s = f.toString();
var rs = s.indexOf('.');
if (rs < 0) {
rs = s.length;
s += '.';
}
while (s.length <= rs + 2) {
s += '0';
}
return s;
}
//フッター統計js 終了
上級者向け チェックボックスの選択に基づいて、フッター統計を行う#
checkData と table.bootstrapTable ('resetFooter'); を使用して実現
//checkboxを監視
table.on('check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table post-body.bs.table', function (e) {
checkData = Table.api.selecteddata(table);
table.bootstrapTable('resetFooter');
})
let checkData = [];
function sumFormatter(rows,value,format= false) {
if (checkData.length) {
rows = checkData;
}
var sum = 0;
for (var i=0;i<rows.length;i++) {
sum += Number(rows[i][value])
}
let result = 0;
if (format){
result = sum.toString();
}else {
result = toDecimal2(sum)
}
return result;
}
注意
public/assets/libs/bootstrap-table/dist/bootstrap-table.js の resetFooter はデフォルトで開放されていません
コードを修正する必要があります。おおよそ 3016 行目、resetFooter を末尾に追加します。
var allowedMethods = [... 省略された他のメソッド名,'resetFooter']
修正後、js を圧縮し、同じディレクトリの bootstrap-table.min.js にコピーします。
最後に実行します。
php think min -m backend -r all
テーブルフッターのバグ - フッター統計と列が整列しない#
フッターの各セルが 1 ピクセル多くなっているように見え、整列しない
後でこのフッター生成の js を見つけて、いくつかの修正を行いました。
public/assets/libs/bootstrap-table/dist/bootstrap-table.js のおおよそ 2288 行目
下のコードは元のもので、上の行は私の修正です。
$footerTd.eq(i).find(".fht-cell").width($this[0].getBoundingClientRect().width - 1)
//$footerTd.eq(i).find(".fht-cell").width($this.innerWidth())
修正後、圧縮して同じディレクトリの bootstrap-table.min.js にコピーする必要があります。
オンライン圧縮ツール
そのため、最後に実行する必要があります。
php think min -m backend -r all
テーブルフッターのバグ - フッターと固定列の CSS 問題#
フッターと固定列を同時に有効にすると、固定列が余分な部分を持つことがあり、CSS スタイルで削除できます。
<style>
.fixed-table-container .fixed-columns {
height: calc(100% - 116px) !important;
}
</style>
#tableで固定列を有効にする
table.bootstrapTable({
url: $.fn.bootstrapTable.defaults.extend.index_url,
pk: 'id',
sortName: 'id',
searchFormVisible: true,
toolbar: '#toolbar',
fixedColumns: true, //固定列を有効にする
fixedNumber: 2, //左側の列を固定
#省略..
})
public/assets/libs/bootstrap-table/dist/bootstrap-table.js#
BootstrapTable.prototype.fitFooter = function () {
//....
//todo $this.innerWidth() このバージョンのjsは精度の数字を取得できません。修正後、bootstrap-table.min.jsを圧縮してください。
this.$body.find('>tr:first-child:not(.no-records-found) > *').each(function (i) {
var $this = $(this);
$footerTd.eq(i).find(".fht-cell").width($this[0].getBoundingClientRect().width - 1)
//$footerTd.eq(i).find(".fht-cell").width($this.innerWidth())
});
};
タブページ 多テーブル#
<div class="panel panel-default panel-intro">
{:build_heading()}
<ul class="nav nav-tabs main">
{foreach name="typeList" item="vo" index="i"}
<li {if $i==1}class="active"{/if}><a href="#{$key}" data-toggle="tab">{$vo}</a></li>
{/foreach}
</ul>
<div class="panel-body">
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade active in" id="one">
<div class="widget-body no-padding">
<div id="toolbar" class="toolbar">
{:build_toolbar('refresh,add,delete')}
</div>
<table id="table" class="table table-striped table-bordered table-hover"
data-operate-edit=false
width="100%">
</table>
</div>
</div>
<div class="tab-pane fade" id="two">
<div class="widget-body no-padding">
<div id="toolbar2" class="toolbar">
{:build_toolbar('refresh,add,delete')}
</div>
<table id="table2" class="table table-striped table-bordered table-hover"
data-operate-edit=false
width="100%">
</table>
</div>
</div>
</div>
</div>
</div>
対応する js
index: function () {
Table.api.init();
//イベントをバインド
$('.main a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
var panel = $($(this).attr("href"));
console.log(panel)
if (panel.size() > 0) {
Controller.table[panel.attr("id")].call(this);
$(this).on('click', function (e) {
console.log(1)
$($(this).attr("href")).find(".btn-refresh").trigger("click");
});
}
//バインドされたイベントを削除
$(this).unbind('shown.bs.tab');
});
//必ずデフォルトでshown.bs.tabイベントをトリガーする
$('ul.nav-tabs li.active a[data-toggle="tab"]').trigger("shown.bs.tab");
},
table: {
one: function () {
var table = $("#table");
// テーブルの初期化
table.bootstrapTable({
url: '',
extend: {
index_url: '',
add_url: '',
del_url: '',
table: '',
},
pk: 'id',
sortName: 'weigh',
toolbar:'#toolbar',
columns: [
[
{checkbox: true},
{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
]
],
sidePagination: "client", //クライアントサイドのページネーション
});
// テーブルにイベントをバインド
Table.api.bindevent(table);
},
two: function () {
var table = $("#table2");
// テーブルの初期化
table.bootstrapTable({
url: '',
extend: {
index_url: '',
add_url: '',
del_url: '',
table: '',
},
pk: 'id',
sortName: 'weigh',
toolbar:'#toolbar2',
columns: [
[
{checkbox: true},
{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
]
],
sidePagination: "client", //クライアントサイドのページネーション
});
// テーブルにイベントをバインド
Table.api.bindevent(table);
},
},
btn-group ボタングループのドロップダウン#
ボタンが多すぎる場合、いくつかのボタンをボタングループにまとめます。
buttons: [
{
name: '',
text: '',
title: '',
classname: 'btn btn-xs btn-info btn-dialog',
icon: 'fa fa-list-alt',
url: '',
extend: 'data-area=\'["650px", "450px"]\'',
dropdown:__('Operate'), //一緒にまとめる必要があるボタンにはすべてdropdownを追加
callback: function (data) {
},
visible: function (row) {
//trueを返すとボタンが表示され、falseを返すと非表示
return true;
}
}
]
btn-group ボタングループの表示があまり親切でないため、CSS スタイルを調整しました。
.dropdown-menu.pull-right {
right: auto;
top: auto;
margin-top: 24px;
}
.dropdown-menu > li > a {
text-align: left;
}
.btn-group {
position: inherit;
display: inline-flex;
}
btn-group 複数のボタングループの間にカンマ#
require-table.js html.unshift (dropdownHtml) を修正し、html.unshift (dropdownHtml.join (' ')) に変更
if (!$.isEmptyObject(dropdowns)) {
var dropdownHtml = [];
$.each(dropdowns, function (i, j) {
dropdownHtml.push('<div class="btn-group"><button type="button" class="btn btn-primary dropdown-toggle btn-xs" data-toggle="dropdown">' + i + '</button><button type="button" class="btn btn-primary dropdown-toggle btn-xs" data-toggle="dropdown"><span class="caret"></span></button><ul class="dropdown-menu dropdown-menu-right"><li>' + j.join('</li><li>') + '</li></ul></div>');
});
html.unshift(dropdownHtml.join(' '));
}
return html.join(' ');
テーブル表示列、全選択と全解除#
index: function () {
// テーブルパラメータの初期化
var table = $("#table");
table.on('post-common-search.bs.table', function (e, settings, json, xhr) {
$("ul.dropdown-menu", settings.$toolbar).prepend("<li role='menucheckall'><label><input type='checkbox' checked> 全選択/反選択</label></li>");
$(document).on("click", "ul.dropdown-menu li[role='menucheckall'] input", function (e) {
e.stopPropagation();
var that = settings;
var checked = $(this).prop('checked');
$("ul.dropdown-menu li[role='menuitem'] input").each(function () {
that.toggleColumn($(this).val(), checked, false);
that.trigger('column-switch', $(this).data('field'), checked);
$(this).prop("checked", checked);
});
});
});
// テーブルにイベントをバインド
Table.api.bindevent(table);
}
単日付 day カスタム検索#
bootstrap table の検索スタイル 単一日付検索
参考リンク
https://ask.fastadmin.net/question/28226.html
[
{field: 'day', title: __('Day'), addclass:'datetimepicker', data: 'data-date-format="YYYYMMDD"'},
]
表示にバグがあります
.bootstrap-table .form-commonsearch .form-group {
white-space: normal;
}
bulid_checkboxs 全選択 / 反選択を追加#
bulid_checkboxs で構築されたチェックボックスには全選択 / 反選択がありません。
ここで配列の先頭に ['' => ' 全選択 / 反選択 '] を追加します。
bulid_checkboxs ('status []',['' => ' 全選択 / 反選択 ',... 他の要素])
さらに js と組み合わせて全選択 / 反選択の効果を達成します。
//チェックボックスの初期化 全選択/反選択がチェックされているかどうか
function init(name) {
let elem = $('input[name="' + name + '"]');
//現在の列のチェックボックス 除外全選択/反選択の要素数
let len = elem.length - 1;
let chk = $('input[name="' + name + '"]:checked');
let chklen = chk.length;
//全選択を除外
if (elem.first().prop("checked")) {
chklen = chk.length - 1;
}
if (len == chklen && chklen != 0){
elem.first().prop("checked",true);
}else {
elem.first().prop("checked",false);
}
}
init('status');
$(":checkbox").on('click',function(){
//現在のnameを取得
let name = $(this).attr('name');
let elem = $('input[name="' + name + '"]');
//現在の列のチェックボックス 除外全選択/反選択の要素数
let len = elem.length - 1;
//全選択/反選択を判断
let checked = $(this).prop('checked');
let key = $(this).val();
if (key == '') {
if (checked) {
elem.prop("checked",true);
} else {
elem.prop("checked",false);
}
}
//もし一つでも未選択の場合は全選択ボタンの選択状態を解除し、全て選択されている場合は全選択ボタンを選択状態に設定
let chk = $('input[name="' + name + '"]:checked');
let chklen = chk.length;
//全選択を除外
if (elem.first().prop("checked")) {
chklen = chk.length - 1;
}
if (len == chklen && chklen != 0){
elem.first().prop("checked",true);
}else {
elem.first().prop("checked",false);
}
})
もしチェックボックスを選択しない場合、php バックエンドはパラメータを [] ではなく [0 => ''] として受け取ります。array_filter を使用してフィルタリングできます。
$status = array_filter($status);
実用的なテーブルリストフィールド表示の最適化、cookie を使用して隠しフィールド機能を記憶します。#
define(['jquery', 'bootstrap', 'backend', 'table', 'form','cookie'], function ($, undefined, Backend, Table, Form) {
var Controller = {
index: function () {
// テーブルパラメータの初期化
var table = $("#table");
// 隠しフィールドの選択イベント、cookieに保存
table.on('column-switch.bs.table', function (e, json) {
var myColumns = [];
$.each(table.bootstrapTable('getHiddenColumns'), function (i, item) {
myColumns.push(item.field);
});
let cookieName = 'fa_{%table%}' //fa_\{%table%\} 反斜線を削除
$.cookie(cookieName, JSON.stringify(myColumns), {expires: 365, path: '/'});
});
if ($.cookie(cookieName)) {
//cookieから隠しフィールドを読み取る
$.each(JSON.parse($.cookie(cookieName)), function (i, item) {
table.bootstrapTable('hideColumn', item);
});
}
// テーブルにイベントをバインド
Table.api.bindevent(table);
}
}
})
現在のウィンドウ内の確認ボックスのトリガーを記録#
$('.btn-release').on('click',function () {
event.preventDefault();
Layer.confirm(__('Confirm Release?'), {
title: __('Confirm Release?'),
}, function (index) {
Fast.api.ajax({
url: "",
}, function (data) {
Layer.closeAll('dialog'); //確認ボックスを閉じる
Fast.api.close(1); //ウィンドウを閉じてデータを返す
parent.$(".btn-refresh").trigger("click"); //親ページのリフレッシュをトリガー
},function () {
});
}, function (index) {
});
});
カスタム検索(ドロップダウン検索)#
fastAdmin には開発サンプルのプラグインがあり、いくつかの便利なテクニックが含まれています。以下のように
var table = $("#table");
//通常の検索がレンダリングされた後
table.on('post-common-search.bs.table', function (event, table) {
var form = $("form", table.$commonsearch);
$("input[name='bankID']", form).addClass("selectpage").data("source", "bank/bank/index").data("primaryKey", "id").data("field", "account").data("orderBy", "id desc");
Form.events.cxselect(form);
Form.events.selectpage(form);
});
let col = [
{checkbox: true},
{field: 'id', title: __('Id')},
{field: 'bankID', title: __('Account'),visible: false},
{field: 'bank.account', title: __('Account'), operate: false},
]
テーブルの高さを固定#
<table data-height="500"></table>
または
table.bootstrapTable({
...
height: 500,
...
})
テーブル表示列の全選択反選択を追加#
//テーブル表示列の全選択反選択を追加
table.on('post-common-search.bs.table', function (e, settings, json, xhr) {
$("ul.dropdown-menu", settings.$toolbar).prepend("<li role='menucheckall'><label><input type='checkbox' checked> 全選択/反選択</label></li>");
$(document).on("click", "ul.dropdown-menu li[role='menucheckall'] input", function (e) {
e.stopPropagation();
var that = settings;
var checked = $(this).prop('checked');
$("ul.dropdown-menu li[role='menuitem'] input").each(function () {
that.toggleColumn($(this).val(), checked, false);
that.trigger('column-switch', $(this).data('field'), checked);
$(this).prop("checked", checked);
});
});
});