瀏覽代碼

重构表格部分前端代码

jqh 4 年之前
父節點
當前提交
b47a788007

+ 70 - 0
resources/assets/dcat/extra/Grid/AsyncTable.js

@@ -0,0 +1,70 @@
+/**
+ * 异步渲染表格
+ */
+
+export default class AsyncTable {
+    constructor(options) {
+        this.options = $.extend({
+            container: '.table-card',
+        }, options);
+
+        let _this = this;
+
+        $(this.options.container).on('table:load', function () {
+            _this.load($(this).data('url'), $(this));
+        });
+    }
+
+    load(url, box) {
+        let _this = this;
+
+        if (! url) {
+            return;
+        }
+
+        // 缓存当前请求地址
+        box.attr('data-current', url);
+
+        box.loading({background: 'transparent!important'});
+
+        Dcat.helpers.asyncRender(url, function (html) {
+            box.loading(false);
+            box.html(html);
+            _this.bind(box);
+            box.trigger('table:loaded');
+        });
+    }
+
+    bind(box) {
+        let _this = this;
+
+        function loadLink() {
+            _this.load($(this).attr('href'), box);
+
+            return false;
+        }
+
+        box.find('.pagination .page-link').on('click', loadLink);
+        box.find('.grid-column-header a').on('click', loadLink);
+
+        box.find('form').on('submit', function () {
+            _this.load($(this).attr('action')+'&'+$(this).serialize(), box);
+
+            return false;
+        });
+
+        box.find('.filter-box .reset').on('click', loadLink);
+
+        box.find('.grid-selector a').on('click', loadLink);
+
+        Dcat.ready(function () {
+            setTimeout(function () {
+                box.find('.grid-refresh').off('click').on('click', function () {
+                    _this.load(box.data('current'), box);
+
+                    return false;
+                })
+            }, 10)
+        })
+    }
+}

+ 64 - 0
resources/assets/dcat/extra/Grid/Helper.js

@@ -0,0 +1,64 @@
+
+export default class Helper {
+    getChildren(all, parent) {
+        let _this = this,
+            arr = [],
+            isBreak = false,
+            firstTr;
+
+        all.each(function (_, v) {
+            // 过滤非tr标签
+            if (! _this.isTr(v) || isBreak) return;
+
+            firstTr || (firstTr = $(v));
+
+            // 非连续的子节点
+            if (firstTr && ! _this.isChildren(parent, firstTr)) {
+                return;
+            }
+
+            if (_this.isChildren(parent, v)) {
+                arr.push(v)
+            } else {
+                isBreak = true;
+            }
+        });
+
+        return arr;
+    }
+
+    swapable(_o, depth) {
+        if (
+            _o
+            && _o.length
+            && depth === this.getDepth(_o)
+        ) {
+            return true
+        }
+    }
+
+    sibling(all, depth) {
+        let _this = this,
+            next;
+
+        all.each(function (_, v) {
+            if (_this.getDepth(v) === depth && ! next && _this.isTr(v)) {
+                next = $(v);
+            }
+        });
+
+        return next;
+    }
+
+    isChildren(parent, child) {
+        return this.getDepth(child) > this.getDepth(parent);
+    }
+
+    getDepth(v) {
+        return parseInt($(v).data('depth') || 0);
+    }
+
+    isTr(v) {
+        return $(v).prop('tagName').toLocaleLowerCase() === 'tr'
+    }
+}

+ 111 - 0
resources/assets/dcat/extra/Grid/Orderable.js

@@ -0,0 +1,111 @@
+/**
+ * 行排序
+ */
+
+export default class Orderable {
+    constructor(Helper, opts) {
+        this.options = $.extend({
+            button: null,
+            url: '',
+        }, opts);
+
+        this.helper = Helper;
+
+        this.direction = this.key = this.depth = this.row = this._req = null;
+
+        this._init();
+    }
+
+    _init() {
+        let _this = this;
+
+        $(_this.options.button).off('click').click(function () {
+            if (_this._req) {
+                return;
+            }
+
+            _this._req = 1;
+            Dcat.loading();
+
+            let $this = $(this);
+
+            _this.key = $this.data('id');
+            _this.direction = $this.data('direction');
+            _this.row = $this.closest('tr');
+            _this.depth = _this.helper.getDepth(_this.row);
+
+            _this.request();
+        })
+    }
+
+    request() {
+        var _this = this,
+            helper = _this.helper,
+            key = _this.key,
+            row = _this.row,
+            depth = _this.depth,
+            direction = _this.direction,
+            prevAll = row.prevAll(),
+            nextAll = row.nextAll(),
+            prev = row.prevAll('tr').first(),
+            next = row.nextAll('tr').first();
+
+        $.put({
+            url: _this.options.url.replace(':key', key),
+            data: {_orderable: direction},
+            success: function(data){
+                Dcat.loading(false);
+
+                _this._req = 0;
+
+                if (! data.status) {
+                    return data.data.message && Dcat.warning(data.data.message);
+                }
+
+                Dcat.success(data.data.message);
+
+                if (direction) {
+                    var prevRow = helper.sibling(prevAll, depth);
+                    if (helper.swapable(prevRow, depth) && prev.length && helper.getDepth(prev) >= depth) {
+                        prevRow.before(row);
+
+                        // 把所有子节点上移
+                        helper.getChildren(nextAll, row).forEach(function (v) {
+                            prevRow.before(v)
+                        });
+                    }
+                } else {
+                    var nextRow = helper.sibling(nextAll, depth),
+                        nextRowChildren = nextRow ? helper.getChildren(nextRow.nextAll(), nextRow) : [];
+
+                    if (helper.swapable(nextRow, depth) && next.length && helper.getDepth(next) >= depth) {
+                        nextAll = row.nextAll();
+
+                        if (nextRowChildren.length) {
+                            nextRow = $(nextRowChildren.pop())
+                        }
+
+                        // 把所有子节点下移
+                        var all = [];
+                        helper.getChildren(nextAll, row).forEach(function (v) {
+                            all.unshift(v)
+                        });
+
+                        all.forEach(function(v) {
+                            nextRow.after(v)
+                        });
+
+                        nextRow.after(row);
+                    }
+                }
+            },
+            error: function (a, b, c) {
+                _this._req = 0;
+
+                Dcat.loading(false);
+
+                Dcat.handleAjaxError(a, b, c)
+            }
+        });
+    }
+}

+ 171 - 0
resources/assets/dcat/extra/Grid/Tree.js

@@ -0,0 +1,171 @@
+/**
+ * 树形表格
+ */
+
+export default class Tree {
+    constructor(Helper, opts) {
+        this.options = $.extend({
+            button: null,
+            table: null,
+            url: '',
+            perPage: '',
+            showNextPage: '',
+            pageQueryName: '',
+            parentIdQueryName: '',
+            depthQueryName: '',
+            showIcon: 'fa-angle-right',
+            hideIcon: 'fa-angle-down',
+            loadMoreIcon: '<i class="feather icon-more-horizontal"></i>',
+        }, opts);
+
+        this.helper = Helper;
+        
+        this.key = this.depth = this.row = this.data = this._req = null;
+
+        this._bind();
+    }
+
+    // 绑定点击事件
+    _bind () {
+        var _this = this,
+            opts = _this.options;
+
+        $(opts.button).off('click').click(function () {
+            if (_this._req) {
+                return;
+            }
+
+            var $this = $(this),
+                _i = $("i", this),
+                shown = _i.hasClass(opts.showIcon);
+
+            _this.key = $this.data('key');
+            _this.depth = $this.data('depth');
+            _this.row = $this.closest('tr');
+
+            if ($this.data('inserted') == '0') {
+                _this.request(1);
+                $this.data('inserted', 1);
+            }
+
+            _i.toggleClass(opts.showIcon + ' ' + opts.hideIcon);
+
+            var children = [];
+
+            _this.helper.getChildren(_this.row.nextAll(), _this.row).forEach(function (v) {
+                if (_this.helper.getDepth(v) !== (_this.depth + 1)) {
+                    return;
+                }
+
+                children.push(v);
+
+                shown ? $(v).show() : $(v).hide();
+            });
+
+            children.forEach(function (v) {
+                if (shown) {
+                    return
+                }
+
+                var icon = $(v).find('a[data-depth=' + _this.helper.getDepth(v) + '] i');
+
+                if (icon.hasClass(opts.hideIcon)) {
+                    icon.parent().click();
+                }
+            })
+        })
+    }
+
+    // 发起请求
+    request (page, after) {
+        var _this = this,
+            row = _this.row,
+            key = _this.key,
+            depth = _this.depth,
+            tableSelector = _this.options.table;
+
+        if (_this._req) {
+            return;
+        }
+        _this._req = 1;
+        Dcat.loading();
+
+        var data = {};
+
+        data[_this.options.parentIdQueryName] = key;
+        data[_this.options.depthQueryName] = depth + 1;
+        data[_this.options.pageQueryName.replace(':key', key)] = page;
+
+        $.ajax({
+            url: _this.options.url,
+            type: 'GET',
+            data: data,
+            headers: {'X-PJAX': true},
+            success: function (resp) {
+                after && after();
+                Dcat.loading(false);
+                _this._req = 0;
+
+                // 获取最后一行
+                var children = _this.helper.getChildren(row.nextAll(), row);
+                row = children.length ? $(children.pop()) : row;
+
+                var _body = $('<div>'+resp+'</div>'),
+                    _tbody = _body.find(tableSelector + ' tbody'),
+                    lastPage = _body.find('last-page').text(),
+                    nextPage = _body.find('next-page').text();
+
+                // 标记子节点行
+                _tbody.find('tr').each(function (_, v) {
+                    $(v).attr('data-depth', depth + 1)
+                });
+
+                if (
+                    _this.options.showNextPage
+                    && _tbody.find('tr').length == _this.options.perPage
+                    && lastPage >= page
+                ) {
+                    // 加载更多
+                    let loadMore = $(
+                        `<tr data-depth="${depth + 1}" data-page="${nextPage}">
+                                <td colspan="${row.find('td').length}" align="center" style="cursor: pointer"> 
+                                    <a href="#" style="font-size: 1.5rem">${_this.options.loadMoreIcon}</a> 
+                                </td>
+                            </tr>`
+                    );
+
+                    row.after(loadMore);
+
+                    // 加载更多
+                    loadMore.click(function () {
+                        var _t = $(this);
+                        _this.request(_t.data('page'), function () {
+                            _t.remove();
+                        });
+                    });
+                }
+
+                // 附加子节点
+                row.after(_tbody.html());
+
+                // 附加子节点js脚本以及触发子节点js脚本执行
+                _body.find('script').each(function (_, v) {
+                    row.after(v);
+                });
+                // 主动触发ready事件,执行子节点附带的js脚本
+                Dcat.triggerReady();
+            },
+            error:function(a, b, c){
+                after && after();
+
+                Dcat.loading(false);
+
+                _this._req = 0;
+
+                if (a.status != 404) {
+                    Dcat.handleAjaxError(a, b, c);
+                }
+            }
+        });
+    }
+}

+ 14 - 406
resources/assets/dcat/extra/grid-extend.js

@@ -1,416 +1,24 @@
-(function (w, $) {
-    let Dcat = w.Dcat;
-
-    /**
-     * 树状表格
-     *
-     * @param opts
-     * @constructor
-     */
-    function Tree(opts) {
-        this.options = $.extend({
-            button: null,
-            table: null,
-            url: '',
-            perPage: '',
-            showNextPage: '',
-            pageQueryName: '',
-            parentIdQueryName: '',
-            tierQueryName: '',
-            showIcon: 'fa-angle-right',
-            hideIcon: 'fa-angle-down',
-            loadMoreIcon: '<i class="feather icon-more-horizontal"></i>',
-        }, opts);
-
-        this.key = this.tier = this.row = this.data = this._req = null;
-
-        this._init();
-    }
-
-    Tree.prototype = {
-        _init: function () {
-            this._bindClick();
-        },
-
-        _bindClick: function () {
-            var _this = this,
-                opts = _this.options;
-
-            $(opts.button).off('click').click(function () {
-                if (_this._req) {
-                    return;
-                }
-
-                var $this = $(this),
-                    _i = $("i", this),
-                    shown = _i.hasClass(opts.showIcon);
-
-                _this.key = $this.data('key');
-                _this.tier = $this.data('tier');
-                _this.row = $this.closest('tr');
-
-                if ($this.data('inserted') == '0') {
-                    _this.request(1);
-                    $this.data('inserted', 1);
-                }
-
-                _i.toggleClass(opts.showIcon + ' ' + opts.hideIcon);
-
-                var children = [];
-
-                getChildren(_this.row.nextAll(), _this.row).forEach(function (v) {
-                    if (getTier(v) !== (_this.tier + 1)) {
-                        return;
-                    }
-
-                    children.push(v);
-
-                    shown ? $(v).show() : $(v).hide();
-                });
-
-                children.forEach(function (v) {
-                    if (shown) {
-                        return
-                    }
-
-                    var icon = $(v).find('a[data-tier=' + getTier(v) + '] i');
-
-                    if (icon.hasClass(opts.hideIcon)) {
-                        icon.parent().click();
-                    }
-                })
-            })
-        },
-
-        request: function (page, after) {
-            var _this = this,
-                row = _this.row,
-                key = _this.key,
-                tier = _this.tier,
-                tableSelector = _this.options.table;
-
-            if (_this._req) {
-                return;
-            }
-            _this._req = 1;
-            Dcat.loading();
-
-            var data = {};
-
-            data[_this.options.parentIdQueryName] = key;
-            data[_this.options.tierQueryName] = tier + 1;
-            data[_this.options.pageQueryName.replace(':key', key)] = page;
-
-            $.ajax({
-                url: _this.options.url,
-                type: 'GET',
-                data: data,
-                headers: {'X-PJAX': true},
-                success: function (resp) {
-                    after && after();
-                    Dcat.loading(false);
-                    _this._req = 0;
-
-                    // 获取最后一行
-                    var children = getChildren(row.nextAll(), row);
-                    row = children.length ? $(children.pop()) : row;
-
-                    var _body = $('<div>'+resp+'</div>'),
-                        _tbody = _body.find(tableSelector + ' tbody'),
-                        lastPage = _body.find('last-page').text(),
-                        nextPage = _body.find('next-page').text();
-
-                    // 标记子节点行
-                    _tbody.find('tr').each(function (_, v) {
-                        $(v).attr('data-tier', tier + 1)
-                    });
-
-                    if (
-                        _this.options.showNextPage
-                        && _tbody.find('tr').length == _this.options.perPage
-                        && lastPage >= page
-                    ) {
-                        // 加载更多
-                        let loadMore = $(
-                            `<tr data-tier="${tier + 1}" data-page="${nextPage}">
-                                <td colspan="${row.find('td').length}" align="center" style="cursor: pointer"> 
-                                    <a href="#" style="font-size: 1.5rem">${_this.options.loadMoreIcon}</a> 
-                                </td>
-                            </tr>`
-                        );
-
-                        row.after(loadMore);
-
-                        // 加载更多
-                        loadMore.click(function () {
-                            var _t = $(this);
-                            _this.request(_t.data('page'), function () {
-                                _t.remove();
-                            });
-                        });
-                    }
-
-                    // 附加子节点
-                    row.after(_tbody.html());
-
-                    // 附加子节点js脚本以及触发子节点js脚本执行
-                    _body.find('script').each(function (_, v) {
-                        row.after(v);
-                    });
-                    // 主动触发ready事件,执行子节点附带的js脚本
-                    Dcat.triggerReady();
-                },
-                error:function(a, b, c){
-                    after && after();
-                    Dcat.loading(false);
-                    _this._req = 0;
-                    if (a.status != 404) {
-                        Dcat.handleAjaxError(a, b, c);
-                    }
-                }
-            });
-        }
-    };
-
-    /**
-     * 可排序功能
-     *
-     * @param opts
-     * @constructor
-     */
-    function Orderable(opts) {
-        this.options = $.extend({
-            button: null,
-            url: '',
-        }, opts);
-
-        this.direction = this.key = this.tier = this.row = this._req = null;
-
-        this.init();
-    }
-
-    Orderable.prototype = {
-        init: function () {
-            var _this = this;
-
-            $(_this.options.button).off('click').click(function () {
-                if (_this._req) {
-                    return;
-                }
-
-                _this._req = 1;
-                Dcat.loading();
-
-                var $this = $(this);
-
-                _this.key = $this.data('id');
-                _this.direction = $this.data('direction');
-                _this.row = $this.closest('tr');
-                _this.tier = getTier(_this.row);
-
-                _this.request();
-            })
-        },
-
-        request: function () {
-            var _this = this,
-                key = _this.key,
-                row = _this.row,
-                tier = _this.tier,
-                direction = _this.direction,
-                prevAll = row.prevAll(),
-                nextAll = row.nextAll(),
-                prev = row.prevAll('tr').first(),
-                next = row.nextAll('tr').first();
-
-            $.put({
-                url: _this.options.url.replace(':key', key),
-                data: {_orderable: direction},
-                success: function(data){
-                    Dcat.loading(false);
-                    _this._req = 0;
-                    if (! data.status) {
-                        return data.message && Dcat.warning(data.message);
-                    }
-
-                    Dcat.success(data.message);
 
-                    if (direction) {
-                        var prevRow = sibling(prevAll, tier);
-                        if (swapable(prevRow, tier) && prev.length && getTier(prev) >= tier) {
-                            prevRow.before(row);
+import Helper from './Grid/Helper'
+import Tree from './Grid/Tree'
+import Orderable from './Grid/Orderable'
+import AsyncTable from './Grid/AsyncTable'
 
-                            // 把所有子节点上移
-                            getChildren(nextAll, row).forEach(function (v) {
-                                prevRow.before(v)
-                            });
-                        }
-                    } else {
-                        var nextRow = sibling(nextAll, tier),
-                            nextRowChildren = nextRow ? getChildren(nextRow.nextAll(), nextRow) : [];
-
-                        if (swapable(nextRow, tier) && next.length && getTier(next) >= tier) {
-                            nextAll = row.nextAll();
-
-                            if (nextRowChildren.length) {
-                                nextRow = $(nextRowChildren.pop())
-                            }
-
-                            // 把所有子节点下移
-                            var all = [];
-                            getChildren(nextAll, row).forEach(function (v) {
-                                all.unshift(v)
-                            });
-
-                            all.forEach(function(v) {
-                                nextRow.after(v)
-                            });
-
-                            nextRow.after(row);
-                        }
-                    }
-                },
-                error: function (a, b, c) {
-                    _this._req = 0;
-                    Dcat.loading(false);
-                    Dcat.handleAjaxError(a, b, c)
-                }
-            });
-        },
-    };
-
-    /**
-     * 异步加载表格
-     *
-     * @param options
-     * @constructor
-     */
-    function AsyncTable(options) {
-        options = $.extend({
-            container: '.table-card',
-        }, options)
-
-        function load(url, box) {
-            var $this = $(this);
-
-            box = box || $this;
-
-            url = $this.data('url') || url;
-            if (! url) {
-                return;
-            }
-
-            // 缓存当前请求地址
-            box.attr('data-current', url);
-
-            box.loading({background: 'transparent!important'});
-
-            Dcat.helpers.asyncRender(url, function (html) {
-                box.loading(false);
-                box.html(html);
-                bind(box);
-                box.trigger('table:loaded');
-            });
-        }
-
-        function bind(box) {
-            function loadLink() {
-                load($(this).attr('href'), box);
-
-                return false;
-            }
-
-            box.find('.pagination .page-link').on('click', loadLink);
-            box.find('.grid-column-header a').on('click', loadLink);
-
-            box.find('form').on('submit', function () {
-                load($(this).attr('action')+'&'+$(this).serialize(), box);
-
-                return false;
-            });
-
-            box.find('.filter-box .reset').on('click', loadLink);
-
-            box.find('.grid-selector a').on('click', loadLink);
-
-            Dcat.ready(function () {
-                setTimeout(function () {
-                    box.find('.grid-refresh').off('click').on('click', function () {
-                        load(box.data('current'), box);
-
-                        return false;
-                    })
-                }, 10)
-            })
-        }
-
-        $(options.container).on('table:load', load);
-    }
-
-
-    function isTr(v) {
-        return $(v).prop('tagName').toLocaleLowerCase() === 'tr'
-    }
-
-    function getTier(v) {
-        return parseInt($(v).data('tier') || 0);
-    }
-
-    function isChildren(parent, child) {
-        return getTier(child) > getTier(parent);
-    }
-
-    function getChildren(all, parent) {
-        var arr = [], isBreak = false, firstTr;
-        all.each(function (_, v) {
-            // 过滤非tr标签
-            if (! isTr(v) || isBreak) return;
-
-            firstTr || (firstTr = $(v));
-
-            // 非连续的子节点
-            if (firstTr && ! isChildren(parent, firstTr)) {
-                return;
-            }
-
-            if (isChildren(parent, v)) {
-                arr.push(v)
-            } else {
-                isBreak = true;
-            }
-        });
-
-        return arr;
-    }
-
-    function swapable(_o, tier) {
-        if (
-            _o
-            && _o.length
-            && tier === getTier(_o)
-        ) {
-            return true
-        }
-    }
-
-    function sibling(all, tier) {
-        var next;
-
-        all.each(function (_, v) {
-            if (getTier(v) === tier && ! next && isTr(v)) {
-                next = $(v);
-            }
-        });
-
-        return next;
-    }
+(function (w, $) {
+    let Dcat = w.Dcat,
+        h = new Helper();
 
+    // 树形表格
     Dcat.grid.Tree = function (opts) {
-        return new Tree(opts);
+        return new Tree(h, opts);
     };
+
+    // 列表行可排序
     Dcat.grid.Orderable = function (opts) {
-        return new Orderable(opts);
+        return new Orderable(h, opts);
     };
+
+    // 异步表格
     Dcat.grid.AsyncTable =function (opts) {
         return new AsyncTable(opts)
     }

+ 6 - 6
src/Grid/Concerns/HasTree.php

@@ -18,7 +18,7 @@ trait HasTree
     /**
      * @var string
      */
-    protected $tierQueryName = '_tier_';
+    protected $depthQueryName = '_depth_';
 
     /**
      * @var bool
@@ -80,7 +80,7 @@ trait HasTree
     {
         Admin::addIgnoreQueryName([
             $this->getParentIdQueryName(),
-            $this->getTierQueryName(),
+            $this->getDepthQueryName(),
             $this->getChildrenPageName($this->getParentIdFromRequest()),
         ]);
     }
@@ -219,18 +219,18 @@ HTML
     /**
      * @return string
      */
-    public function getTierQueryName()
+    public function getDepthQueryName()
     {
-        return $this->getChildrenQueryNamePrefix().$this->tierQueryName;
+        return $this->getChildrenQueryNamePrefix().$this->depthQueryName;
     }
 
     /**
      * @return int
      */
-    public function getTierFromRequest()
+    public function getDepthFromRequest()
     {
         return $this->request->get(
-            $this->getTierQueryName()
+            $this->getDepthQueryName()
         ) ?: 0;
     }
 

+ 4 - 4
src/Grid/Displayers/Tree.php

@@ -29,7 +29,7 @@ Dcat.grid.Tree({
     showNextPage: {$showNextPage},
     pageQueryName: '{$pageName}',
     parentIdQueryName: '{$model->getParentIdQueryName()}',
-    tierQueryName: '{$model->getTierQueryName()}',
+    depthQueryName: '{$model->getDepthQueryName()}',
 });
 JS;
         Admin::script($script);
@@ -42,11 +42,11 @@ JS;
         $key = $this->getKey();
         $tableId = $this->grid->getTableId();
 
-        $tier = $this->grid->model()->getTierFromRequest();
-        $indents = str_repeat(' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ', $tier);
+        $depth = $this->grid->model()->getDepthFromRequest();
+        $indents = str_repeat(' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ', $depth);
 
         return <<<EOT
-<a href="javascript:void(0)" class="{$tableId}-grid-load-children" data-tier="{$tier}" data-inserted="0" data-key="{$key}">
+<a href="javascript:void(0)" class="{$tableId}-grid-load-children" data-depth="{$depth}" data-inserted="0" data-key="{$key}">
    {$indents}<i class="fa fa-angle-right"></i> &nbsp; {$this->value}
 </a>
 EOT;