# 控制台中统计图加载变形

从其他菜单进入控制台 触发 btn-refresh resize

// 从其他按钮进入控制台 触发 btn-refresh resize
let chart = Echarts.getInstanceByDom($('#line-chart')[0]);
stat(chart,false);
$(document).on("click", ".btn-refresh", function () {
   setTimeout(function () {
      chart.resize();
   }, 0);
});

# 控制器方法请求事件

// 提交前确认框 方式一
Form.api.bindevent($("form[role=form]"), function(data, ret){
    // 如果我们需要在提交表单成功后做跳转,可以在此使用 location.href="链接"; 进行跳转
    //parent.location.reload ();// 这里刷新父页面,可以换其他代码
    // 提交成功逻辑
}, function(data, ret){
    Layer.closeAll('dialog');
}, function(success, error){
    //bindevent 的第三个参数为提交前的回调
    // 如果我们需要在表单提交前做一些数据处理,则可以在此方法处理
    // 注意如果我们需要阻止表单,可以在此使用 return false; 即可
    // 如果我们处理完成需要再次提交表单则可以使用 submit 提交,如下
    //Form.api.submit(this, success, error);
    var self = this;
    Layer.confirm('yes or no', {
        btn: [__('OK'),__('Cancel')] // 按钮
    }, function(){
        //Layer.closeAll('dialog');
        //self this
        Form.api.submit(self, success, error);
        //return false;
    }, function(){
        //Layer.closeAll('dialog');
        //return false;
    });
    return false;
});
// 提交成功逻辑 Begin (逻辑参考 关闭窗体,显示信息框,确认框关闭后刷新页面)
Fast.api.close(1); // 关闭窗体并回传数据
let _p = parent
parent.Layer.alert(data,{closeBtn: false},()=>{
    _p.location.reload ();// 这里刷新父页面,可以换其他代码
    _p.Layer.closeAll('dialog');
})
return false;
// 提交成功逻辑 End
// 提交前确认框 方式二 (弃用,只能作为参考)
$("#submitbtn").on("click", function(){
                let that = this;
                let content = __('Confirm Application Configuration?');
                Layer.confirm(content, {
                    btn: [__('OK'),__('Cancel')] // 按钮
                }, function(){
                    $(that).closest("form").trigger("submit");
                    Layer.closeAll('dialog');
                    parent.location.reload();// 这里刷新父页面,可以换其他代码
                }, function(){
                    Layer.closeAll('dialog');
                });
                return false;
            });
            Form.api.bindevent($("form[role=form]"), function(data, ret){
                // 如果我们需要在提交表单成功后做跳转,可以在此使用 location.href="链接"; 进行跳转
                parent.location.reload();// 这里刷新父页面,可以换其他代码
            }, function(data, ret){
            }, function(success, error){
                //bindevent 的第三个参数为提交前的回调
                // 如果我们需要在表单提交前做一些数据处理,则可以在此方法处理
                // 注意如果我们需要阻止表单,可以在此使用 return false; 即可
                // 如果我们处理完成需要再次提交表单则可以使用 submit 提交,如下
                //Form.api.submit(this, success, error);
            });
            //Controller.api.bindevent();
}

# Layer.open 和 Layer.confirm

//Layer.open 和 Layer.confirm 共存
$(document).on("click", ".setTemplate", function (index,raw){
   var area = ['40%','40%'];
   Layer.open({
      content: Template("setTemplateTpl",[]),
      zIndex: 99,
      area: area,
      title: __('Set Template Name'),
      resize: false,
      type:1,
      btn: [__('Confirm'), __('Close')],
      yes: function (index, layero) {
         let tplName = $('#tplName').val()
         if (!tplName){
            Toastr.error(__('Cannot be empty'));
            return false
         }
         var templateJson = {};
         var formData = $('form').serializeArray();
         $.each(formData, function() {
            if ($.inArray(this.name,['__token__','begin_time','loop_switch']) < 0){
               templateJson[this.name] = this.value;
            }
         });
         let row = {
            name: tplName,
            templateJson:JSON.stringify(templateJson)
         }
         let content = __('是否保存模板?');
         Layer.confirm(content, {
            type:0,
            btn: [__('OK'),__('Cancel')] // 按钮
         }, function(){
            Fast.api.ajax({
               url: "game/game/setTemplate",
               data: {
                  row:row
               }
            }, function (data) {
               layer.closeAll();
            },function (){
               layer.closeAll('dialog');
            });
            //Layer.closeAll();
         }, function(){
            Layer.closeAll('dialog');
         });
      },
      btn2: function(index, layero){
         // 按钮【按钮二】的回调
         layer.close(index)
         //return false // 禁用该按钮
      },
      success: function (layero, index) {
         // 绑定时间控件
         Form.events.datetimepicker($("form"));
      }
   });
   /*let content = __(' 是否保存模板?');
   Layer.confirm (content, {
       btn: [__('OK'),__('Cancel')] // 按钮
   }, function (){
       Fast.api.open ("game/game/setTemplate", __(' 设置模板名称 '), {
           area:['400px', '200px']
       });
       Layer.closeAll ('dialog');
   }, function (){
       Layer.closeAll ('dialog');
   });*/
})
// 按钮应用 和 Layer.open 绑定时间控件
{field: 'operate', title: __('Operate'), table: table, events: {
   'click .btn-chooseone': function (e, value, row, index) {
      if (row.game_mode == 3 && row.play_mode == 0){
         var area = ['60%','80%'];
         Layer.open({
            content: Template("selectTimeTpl",[]),
            zIndex: 99,
            area: area,
            title: __('Begin_time'),
            resize: false,
            btn: [__('Confirm'), __('Close')],
            yes: function (index, layero) {
               let begin_time = $('#begin_time').val()
               if (!begin_time){
                  Toastr.error(__('Cannot be empty'));
                  return false
               }
               let templateJson = row.templateJson
               templateJson.begin_time = begin_time
               Fast.api.close({templateJson: templateJson});
               layer.closeAll();
            },
            btn2: function(index, layero){
               // 按钮【按钮二】的回调
               layer.close(index)
               //return false // 禁用该按钮
            },
            success: function (layero, index) {
               // 绑定时间控件
               Form.events.datetimepicker($("form"));
            }
         });
      }else{
         let content = __('Confirm Use Template?');
         Layer.confirm(content, {
            btn: [__('OK'),__('Cancel')] // 按钮
         }, function(){
            Fast.api.close({templateJson: row.templateJson});
            Layer.closeAll('dialog');
         }, function(){
            Layer.closeAll('dialog');
         });
      }
   },
}, formatter: function () {
   return '<a href="javascript:;" class="btn btn-danger btn-chooseone btn-xs"><i class="fa fa-check"></i> ' + __('Use Template') + '</a>';
},
},

# 模板 遍历对象字典

<script id="catJsonTpl" type="text/html">
    <div class="showTpl wrap">
        <%for (var key in data) <!--swig0-->%>
    </div>
</script>

# 时间控件 autocomplete off 全局和局部设置

// 在 public/assets/js/require-form.js 设置 $(this).attr ('autocomplete','off'); 并重新压缩 js
$(".datetimerange", form).each(function () {
   $(this).attr('autocomplete','off');
   var callback = typeof $(this).data('callback') == 'function' ? $(this).data('callback') : origincallback;
   $(this).on('apply.daterangepicker', function (ev, picker) {
      callback.call(picker, picker.startDate, picker.endDate);
   });
   $(this).on('cancel.daterangepicker', function (ev, picker) {
      $(this).val('').trigger('blur');
   });
   $(this).daterangepicker($.extend(true, options, $(this).data()), callback);
});
// 在当前控制器 js 设置
table.on('post-body.bs.table',function (e,settings,json,xhr) {
   $('.datetimerange').each(function () {
      $(this).attr('autocomplete','off')
   })
});

// 生成的 input
/extend/fast/Form.php 里,找到 public function input 里的 return 自已加上。然后重新生成一下
// 搜索框 form
如果是查看页顶部的搜索,那是在
public/assets/js/bootstrap-table-commonsearch.js 这个文件里改。差不多在 54 行左右。在 FORM 里加上就行了

# input data-rule 控制生效失效

// 过滤中文和空格
$("input[name='row[utr]']").attr('data-rule','required;filter(\u0391-\uFFE5\\s)')
// 过滤非大小写字母和数字
$("input[name='row[backu]']").attr('data-rule',"required;filter(^A-Za-z0-9)")
// 通过 js 控制 data-rule 生效失效
$("input[name='row[type]']").on("click",function(){
    var menu_li = $(this).val();
    if(menu_li==0){
        $("#rechargeShow").show();
        $("#withdrawShow").hide();
        $("select[name='row[channelID]']").attr('data-rule','required')
        $("select[name='row[channelID]']").attr('disabled',false)
        $("input[name='row[utr]']").attr('data-rule','required;filter(\u0391-\uFFE5\\s)')
        $("input[name='row[utr]']").attr('disabled',false)
        $("input[name='row[usdtAccount]']").attr('disabled','disabled')
        $("input[name='row[usdtAccount]']").remove('data-rule')
    }
    else{
        $("#rechargeShow").hide();
        $("#withdrawShow").show();
        $("select[name='row[channelID]']").attr('disabled','disabled')
        $("select[name='row[channelID]']").remove('data-rule')
        $("input[name='row[utr]']").attr('disabled','disabled')
        $("input[name='row[utr]']").remove('data-rule')
        $("input[name='row[usdtAccount]']").attr('data-rule','required;filter(\u0391-\uFFE5\\s)')
        $("input[name='row[usdtAccount]']").attr('disabled',false)
    }
})

# selectpage 联动查询

selectpage 动态下拉组件 的参数 data-params(自定义扩展参数)可以进行搜索筛选过滤
类型下面的代码监听 $("#c-type") 的 selectpage 动态传参

$("#c-name").data("params", function (obj) {
    return {custom: {type: $("#c-type").val()}};
});

# selectpage 示例,(多字段搜索等)

额外参数 data-params='{"custom [status]":["notin",0]}'
自定义显示 data-field="name" data-format-item="{id} | {name}"
多字段搜索 data-andOr="OR"data-search-field="id,name"

<input id="c-channel" data-source="channel/index" data-params='{"custom[status]":["notin",0]}' data-order-by="id" data-andOr="OR" data-search-field="id,name" data-primary-key="id" data-field="name" data-format-item="{id} | {name}" class="form-control selectpage" name="row[channel]" type="text">

# 自定义搜索的时间区间控件选择时分秒

require-form.js 找到 daterangepicker 修改 options 的 timePicker: true
关闭调试模式需要修改 require-backend.min.js 或重新压缩 php think min -m backend -r all

var options = {
    timePicker: true,
    autoUpdateInput: false,
    timePickerSeconds: true,
    timePicker24Hour: true,
    autoApply: true,
    locale: {
        format: 'YYYY-MM-DD HH:mm:ss',
        customRangeLabel: __("Custom Range"),
        applyLabel: __("Apply"),
        cancelLabel: __("Clear"),
    },
    ranges: ranges,
};

# 触发表格刷新

$(".btn-refresh").trigger("click")

# attr 和 prop 区别

  1. attr 是从页面搜索获得元素值,所以页面必须明确定义元素才能获取值,相对来说较慢。
  2. prop 是从属性对象中取值,属性对象中有多少属性,就能获取多少值,不需要在页面中显示定义。
  3. 涉及和获取 状态 切换的 要用 prop, attr 会出错的

如 radio 切换

<div class="radio">
    <label for="row[status]-1"><input id="row[status]-1" checked="checked" name="row[status]" type="radio" value="1"></label> 
    <label for="row[status]-0"><input id="row[status]-0" name="row[status]" type="radio" value="0"></label>
</div>
// 动态选中 radio 值
$(":radio[name='row[status]'][value='" + 0 + "']").prop("checked", "checked");
// 获取 radio 选中值
$('input[name="status"]:checked').val();