fastadmin相关知识

  1. 字段禁用搜索
//设置operate为false
{field: 'site_name', title: __('Site_id'),operate:false},
  1. 绑定事件
            {
                field: 'status',
                    title: __('Status'),
                align: 'center',
                searchList:{"1":"启用","0":"禁用"},
                formatter: Controller.api.formatter.custom
            },                  
//formatter: Controller.api.formatter.custom在api下面的formatter中添加custom匿名方法,此处我加的是按钮切换禁用和使用的事件

            formatter: {
                custom: function (value, row, index) {
                    var status = 0;
                    if(value==0){
                        status= 1;
                    }
                    //添加上btn-change可以自定义请求的URL进行数据处理
                    return '<a class="btn-change text-success" data-url="tiku/question_paper_category/multi" data-id="' + row.id + '" data-params="'+ this.field + '=' + status + '" ><i class="fa ' + (value == 0 ? 'fa-toggle-on fa-flip-horizontal text-gray' : 'fa-toggle-on') + ' fa-2x"></i></a>';
                },
            }
  1. 自定义表单实现


//add.html
<div class="col-xs-12 col-sm-8">
            <dl class="fieldlist" data-template="eventtpl" data-name="row[description]">
                <dd>
                    <ins>{:__('类型')}</ins>
                    <ins>{:__('题数')}</ins>
                    <ins>{:__('每题分数')}</ins>
                </dd>
                <dd><a href="javascript:;" class="btn btn-sm btn-success btn-append"><i class="fa fa-plus"></i> {:__('Append')}</a></dd>
                <!--请注意 dd和textarea间不能存在其它任何元素,实际开发中textarea应该添加个hidden进行隐藏-->
                <textarea name="row[description]" required class="form-control hide" cols="30" rows="5"></textarea>
            </dl>
            <script id="eventtpl" type="text/html">
                <dd class="form-inline">
                    <ins><input type="text" name="<%=name%>[<%=index%>][id]" class="form-control selectpage" data-source="tiku/question_paper_category/selectpageUpdate" data-field="name" value="<%=row.id%>" placeholder="类型" size="10"/></ins>
                    <ins><input type="text" name="<%=name%>[<%=index%>][number]" class="form-control" value="<%=row.number%>" placeholder="题数"/></ins>
                    <ins><input type="text" name="<%=name%>[<%=index%>][score]" class="form-control" value="<%=row.score%>" placeholder="每题分数"/></ins>
                    <!--下面的两个按钮务必保留-->
                    <span class="btn btn-sm btn-danger btn-remove"><i class="fa fa-times"></i></span>
                    <span class="btn btn-sm btn-primary btn-dragsort"><i class="fa fa-arrows"></i></span>
                </dd>
            </script>
        </div>
//edit.html 中只需要把add保存的没处理的结果放到textarea文本域中就行
 <textarea name="row[description]" required class="form-control hide" cols="30" rows="5">{$row['description']}</textarea>
//js实现
 add: function () {
            Controller.api.bindevent();
        },
        edit: function () {
            Controller.api.bindevent();
        },
        api: {
            bindevent: function () {
                Form.api.bindevent($("form[role=form]"));
                $(document).on("fa.event.appendfieldlist", "#add-form .btn-append,#edit-form .btn-append", function (e, obj) {
                    Form.events.selectpage(obj);
                });

        }
}
#php 对应函数
/**
     * 下拉搜索
     */
    public function selectpageUpdate()
    {
        $searchValue = $this->request->post('searchValue');
        $result = array();
        if ($searchValue) {//编辑页面
            $name = $this->listType[$searchValue];
            $result[] = ['id'=>$searchValue,'name'=>$name];
            $count = 1;
        }else{ //点击显示
            $pageSize = $this->request->post('pageSize');
            $pageNumber = $this->request->post('pageNumber');
            $offset = ($pageNumber-1)*$pageSize;
            $lists = array_slice($this->listType,$offset,$pageSize);//提取指定数量
            //获取所有的元素
            foreach ($lists as $k=>$v) {
                $result[$k]['id'] = $k+$offset;
                $result[$k]['name'] = $v;
                $result[$k]['pid'] = 0;
            }
            $count = count($this->listType);
        }

        return json(['list' => $result, 'total' => $count]);
    }
  1. 多级联动


//edit.html 添加页面把if语句去掉就行了
<div class="form-group">
        <label class="control-label col-xs-12 col-sm-2">{:__('Qc_id')}:</label>
        <div class="col-xs-12 col-sm-8">
            <div class="form-inline" data-toggle="cxselect" data-selects="first,second,third">
                <select required class="first form-control" name="row[first]" data-url="tiku/question_paper_category/get_course?pid=0">
                    {if condition="isset($pdata[0])"}
                    <option value="{$pdata[0]['id']}" selected="">{$pdata[0]['name']}</option>
                    {/if}
                </select>
                <select required class="second form-control" name="row[second]" data-url="tiku/question_paper_category/get_course" data-query-name="pid">
                    {if condition="isset($pdata[1])"}
                    <option value="{$pdata[1]['id']}" selected="">{$pdata[1]['name']}</option>
                    {/if}
                </select>
                <select class="third form-control" name="row[third]" data-url="tiku/question_paper_category/get_course" data-query-name="pid">
                    {if condition="isset($pdata[2])"}
                    <option value="{$pdata[2]['id']}" selected="">{$pdata[2]['name']}</option>
                    {/if}
                </select>
            </div>
        </div>
    </div>
##接口返回数据如下
  1. 下拉框添加搜索功能
#加上下面两条树形
class="selectpicker"
data-live-search="true"
  1. 添加新的表格页面,需要初始化,不然即便获取到数据也显示“没有找到匹配的内容”
Table.api.init({
      extend: {
            index_url: 'tiku/question_special/get_material'+decodeURI(location.search),
            table: 'question_special',
      }
});
  1. 普通搜索框中如何使用select框
//js代买
{field: 'site_type', title: __('site_type'),searchList: $.getJSON("tiku/question/get_site_type")},
//$.getJSON("tiku/question/get_site_type")}返回值未json对象形势,而不是json数组,当然也可以直接是json对象,不需要ajax
//{0: "教师招聘", 1: "教师资格"}

如果想在url地址上面有参数,还想要select有选中状态,name必须保证select的name值和

注意:site_type一定要和数据库中的字段、select字段一样,不然的话不会默认选中,当然选中了也不会自己在where中,因为list($where, $sort, $order, $offset, $limit) = $this->buildparams();$where条件调用的参数和url中的不是一个,所以导致的,我是自己实现的where,详情见下图:

js

php

效果
  1. 按钮中添加自定义参数
    url 按钮的链接/Ajax事件请求的URL/弹窗链接/选项卡链接,直接function和string类型,此链接会自动在链接后添加ids/{ids},{ids}为当行主键ID,如果需要传递其它字段值,请在URL中使用{字段名}占位即可,
buttons:[
    {
        name: 'look',
        title: __('查看试题'),
        classname: 'btn btn-xs btn-primary btn-addtabs',
        icon: 'fa fa-list',
        url: 'tiku/question/index?code={code}'//使用{code}占位
    },
]
  1. fastadmin 使用Fast.api.open调取弹窗回调问题
//lists.html,调用添加页面,添加完成后刷新
 Fast.api.open(url, __('Add'),{callback:function(data){
    layer.msg('操作成功',{icon: 1,time: 2000},function(){
      window.location.reload();
    });
}});

如果要让Fast.api.open回调生效,需要在打开页面中调用Fast.api.close(data);关闭窗口,并传递回调值,我这里调用的是添加的表单页面,那么直接在对应的添加页面js文件中加入如下即可

Form.api.bindevent($("form[role=form]"), function(data, ret){
     //给表单绑定新的回调函数 接收 控制器 success(msg,url,data)或者error(msg,url,data)
     Fast.api.close(data);//在这里
});

php页面$this->success()就会有返回了

  1. 添加编辑器自动渲染代码
  • 问题:
    对于fastadmin中调用组件都需要Form.api.bindevent($("form[role=form]"));渲染才可显示,那么对于动态加入的组件怎么解决呢,这里以fieldlist组件添加编辑器为例,比较有代表性
  • 解决办法:
    在filedlist组件中添加组件需要渲染,这个在事例中js文件可以看到,放在对应方法的js中如下:
$(document).on("fa.event.appendfieldlist", "#edit-form .btn-append", function (e, obj) {
                Form.events.datetimepicker(obj);//加载时间选择器
                //Form.api.bindevent($("form[role=form]"));这种办法会导致filedlist成倍增加选项
            });

那么我的解决办法是自己在require-form.js中添加一个方法editor,如下:代码就不贴了


就可以使用Form.events.editor(obj);动态加载编辑器了

  1. fastadmin中引入外部js
  • 问题
    fastadmin如果在html页面中引入js会导致页面有些组件不能使用,比如form select会不显示,我再add.html中想引入ace编辑器插件,页面没报错,但是form表单的select加载不出来,然后查百度,说应该需要通过require去引入第三方组件
  • 解决
    public/assets/js/新建一个ace.js
//public/assets/js/ace.js
define(['ace'], function(ace){
    var Obj = {
        name:"ace"
    };
    return Obj;
});

public/assets/js/backend-init.js配置ace插件

//public/assets/js/backend-init.js
define(['backend'], function (Backend) {
  //配置ace插件
    require.config({
        paths: {
            'ace': '../libs/ace/src-noconflict/ace',//这里是ace路径,我引入的src和src-min下面的都不行,然后还是引入src-noconflict下面的ace可以
        }
    });
});
  1. fastadmin 指定一个自定义页面不引用公共模板
//控制器中添加
$this->view->engine->layout(false);
//html页面添加,自己在common下面定义一个nometa.html,里面放入自己定义的即可
<head>
    {include file="common/nometa" /}
</head>

示例,如果没生效,改下html页面的内容,然后刷新下

<!doctype html>
<html lang="en">
<head>
    {include file="common/nometa" /}
</head>
<body>
{$row['html']}
</body>
</html>
  1. 默认导入功能
#index.html页面加入样式
 <a href="javascript:;" class="btn btn-danger btn-import {:$auth->check('tool/promotes/import')?'':'hide'}" title="{:__('Import')}" id="btn-import-file" data-url="ajax/upload" data-mimetype="csv,xls,xlsx" data-multiple="false"><i class="fa fa-upload"></i> {:__('Import')}</a>
# js页面index页面的url加入链接
import_url: 'tool/promotes/import',
#控制器中加入方法
public function import(){
    return parent::import();
}

导入规则第一列需要对应数据表中注释【默认】


如果使用字段名称可以修改属性
/**
     * 导入文件首行类型
     * 支持comment/name
     * 表示注释或字段名
     */
    protected $importHeadType = 'comment';

推荐阅读更多精彩内容