Fastadmin 子级菜单展开合并,分类父级归纳

【Fastadmin】fastadmin后台默认分类列表视图和功能美化 fastadmin后台默认分类列表视图和功能美化 阅读详情

这里踩过一个坑,fastadmin默认的展开合并预定义处理的变量是pid。

所以建表时父级id需要是pid;

当然不是pid也没关系,这里以cat_id为例,多加一步处理一样能实现。

废话少说上代码:

首先在控制器,

引用:use fast\Tree;

自动调取函数 _initialize 内添加以下代码:

cat_id 我重命名成pid了。本身是pid的忽略不计。

public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\classification\Classification;

        $tree = Tree::instance();
        $tree->init(collection($this->model->field('*,cat_id as pid')->order('id desc')->select())->toArray(), 'pid');
        $this->categorylist = $tree->getTreeList($tree->getTreeArray(0), 'name');

        $categorydata = [0 => ['name' => __('None')]];
        foreach ($this->categorylist as $k => &$v) {
            $categorydata[$v['id']] = $v;
        }

        $this->view->assign("parentList", $categorydata);

    }

复制控制器index方法:

 public function index()
    {
        if ($this->request->isAjax()) {
            $list = $this->categorylist;
            $total = count($this->categorylist);
            $result = array("total" => $total, "rows" => $list);
            return json($result);
        }
        return $this->view->fetch();
    }

接下来找到 js 文件:

目录:public\assets\js\backend\classify.js

注意:

原name:{field: 'name', title: __('Name')},

替换为:

{field: 'name', title: __('Name'), align: 'left', formatter:function (value, row, index) { return value.toString().replace(/(&|&)nbsp;/g, ' '); } },

添加一列展开合并的按钮

{
    field: 'id',
    title: '<a href="javascript:;" class="btn btn-success btn-xs btn-toggle" style="border-top:none;"><i class="fa fa-chevron-down"></i></a>',
    operate: false,
    formatter: Controller.api.formatter.subnode
},

整段js示例:

// 初始化表格
table.bootstrapTable({
    url: $.fn.bootstrapTable.defaults.extend.index_url,
    pk: 'id',
    sortName: 'id',
    escape: false,
    columns: [
        [
            {checkbox: true},
            {field: 'id', title: __('Id')},
            {field: 'pid', title: __('Pid')},
            {
                field: 'name', title: __('Name'), align: 'left', formatter: function (value, row, index) {
                        return value.toString().replace(/(&|&amp;)nbsp;/g, '&nbsp;');
                    }
            },
            {
                field: 'id',
                title: '<a href="javascript:;" class="btn btn-success btn-xs btn-toggle" style="border-top:none;"><i class="fa fa-chevron-down"></i></a>',
                operate: false,
                formatter: Controller.api.formatter.subnode
            },
            {field: 'createtime', title: __('Createtime'), operate:'RANGE', addclass:'datetimerange', autocomplete:false, formatter: Table.api.formatter.datetime},
            {field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', autocomplete:false, formatter: Table.api.formatter.datetime},
            {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
        ]
    ],
    pagination: false, // 隐藏分页
    search: false, // 隐藏搜索框
    commonSearch: false, // 隐藏搜索按钮
    showToggle: false, // 表格视图两种模式
    showColumns: false, // 隐藏列
    showExport: false, // 隐藏导出
    rowAttributes: function (row, index) {
        if (this.totalRows > 500) {
            return row.pid == 0 ? {} : {style: "display:none"};
        }
        return row.haschild == 1 || row.pid ? {} : {style: "display:none"};
    }
});

注意 escape: false, 属性

还是在js文件, table.bootstrapTable下追加以下代码:

// 为表格绑定事件
Table.api.bindevent(table);

//表格内容渲染前
table.on('pre-body.bs.table', function (e, data) {
    var options = table.bootstrapTable("getOptions");
    options.escape = true;
});

// 当内容渲染完成后
table.on('post-body.bs.table', function (e, settings, json, xhr) {
    // 默认隐藏所有子节点
    $("a.btn[data-id][data-pid][data-pid!=0]").closest("tr").hide();
    $(".btn-node-sub.disabled").closest("tr").hide();

    // 显示隐藏子节点
    $(".btn-node-sub").off("click").on("click", function (e) {
        var status = $(this).data("shown") ? true : false;
        $("a.btn[data-pid='" + $(this).data("id") + "']").each(function () {
            $(this).closest("tr").toggle(!status);
        });
        $(this).data("shown", !status);
            return false;
        });

    // 点击切换/排序/删除操作后刷新左侧菜单
    $(".btn-change[data-id],.btn-delone,.btn-dragsort").data("success", function (data, ret) {
        Fast.api.refreshmenu();
        return false;
    });
});

// 批量删除后的回调
$(".toolbar > .btn-del,.toolbar .btn-more~ul>li>a").data("success", function (e) {
    Fast.api.refreshmenu();
});

// 展开隐藏一级
$(document.body).on("click", ".btn-toggle", function (e) {
    $("a.btn[data-id][data-pid][data-pid!=0].disabled").closest("tr").hide();
    var that = this;
    var show = $("i", that).hasClass("fa-chevron-down");
    $("i", that).toggleClass("fa-chevron-down", !show);
    $("i", that).toggleClass("fa-chevron-up", show);
    $("a.btn[data-id][data-pid][data-pid!=0]").not('.disabled').closest("tr").toggle(show);
    $(".btn-node-sub[data-pid=0]").data("shown", show);
});

// 展开隐藏全部
$(document.body).on("click", ".btn-toggle-all", function (e) {
    var that = this;
    var show = $("i", that).hasClass("fa-plus");
    $("i", that).toggleClass("fa-plus", !show);
    $("i", that).toggleClass("fa-minus", show);
    $(".btn-node-sub.disabled").closest("tr").toggle(show);
    $(".btn-node-sub").data("shown", show);
});

还是js文件,下面api 替换为:

api: {
    formatter: {
        subnode: function (value, row, index) {
        return '<a href="javascript:;" data-toggle="tooltip" title="' + __('Toggle sub menu') + '" data-id="' + row.id + '" data-pid="' + row.pid + '" class="btn btn-xs '
                        + (row.haschild == 1 || row.pid ? 'btn-success' : 'btn-default disabled') + ' btn-node-sub"><i class="fa fa-sitemap"></i></a>';
        }
    },
    bindevent: function () {
        $(document).on('click', "input[name='row[pid]']", function () {
            var name = $("input[name='row[name]']");
            var ismenu = $(this).val() == 1;
            name.prop("placeholder", ismenu ? name.data("placeholder-menu") : name.data("placeholder-node"));
            $('div[data-type="menu"]').toggleClass("hidden", !ismenu);
        });

        $("input[name='row[ismenu]']:checked").trigger("click");

        var iconlist = [];

        var iconfunc = function () {
            Layer.open({
                type: 1,
                area: ['99%', '98%'], //宽高
                content: Template('chooseicontpl', {iconlist: iconlist})
            });
        };
        Form.api.bindevent($("form[role=form]"), function (data) {
            Fast.api.refreshmenu();
        });
        $(document).on('change keyup', "#icon", function () {
            $(this).prev().find("i").prop("class", $(this).val());
        });
        $(document).on('click', ".btn-search-icon", function () {
            if (iconlist.length == 0) {
                $.get(Config.site.cdnurl + "/assets/libs/font-awesome/less/variables.less", function (ret) {
                    var exp = /fa-var-(.*):/ig;
                    var result;
                    while ((result = exp.exec(ret)) != null) {
                        iconlist.push(result[1]);
                    }
                    iconfunc();
                });
            } else {
                iconfunc();
            }
        });
        $(document).on('click', '#chooseicon ul li', function () {
            $("input[name='row[icon]']").val('fa fa-' + $(this).data("font")).trigger("change");
            Layer.closeAll();
        });
        $(document).on('keyup', 'input.js-icon-search', function () {
            $("#chooseicon ul li").show();
            if ($(this).val() != '') {
                $("#chooseicon ul li:not([data-font*='" + $(this).val() + "'])").hide();
            }
        });
    }

}

FastAdmin实现后台菜单自定义方法 就可以让其完全按照我们上面的button设置来展示了,另外一个如果自定义了还有很多的操作,例如刷新当前页面等等一系列的弹出咨询框确认等等,需要我们自己去一一的实践一下,不会的多多交流,共同进步。实现后台菜单自定义显示,默认显示的是编辑和删除操作,我们有的时候是需要增加一些功能性的按钮,例如审核,或者说更多的关联性的信息。那么我们就可以按如下的操作去做。上面是默认展示的功能图片,下面我来简单的分享一下如何做到自定义如果说在原有的基础上进行增加那么我们可以找到页面所在的js进行如下操作。默认初始化表格的代码。 阅读详情

相关推荐

MCGS触摸屏数据记录与U盘导出配置全解析

在工业自动化现场,数据记录是设备运行状态分析与故障追溯的基础。HMI触摸屏作为人机交互核心,不仅承担实时监控任务,还负责过程数据的存储与导出。理解数据采集周期、存盘机制与存储介质的匹配原理,能帮助工程师高效配置数据记录功能。合理运用定时存盘、存盘组与U盘导出,可支撑设备趋势分析、报表生成及事故排查。本文以MCGS触摸屏为例,详解数据记录的完整组态流程,并汇总常见配置陷阱与排查思路,为现场调试与长期运维提供可落地的技术参考。

weixin_34253126的博客 461

fastadmin菜单创建(保姆级图文教程)

本地搭建目录:目录方法一 在线命令创建方法二 cmd命令创建先下载小皮,然后新建一个网站和数据库,然后下载fastaadmin 安装包,解压安装包到网站根目录: 在小皮里修改网站根目录指定到网站public目录: 然后打开网站即可来到fastadmin安装页面(填写相关信息)然后安装: 安装完成会出现该页面: 点击进入后台,输入密码进入后台: 在后台插件管理页面,安装在线命令插件: 然后在小皮控制面板进入数据库,新建一张表测试: 数据库建好表,添加选择主表就会看到刚刚建的表,我们选择它然后立即执行: 然后就

qq_58378409的博客 5661

Unity插件——WebView内嵌网页/浏览器插件

一、相关插件: 1、Embedded Browser 插件(文件夹名ZFBrowserUnity) 2、UniWebView插件 3、UnityAndroidWebviewToTexture插件 4、3D WebView for Android插件 二、遇到的问题: 3D WebView显示问题 项目中使用3D WebView存在的问题 三、插件使用 Embedded Browser 加载页面的使用

青岚岁叶的博客 1万+

fastadmin相关操作(生成CRUD,生成菜单,关闭验证码,调试模式,开启表格用户查看权限)

fastadmin相关操作(生成CRUD,生成菜单,关闭验证码,调试模式,开启表格用户查看权限)

weixin_46001736的博客 5644

百条网络工程师基础面试题(不断更新)

1)什么是链接? 链接是指两个设备之间的连接。它包括用于一个设备能够与另一个设备通信的电缆类型和协议。 2)OSI 参考模型的层次是什么? 有 7 个 OSI 层:物理层,数据链路层,网络层,传输层,会话层,表示层和应用层。 3)什么是骨干网? 骨干网络是集中的基础设施,旨在将不同的路由和数据分发到各种网络。它还处理带宽管理和各种通道。 4)什么是 LAN? LAN 是局域网的缩写。它是指计算机与位于小物理位置的其他网络设备之间的连接。 5)什么是节点? 节点是指连接发生的点。它可以是作为网络一部分的计算机

weixin_42728126的博客 2万+

STM32+ESP8266接入OneNet的MQTT嵌入式实现

MQTT是一种轻量级发布/订阅模式的消息传输协议,广泛应用于资源受限的物联网终端设备通信。其基于TCP/IP栈构建,具备低带宽占用、小代码体积和高可靠性等技术优势,特别适合STM32等MCU与Wi-Fi模组协同工作的边缘节点场景。在实际工程中,需结合AT指令集控制ESP8266完成Wi-Fi连接、TCP建链及MQTT会话管理,并通过环形缓冲区、空闲中断检测等机制保障UART异步通信稳定性。本文围绕STM32F103与ESP8266硬件协同、OneNet平台对接、JSON消息解析与OLED状态反馈等关键环节,

yhn456789的博客 1037

fastadmin 一键CRUD 通过主键pid关联

建表时候 起名字比如别叫pid 比如 表A有id name 表B有id pid name 那么表b里面别叫pid 叫A_id 直接就能关联成下拉选择框

小沐 1444

如何创建 SAP ABAP CDS View 的 Association

所以本文我们虽然学习了如何创建 SAP CDS View 的 association,知道了 association 是用来在 CDS View 里将两张数据库表关联起来,但根本不知道怎么使用这个 association. 而且从 association 的写法来看,似乎和本教程之前介绍 inner join,left join 这些数据库表的连接操作没什么区别,都是根据两张表的 carrid 和 connid 字段相同进行的连接。只看到了我们在 CDS View 源代码实现里,放出来的四个字段。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 904

fastadmin 子级菜单展开合并,分类父级归纳

效果如下:

qq_38029640的博客 2448

一张微服务地图的十年演进:Spring Cloud 核心、扩展与工具组件的定位、原理与选型

本文把 Spring Cloud 当作一张微服务地图来读:先说明它是由 Commons 抽象层、实现层和 Boot 装配层构成的发行版,再沿一次请求梳理注册发现、负载均衡、声明式调用、容错限流、网关、配置、追踪与总线七类核心组件的原理与换代,并扩展到云平台、服务网格、消息流、批处理、安全与周边生态。仿真实测:默认参数下实例宕机平均 242 秒才被感知,优雅下线降到 47 秒;一个慢实例让轮询的 P99 达 49 秒,P2C 仅 203 毫秒。最后给出退场替代表、技术栈组合、升级路线和决策树。

曾经“等你生日那天”都遥远得像未来,如今却可欢愉的挥手说“下个十年见” 169万+

PCL Trimmed ICP实现点云精配准【2025最新版】

博客长期更新,本文最新更新时间为:2025年6月25日。抄袭狗记得来抄最新代码哦,抄都抄成错的,不够丢人钱。

点云侠的博客 37万+

fastadmin 树状菜单展开,合并;简要文件管理系统界面设计与实现

js文件:backend 文件夹下找到该模块下的文件。注意:上下级结构需要用pid进行关联。

优倍素材网技术总结 2133

YOLO26 无损剪枝:稀疏训练 + 结构化通道裁剪

YOLO26 无损剪枝链路:YOLO26s (7.2M) → 稀疏训练 30 epoch (L1 on BN gamma, lam=0.01) → 阈值剪枝 50% (gamma<quantile(0.5)) → 结构化重建 Conv+BN → 微调 10 epoch (lr=1e-4) → YOLO26n (1.9M, mAP50 0.808, 仅降 0.6%)。核心贡献:稀疏训练让 BN gamma 趋向二元分布 (近 0 或近 1), 剪枝阈值可直接取 median 自动 50% 压缩。

m0_64661770的博客 263

fastadmin分类下拉(多级分类)使用教程

找到需要修改的控制器,修改公共方法 _initialize(),修改前需要引入功能包 use fast\Tree。找到你对应的编辑模板页面,视图中view/xxx/edit.html。找到你对应的添加模板页面,视图中view/xxx/add.html。在后台添加页面,点击下拉即可出现分类多级下拉数据。在后台分类管理中,添加需要的分类数据。zb,广州,2023.10.28。

青茶 2711

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

fastadmin 父子分类 实现

效果如下: 步骤1:表设计中有字段pid; 步骤2:控制器修改 2.1初始化Tree: public function _initialize() { parent::_initialize(); $this->model = new \app\admin\model\member\Grade; ...

qq_27787259的博客 2309

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

fastadmin 父子分类(父id)实现

效果 实现过程 首先建表的时候有个字段为pid 一.然后修改controller层代码: 1.别忘了 use fast\Tree; public function _initialize() { parent::_initialize(); $this->model = new \app\admin\model\Rule; $tree = Tree::instance(); $tree->init(coll

zyh2468的博客 2086

【FastAdmin】菜单规则配置详细说明

【代码】【FastAdmin】菜单规则配置详细说明。

有点东西 1322

fastadmin后台父子级数据呈tree显示

fastadmin后台父子级数据呈tree显示

qq_53457276的博客 1040

fastadmin框架中selectpage二级联动菜单的问题

困扰我一晚上,经过查资料,不停的调试,终于成功。 简单说就是二级联动菜单,一级为学院,二级为专业。 当切换学院时,专业联动即可。 关键代码: ... import: function () { $("#zhuanye_id").data("params", function (obj) { return {"custom[is_delete...

JadePlus的技术博客 4204

antDesign树形表格或者额外展开行-子父级表格默认展开行

antDesign子父级表格默认展开行

Sunny_lxm的博客 4756

Fastadmin一键生成菜单栏目

Fastadmin一键生成菜单栏目 一键生成CRUD 使用一键生成,核心 创建 栏目的数据库一键生成CRUD 字段类型尽量符合要求 数据库 CURL命令使用 编辑器打开 新终端,或者在项目文件夹下 Shist+右键,打开Powershell窗口 切记在项目文件夹下运行命令 编辑栏目菜单 生成栏目会根据字段名称自动生成 图片/时间戳/按钮等,具体修改我们在下个文章详解 看到生成好的栏目,在权限管理->菜单规则 中编辑栏目 修改标题 图标,权重负责排序,数字越大越靠上 也可添加一个新的规则,选

qq_44340218的博客 3027

【php】fastadmin中使用级联下拉菜单

这里的categorytpl就是之前在html中声明的script的id, r.region需要自己在ajax数据中维护,以正常显示在表格中。在项目中,将客户根据省市和类别分类是非常常见的场景,在fastadmin的后台管理中,对于有数据据绑定的下拉菜单搜索条件,是需要额外编写的。位置随意,主要是要声明对ajax的数据源地址data-url属性。需要注意集合中的键值格式。

wewewecmcm的博客 1060

fastadmin给操作按钮添加权限菜单控制|新增权限控制菜单

fastadmin5给新添加的方法增加权限菜单管理节点

LordForce的博客 2716

Fastadmin实战:5分钟搞定动态下拉菜单(附完整代码)

本文详细解析了在Fastadmin框架中实现动态下拉菜单的完整流程与高级技巧。从基础的表单数据流理解,到实战构建分类选择菜单,再到实现无刷新的两级联动下拉菜单,并深入探讨了性能优化方案(如数据预加载与缓存)以及集成Select2进行远程搜索的高级应用。文章还提供了关键的避坑指南和最佳实践,帮助开发者高效、优雅地处理后台管理系统中的复杂表单交互需求。

weixin_29011395的博客 224

fastadmin 下拉多级分类

fastadmin 下拉多级分类

天龙的博客 1868

fastadmin搜索框连表查询搜索

fastadmin搜索框连表查询搜索

T_Hong的博客 1314
上一篇: MYSQL中的14个神仙功能
下一篇: FadstAdmin的city-picker插件实现地区多选
withoutfear
博客等级 码龄13年 541粉丝 79原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

withoutfear

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值