jqh hace 5 años
padre
commit
1505bd5a17

+ 54 - 0
resources/views/grid/displayer/checkbox.blade.php

@@ -0,0 +1,54 @@
+<form class="form-group {{ $class }}" style="text-align:left;" data-key="{{ $key }}">
+    @foreach($options as $v => $label)
+        @php($checked = \Dcat\Admin\Support\Helper::inArray($v, $value) ? 'checked' : '')
+
+        <div class="vs-checkbox-con vs-checkbox-primary" style="margin-bottom: 4px">
+            <input type="checkbox" name="grid-checkbox-{{ $column }}[]" value="{{ $v }}" {{ $checked }}>
+            <span class="vs-checkbox vs-checkbox-sm"><span class="vs-checkbox--check"><i class="vs-icon feather icon-check"></i></span></span>
+            <span class="">{{ $label }}</span>
+        </div>
+    @endforeach
+
+    <button type="submit" class="btn btn-primary btn-sm pull-left">
+        <i class="feather icon-save"></i>&nbsp;{{ trans('admin.save') }}
+    </button>
+    <button type="reset" class="btn btn-white btn-sm pull-left" style="margin-left:5px;">
+        <i class="feather icon-trash"></i>&nbsp;{{ trans('admin.reset') }}
+    </button>
+</form>
+
+<script>
+    $(document).off('submit', 'form.{{ $class }}').on('submit', 'form.{{ $class }}', function () {
+        var values = $(this).find('input:checkbox:checked').map(function (_, el) {
+                return $(el).val();
+            }).get(),
+            btn = $(this).find('[type="submit"]'),
+            reload = '{{ $refresh }}';
+
+        if (btn.attr('loading')) {
+            return;
+        }
+        btn.attr('loading', 1);
+        btn.buttonLoading();
+
+        $.put({
+            url: "{{ $resource }}/" + $(this).data('key'),
+            data: {
+                '{{ $column }}': values,
+            },
+            success: function (data) {
+                btn.buttonLoading(false);
+                btn.removeAttr('loading');
+                Dcat.success(data.message);
+                reload && Dcat.reload();
+            },
+            error: function (a, b, c) {
+                btn.buttonLoading(false);
+                btn.removeAttr('loading');
+                Dcat.handleAjaxError(a, b, c);
+            },
+        });
+
+        return false;
+    });
+</script>

+ 95 - 0
resources/views/grid/displayer/dialogtree.blade.php

@@ -0,0 +1,95 @@
+<a href="javascript:void(0)" class="{{ $prefix }}-open-tree" data-checked="{{ $checkAll }}" data-val="{{ $value }}">
+    <i class='feather icon-align-right'></i> {{ trans('admin.view') }}
+</a>
+
+<script require="@jstree">
+    var selector = '.{{ $prefix}}-open-tree';
+
+    $(document).off('click', selector).on('click', selector, function () {
+        var tpl = '<div class="jstree-wrapper p-1" style="border:0"><div class="da-tree" style="margin-top:10px"></div></div>',
+            url = '{{ $url }}',
+            t = $(this),
+            val = t.data('val'),
+            ckall = t.data('checked'),
+            idx,
+            loading,
+            opts = {!! json_encode($options) !!};
+
+        val = val ? String(val).split(',') : [];
+
+        if (url) {
+            if (loading) return;
+            loading = 1;
+
+            t.buttonLoading();
+            $.ajax(url, {data: {value: val}}).then(function (resp) {
+                loading = 0;
+                t.buttonLoading(false);
+
+                if (!resp.status) {
+                    return Dcat.error(resp.message || '系统繁忙,请稍后再试');
+                }
+
+                build(resp.value);
+            });
+        } else {
+            build(val);
+        }
+
+        function build(val) {
+            opts.core.data = formatNodes(val, {!! json_encode($nodes) !!});
+
+            idx = layer.open({
+                type: 1,
+                area: {!! json_encode($area) !!},
+                content: tpl,
+                title: '{{ $title }}',
+                success: function (a, idx) {
+                    var tree = $('#layui-layer'+idx).find('.da-tree');
+
+                    tree.on("loaded.jstree", function () {
+                        tree.jstree('open_all');
+                    }).jstree(opts);
+                }
+            });
+
+            $(document).one('pjax:complete', function () {
+                layer.close(idx);
+            });
+        }
+
+        function formatNodes(value, all) {
+            var idColumn = '{{ $columnNames['id'] }}',
+                textColumn = '{{ $columnNames['text'] }}',
+                parentColumn = '{{ $columnNames['parent'] }}',
+                parentIds = [], nodes = [], i, v, parentId;
+
+            for (i in all) {
+                v = all[i];
+                if (!v[idColumn]) continue;
+
+                parentId = v[parentColumn] || '#';
+                if (!parentId) {
+                    parentId = '#';
+                } else {
+                    parentIds.push(parentId);
+                }
+
+                v['state'] = {'disabled': true};
+
+                if (ckall || (value && Dcat.helpers.inObject(value, v[idColumn]))) {
+                    v['state']['selected'] = true;
+                }
+
+                nodes.push({
+                    'id'     : v[idColumn],
+                    'text'   : v[textColumn] || null,
+                    'parent' : parentId,
+                    'state'  : v['state'],
+                });
+            }
+
+            return nodes;
+        }
+    });
+</script>

+ 49 - 0
resources/views/grid/displayer/expand.blade.php

@@ -0,0 +1,49 @@
+<span class="grid-expand" data-url="{{ $url }}" data-inserted="0" data-id="{{ $key }}" data-key="{{ $dataKey }}" data-toggle="collapse" data-target="#grid-collapse-{{ $dataKey }}">
+   <a href="javascript:void(0)"><i class="feather icon-chevrons-right"></i>  {!! $button !!}</a>
+</span>
+<template>
+    <template class="grid-expand-{{ $dataKey }}">
+        <div id="grid-collapse-{{ $dataKey }}" class="collapse">{!! $html !!}</div>
+    </template>
+</template>
+
+<script once>
+    $(document).off('click', '.grid-expand').on('click', '.grid-expand', function () {
+        var _th = $(this), url = _th.data('url');
+
+        if (String(_th.data('inserted')) === '0') {
+
+            var key = _th.data('key');
+            var row = _th.closest('tr');
+            var html = $('template.grid-expand-'+key).html();
+            var id = 'expand-'+key+Dcat.helpers.random(10);
+            var rowKey = _th.data('id');
+
+            $(this).attr('data-expand', '#'+id);
+
+            row.after("<tr id="+id+"><td colspan='"+(row.find('td').length)+"' style='padding:0 !important; border:0;height:0;'>"+html+"</td></tr>");
+
+            if (url) {
+                var collapse = $('#grid-collapse-'+key);
+                collapse.find('div').loading();
+                $('.dcat-loading').css({position: 'inherit', 'padding-top': '70px'});
+
+                Dcat.helpers.asyncRender(url+'&key='+rowKey, function (html) {
+                    collapse.html(html);
+                })
+            }
+
+            $(this).data('inserted', 1);
+        } else {
+            if ($("i", this).hasClass('icon-chevrons-right')) {
+                $(_th.data('expand')).show();
+            } else {
+                setTimeout(function() {
+                    $(_th.data('expand')).hide();
+                }, 250);
+            }
+        }
+
+        $("i", this).toggleClass("icon-chevrons-right icon-chevrons-down");
+    });
+</script>

+ 56 - 0
resources/views/grid/displayer/radio.blade.php

@@ -0,0 +1,56 @@
+<form class="form-group {{ $class }}" style="text-align: left" data-key="{{ $key }}">
+
+    @foreach($options as $v => $label)
+        @php($checked = \Dcat\Admin\Support\Helper::equal($v, $value) ? 'checked' : '')
+
+        <div class="vs-radio-con">
+            <input type="radio" name="grid-radio-{{ $column }}[]" value="{{ $v }}" {{ $checked }} >
+            <span class="vs-radio">
+              <span class="vs-radio--border"></span>
+              <span class="vs-radio--circle"></span>
+            </span>
+            <span class="">{{ $label }}</span>
+        </div>
+    @endforeach
+
+    <button type="submit" class="btn btn-primary btn-sm pull-left">
+        <i class="feather icon-save"></i>&nbsp;{{ trans('admin.save') }}
+    </button>
+    <button type="reset" class="btn btn-white btn-sm pull-left" style="margin-left:5px;">
+        <i class="feather icon-trash"></i>&nbsp;{{ trans('admin.reset') }}
+    </button>
+</form>
+
+<script>
+    $(document).off('submit', 'form.{{ $class }}').on('submit', 'form.{{ $class }}', function () {
+        var value = $(this).find('input:radio:checked').val(),
+            btn = $(this).find('[type="submit"]'),
+            reload = '{{ $refresh }}';
+
+        if (btn.attr('loading')) {
+            return;
+        }
+        btn.attr('loading', 1);
+        btn.buttonLoading();
+
+        $.put({
+            url: "{{ $resource }}/" + $(this).data('key'),
+            data: {
+                '{{ $column }}': value,
+            },
+            success: function (data) {
+                btn.buttonLoading(false);
+                btn.removeAttr('loading');
+                Dcat.success(data.message);
+                reload && Dcat.reload()
+            },
+            error: function (a, b, c) {
+                btn.buttonLoading(false);
+                btn.removeAttr('loading');
+                Dcat.handleAjaxError(a, b, c);
+            },
+        });
+
+        return false;
+    });
+</script>

+ 40 - 0
resources/views/grid/displayer/select.blade.php

@@ -0,0 +1,40 @@
+<div class="input-group input-group-sm">
+    <select style="width: 100%;" class="grid-column-select" data-url="{{ $url }}" data-name="{{ $column }}">
+        @foreach($options as $k => $v)
+            @php($selected = Dcat\Admin\Support\Helper::equal($k, $value)  ? 'selected' : '')
+
+            <option value="{{ $k }}" {{ $selected }}>{{ $v }}</option>
+        @endforeach
+
+    </select>
+</div>
+
+<script require="@select2">
+    $('.grid-column-select').off('change').select2().on('change', function(){
+        var value = $(this).val(),
+            name = $(this).data('name'),
+            url = $(this).data('url'),
+            data = {},
+            reload = '{{ $refresh }}';
+
+        if (name.indexOf('.') === -1) {
+            data[name] = value;
+        } else {
+            name = name.split('.');
+
+            data[name[0]] = {};
+            data[name[0]][name[1]] = value;
+        }
+
+        Dcat.NP.start();
+        $.put({
+            url: url,
+            data: data,
+            success: function (data) {
+                Dcat.NP.done();
+                Dcat.success(data.message);
+                reload && Dcat.reload();
+            }
+        });
+    });
+</script>

+ 49 - 0
resources/views/grid/displayer/switch.blade.php

@@ -0,0 +1,49 @@
+<input class="grid-column-switch" data-url="{{ $url }}" data-size="small" name="{{ $column }}" {{ $checked }} type="checkbox" data-color="{{ $color }}"/>
+
+<script require="@switchery">
+    var swt = $('.grid-column-switch'),
+        that,
+        reload = '{{ $refresh }}';
+    function initSwitchery() {
+        swt.parent().find('.switchery').remove();
+        swt.each(function () {
+            that = $(this);
+            new Switchery(that[0], that.data())
+        })
+    }
+    initSwitchery();
+
+    swt.off('change').on('change', function(e) {
+        var that = $(this),
+            url = that.data('url'),
+            checked = that.is(':checked'),
+            name = that.attr('name'),
+            data = {},
+            value = checked ? 1 : 0;
+
+        if (name.indexOf('.') === -1) {
+            data[name] = value;
+        } else {
+            name = name.split('.');
+
+            data[name[0]] = {};
+            data[name[0]][name[1]] = value;
+        }
+
+        Dcat.NP.start();
+
+        $.put({
+            url: url,
+            data: data,
+            success: function (d) {
+                Dcat.NP.done();
+                if (d.status) {
+                    Dcat.success(d.message);
+                    reload && Dcat.reload();
+                } else {
+                    Dcat.error(d.message);
+                }
+            }
+        });
+    });
+</script>

+ 68 - 0
resources/views/grid/displayer/switchgroup.blade.php

@@ -0,0 +1,68 @@
+
+<style>
+    table.grid-switch-group td {
+        padding: 3px 0;
+        height:23px;
+        border: 0;
+    }
+</style>
+
+<table class="grid-switch-group">
+    @foreach($columns as $column => $label)
+        @php($checked = Illuminate\Support\Arr::get($row, $column) ? 'checked' : '')
+
+        <tr style="box-shadow: none;background: transparent">
+            <td>{{ $label }}:&nbsp;&nbsp;&nbsp;</td>
+            <td><input name="{{ $column }}" data-path="{{ $resource }}" data-key="{{ $key }}" {{ $checked }}
+                                                           type="checkbox" class="grid-column-switch-group" data-size="small" data-color="{{ $color }}"/></td>
+        </tr>
+    @endforeach
+</table>
+
+<script require="@switchery">
+    var swt = $('.grid-column-switch-group'),
+        reload = '{{ $refresh }}',
+        that;
+    function initSwitchery() {
+        swt.each(function() {
+            that = $(this);
+            that.parent().find('.switchery').remove();
+
+            new Switchery(that[0], that.data())
+        })
+    }
+    initSwitchery();
+    swt.off('change').change(function(e) {
+        var that = $(this),
+            id = that.data('key'),
+            url = that.data('path') + '/' + id,
+            checked = that.is(':checked'),
+            name = that.attr('name'),
+            data = {},
+            value = checked ? 1 : 0;
+
+        if (name.indexOf('.') === -1) {
+            data[name] = value;
+        } else {
+            name = name.split('.');
+
+            data[name[0]] = {};
+            data[name[0]][name[1]] = value;
+        }
+        Dcat.NP.start();
+
+        $.put({
+            url: url,
+            data: data,
+            success: function (d) {
+                Dcat.NP.done();
+                if (d.status) {
+                    Dcat.success(d.message);
+                    reload && Dcat.reload()
+                } else {
+                    Dcat.error(d.message);
+                }
+            }
+        });
+    });
+</script>

+ 1 - 1
resources/views/grid/dropdown-actions.blade.php

@@ -5,7 +5,7 @@
     <ul class="dropdown-menu" style="left: -65px;">
 
         @foreach($default as $action)
-            <li class="dropdown-item">{!! \Dcat\Admin\Support\Helper::render($action) !!}</li>
+            <li class="dropdown-item">{!! Dcat\Admin\Support\Helper::render($action) !!}</li>
         @endforeach
 
         @if(!empty($custom))

+ 1 - 3
resources/views/widgets/tree.blade.php

@@ -1,7 +1,6 @@
 <div  {!! $attributes !!}><div class="da-tree"></div></div>
 
-<script>
-Dcat.ready(function () {
+<script require="@jstree">
     var opts = {!! json_encode($options) !!}, tree = $('#{{$id}}').find('.da-tree');
 
     opts.core.data = {!! json_encode($nodes) !!};
@@ -9,5 +8,4 @@ Dcat.ready(function () {
     tree.on("loaded.jstree", function () {
         tree.jstree('open_all');
     }).jstree(opts);
-});
 </script>

+ 1 - 1
src/Extend/Manager.php

@@ -177,7 +177,7 @@ class Manager
 
     public function addExtension(ServiceProvider $serviceProvider)
     {
-        $this->extensions->put($serviceProvider->name(), $serviceProvider);
+        $this->extensions->put($serviceProvider->getName(), $serviceProvider);
     }
 
     protected function registerPsr4($directory, array $psr4)

+ 16 - 16
src/Extend/ServiceProvider.php

@@ -81,19 +81,19 @@ abstract class ServiceProvider extends LaravelServiceProvider
      */
     public function boot()
     {
-        if ($views = $this->views()) {
-            $this->loadViewsFrom($views, $this->name());
+        if ($views = $this->getViewPath()) {
+            $this->loadViewsFrom($views, $this->getName());
         }
 
-        if ($lang = $this->lang()) {
-            $this->loadTranslationsFrom($lang, $this->name());
+        if ($lang = $this->getLangPath()) {
+            $this->loadTranslationsFrom($lang, $this->getName());
         }
 
-        if ($migrations = $this->migrations()) {
+        if ($migrations = $this->getMigrationPath()) {
             $this->loadMigrationsFrom($migrations);
         }
 
-        if ($routes = $this->routes()) {
+        if ($routes = $this->getRoutes()) {
             return $this->registerRoutes($routes);
         }
 
@@ -105,7 +105,7 @@ abstract class ServiceProvider extends LaravelServiceProvider
      *
      * @return string
      */
-    final public function name()
+    final public function getName()
     {
         return $this->name ?: ($this->name = str_replace('/', '.', $this->composerProperty->name));
     }
@@ -141,7 +141,7 @@ abstract class ServiceProvider extends LaravelServiceProvider
      */
     final public function enabled()
     {
-        return in_array($this->name(), Admin::setting()->getExtensionsEnabled(), true);
+        return in_array($this->getName(), Admin::setting()->getExtensionsEnabled(), true);
     }
 
     /**
@@ -209,7 +209,7 @@ abstract class ServiceProvider extends LaravelServiceProvider
      *
      * @return string
      */
-    public function assets()
+    public function getAssetPath()
     {
         return $this->path('resources/assets');
     }
@@ -219,7 +219,7 @@ abstract class ServiceProvider extends LaravelServiceProvider
      *
      * @return string
      */
-    public function views()
+    public function getViewPath()
     {
         return $this->path('resources/views');
     }
@@ -229,7 +229,7 @@ abstract class ServiceProvider extends LaravelServiceProvider
      *
      * @return string
      */
-    public function migrations()
+    public function getMigrationPath()
     {
         return $this->path('database/migrations');
     }
@@ -239,7 +239,7 @@ abstract class ServiceProvider extends LaravelServiceProvider
      *
      * @return string
      */
-    public function lang()
+    public function getLangPath()
     {
         return $this->path('resources/lang');
     }
@@ -251,7 +251,7 @@ abstract class ServiceProvider extends LaravelServiceProvider
      *
      * @throws \ReflectionException
      */
-    public function routes()
+    public function getRoutes()
     {
         $path = $this->path('src/Http/routes.php');
 
@@ -263,7 +263,7 @@ abstract class ServiceProvider extends LaravelServiceProvider
      *
      * @return array
      */
-    public function menu()
+    protected function menu()
     {
         return $this->menu;
     }
@@ -271,7 +271,7 @@ abstract class ServiceProvider extends LaravelServiceProvider
     /**
      * @return array
      */
-    public function permission()
+    protected function permission()
     {
         return $this->permission;
     }
@@ -340,7 +340,7 @@ abstract class ServiceProvider extends LaravelServiceProvider
     protected function registerAssets()
     {
         if ($this->js || $this->css) {
-            Admin::asset()->alias($this->name(), $this->js, $this->css);
+            Admin::asset()->alias($this->getName(), $this->js, $this->css);
         }
     }
 

+ 9 - 76
src/Grid/Displayers/Checkbox.php

@@ -13,88 +13,21 @@ class Checkbox extends AbstractDisplayer
             $options = $options->call($this, $this->row);
         }
 
-        $checkboxes = '';
-        $name = $this->column->getName();
-
-        if (is_string($this->value)) {
-            $this->value = explode(',', $this->value);
-        }
-
         $this->value = Helper::array($this->value);
 
-        foreach ($options as $value => $label) {
-            $checked = in_array($value, $this->value) ? 'checked' : '';
-
-            $checkboxes .= <<<EOT
-<div class="vs-checkbox-con vs-checkbox-primary" style="margin-bottom: 4px">
-    <input type="checkbox" name="grid-checkbox-{$name}[]" value="{$value}" $checked >
-    <span class="vs-checkbox vs-checkbox-sm"><span class="vs-checkbox--check"><i class="vs-icon feather icon-check"></i></span></span>
-    <span class="">{$label}</span>
-</div>
-EOT;
-        }
-
-        Admin::script($this->addScript($refresh));
-
-        return <<<EOT
-<form class="form-group {$this->getElementClass()}" style="text-align:left;" data-key="{$this->getKey()}">
-    $checkboxes
-    <button type="submit" class="btn btn-primary btn-sm pull-left">
-        <i class="feather icon-save"></i>&nbsp;{$this->trans('save')}
-    </button>
-    <button type="reset" class="btn btn-white btn-sm pull-left" style="margin-left:5px;">
-        <i class="feather icon-trash"></i>&nbsp;{$this->trans('reset')}
-    </button>
-</form>
-EOT;
+        return Admin::view('admin::grid.displayer.checkbox', [
+            'options'  => $options,
+            'key'      => $this->getKey(),
+            'column'   => $this->column->getName(),
+            'value'    => $this->value,
+            'class'    => $this->getElementClass(),
+            'resource' => $this->resource(),
+            'refresh'  => $refresh,
+        ]);
     }
 
     protected function getElementClass()
     {
         return 'grid-checkbox-'.$this->column->getName();
     }
-
-    protected function addScript($refresh)
-    {
-        return <<<JS
-(function () {
-    $('form.{$this->getElementClass()}').off('submit').on('submit', function () {
-        var values = $(this).find('input:checkbox:checked').map(function (_, el) {
-            return $(el).val();
-        }).get(), 
-        btn = $(this).find('[type="submit"]'),
-        reload = '{$refresh}';
-        
-        if (btn.attr('loading')) return;
-        btn.attr('loading', 1);
-        btn.buttonLoading();
-    
-        var data = {
-            {$this->column->getName()}: values,
-            _method: 'PUT'
-        };
-        
-        $.ajax({
-            url: "{$this->resource()}/" + $(this).data('key'),
-            type: "POST",
-            contentType: 'application/json;charset=utf-8',
-            data: JSON.stringify(data),
-            success: function (data) {
-                btn.buttonLoading(false);
-                btn.removeAttr('loading');
-                Dcat.success(data.message);
-                reload && Dcat.reload();
-            },
-            error: function (a, b, c) {
-                btn.buttonLoading(false);
-                btn.removeAttr('loading');
-                Dcat.handleAjaxError(a, b, c);
-            },
-        });
-    
-        return false;
-    });
-})();
-JS;
-    }
 }

+ 2 - 2
src/Grid/Displayers/ContextMenuActions.php

@@ -11,8 +11,6 @@ class ContextMenuActions extends DropdownActions
      */
     protected function addScript()
     {
-        parent::addScript();
-
         $script = <<<JS
 (function () {
     $("body").on("contextmenu", "table#{$this->grid->getTableId()} tr", function(e) {
@@ -53,6 +51,8 @@ JS;
      */
     public function display($callback = null)
     {
+        $this->addScript();
+
         Admin::html('<div id="grid-context-menu" class="dropdown" style="display: contents"></div>');
         Admin::style('.grid__actions__ .dropdown{display: none!important;} th.grid__actions__{display: none!important;} .grid__actions__{width:1px}');
 

+ 11 - 118
src/Grid/Displayers/DialogTree.php

@@ -8,9 +8,6 @@ use Illuminate\Contracts\Support\Arrayable;
 
 class DialogTree extends AbstractDisplayer
 {
-    public static $js = '@jstree';
-    public static $css = '@jstree';
-
     protected $url;
 
     protected $title;
@@ -37,9 +34,6 @@ class DialogTree extends AbstractDisplayer
         ],
     ];
 
-    /**
-     * @var array
-     */
     protected $columnNames = [
         'id'     => 'id',
         'text'   => 'name',
@@ -152,17 +146,17 @@ class DialogTree extends AbstractDisplayer
             $callbackOrNodes->call($this->row, $this);
         }
 
-        $btn = $this->trans('view');
-
-        $this->setupScript();
-
-        $val = $this->format($this->value);
-
-        return <<<EOF
-<a href="javascript:void(0)" class="{$this->getSelectorPrefix()}-open-tree" data-checked="{$this->checkAll}" data-val="{$val}">
-    <i class='feather icon-align-right'></i> $btn
-</a>
-EOF;
+        return Admin::view('admin::grid.displayer.dialogtree', [
+            'value'       => $this->format($this->value),
+            'prefix'      => $this->getSelectorPrefix(),
+            'nodes'       => $this->nodes,
+            'title'       => $this->title ?: $this->column->getLabel(),
+            'options'     => $this->options,
+            'area'        => $this->area,
+            'columnNames' => $this->columnNames,
+            'url'         => $this->url,
+            'checkAll'    => $this->checkAll,
+        ]);
     }
 
     protected function format($val)
@@ -174,105 +168,4 @@ EOF;
     {
         return $this->grid->getName().'_'.$this->column->getName().'_'.$this->getKey();
     }
-
-    protected function setupScript()
-    {
-        $title = $this->title ?: $this->column->getLabel();
-
-        $area = json_encode($this->area);
-        $opts = json_encode($this->options);
-        $nodes = json_encode($this->nodes);
-
-        Admin::script(
-            <<<JS
-$('.{$this->getSelectorPrefix()}-open-tree').off('click').on('click', function () {
-    var tpl = '<div class="jstree-wrapper p-1" style="border:0"><div class="da-tree" style="margin-top:10px"></div></div>', 
-        url = '{$this->url}',
-        t = $(this),
-        val = t.data('val'),
-        ckall = t.data('checked'),
-        idx,
-        requesting,
-        opts = $opts;
-
-    val = val ? String(val).split(',') : [];
-        
-    if (url) {
-        if (requesting) return;
-        requesting = 1;
-        
-        t.buttonLoading();
-        $.ajax(url, {data: {value: val}}).then(function (resp) {
-             requesting = 0;
-             t.buttonLoading(false);
-             
-             if (!resp.status) {
-                return Dcat.error(resp.message || '系统繁忙,请稍后再试');
-             }
-             
-             build(resp.value);
-        });
-    } else {
-        build(val);
-    }    
-        
-    function build(val) {
-        opts.core.data = formatNodes(val, $nodes);    
-    
-        idx = layer.open({
-            type: 1,
-            area: {$area},
-            content: tpl,
-            title: '{$title}',
-            success: function (a, idx) {
-                var tree = $('#layui-layer'+idx).find('.da-tree');
-                
-                tree.on("loaded.jstree", function () {
-                    tree.jstree('open_all');
-                }).jstree(opts);
-            }
-        });
-        
-        $(document).one('pjax:complete', function () { 
-            layer.close(idx);
-        });
-    }
-    
-    function formatNodes(value, all) {
-        var idColumn = '{$this->columnNames['id']}', 
-           textColumn = '{$this->columnNames['text']}', 
-           parentColumn = '{$this->columnNames['parent']}';
-        var parentIds = [], nodes = [], i, v, parentId;
-
-        for (i in all) {
-            v = all[i];
-            if (!v[idColumn]) continue;
-
-            parentId = v[parentColumn] || '#';
-            if (!parentId) {
-                parentId = '#';
-            } else {
-                parentIds.push(parentId);
-            }
-
-            v['state'] = {'disabled': true};
-
-            if (ckall || (value && Dcat.helpers.inObject(value, v[idColumn]))) {
-                v['state']['selected'] = true;
-            }
-
-            nodes.push({
-                'id'     : v[idColumn],
-                'text'   : v[textColumn] || null,
-                'parent' : parentId,
-                'state'  : v['state'],
-            });
-        }
-       
-        return nodes;
-    }
-});
-JS
-        );
-    }
 }

+ 3 - 50
src/Grid/Displayers/DropdownActions.php

@@ -31,52 +31,6 @@ class DropdownActions extends Actions
         'delete'    => Delete::class,
     ];
 
-    /**
-     * Add JS script into pages.
-     *
-     * @return void.
-     */
-    protected function addScript()
-    {
-        $background = Admin::color()->dark20();
-        $checkbox = ".{$this->grid->getRowName()}-checkbox";
-
-        $script = <<<JS
-$(function() {
-  $('.table-responsive').on('shown.bs.dropdown', function(e) {
-    var t = $(this),
-      m = $(e.target).find('.dropdown-menu'),
-      tb = t.offset().top + t.height(),
-      mb = m.offset().top + m.outerHeight(true),
-      d = 20; // Space for shadow + scrollbar.   
-      
-    if (t[0].scrollWidth > t.innerWidth()) {
-      if (mb + d > tb) {
-        t.css('padding-bottom', ((mb + d) - tb));
-      }
-    } else {
-      t.css('overflow', 'visible');
-    }
-    
-    $(e.target).parents('tr').css({'background-color': '{$background}'});
-  }).on('hidden.bs.dropdown', function(e) {
-    $(this).css({
-      'padding-bottom': '',
-      'overflow': ''
-    });
-    
-    var tr = $(e.target).parents('tr').eq(0);
-    
-    if (! tr.find("{$checkbox}:checked").length) {
-        tr.css({'background-color': ''});
-    }
-  });
-});
-JS;
-
-        Admin::script($script);
-    }
-
     public function prepend($action)
     {
         return $this->append($action);
@@ -137,15 +91,14 @@ JS;
     {
         $this->resetDefaultActions();
 
-        $this->addScript();
-
         $this->call($callbacks);
 
         $this->prependDefaultActions();
 
         $actions = [
-            'default' => $this->default,
-            'custom'  => $this->appends,
+            'default'  => $this->default,
+            'custom'   => $this->appends,
+            'selector' => ".{$this->grid->getRowName()}-checkbox",
         ];
 
         return view('admin::grid.dropdown-actions', $actions);

+ 7 - 63
src/Grid/Displayers/Expand.php

@@ -11,9 +11,6 @@ class Expand extends AbstractDisplayer
 {
     protected $button;
 
-    /**
-     * @var array
-     */
     protected static $counter = 0;
 
     public function button($button)
@@ -50,25 +47,17 @@ class Expand extends AbstractDisplayer
             $this->button = $callbackOrButton;
         }
 
-        $this->addScript();
-
-        $key = $this->getDataKey();
-
         $button = is_null($this->button) ? $this->value : $this->button;
 
-        return <<<EOT
-<span class="grid-expand" data-url="$remoteUrl" data-inserted="0" data-id="{$this->getKey()}" data-key="{$key}" data-toggle="collapse" data-target="#grid-collapse-{$key}">
-   <a href="javascript:void(0)"><i class="feather icon-chevrons-right"></i>  $button</a>
-</span>
-<template class="grid-expand-{$key}">
-    <div id="grid-collapse-{$key}" class="collapse">$html</div>
-</template>
-EOT;
+        return Admin::view('admin::grid.displayer.expand', [
+            'key'     => $this->getKey(),
+            'url'     => $remoteUrl,
+            'button'  => $button,
+            'html'    => $html,
+            'dataKey' => $this->getDataKey(),
+        ]);
     }
 
-    /**
-     * @return string
-     */
     protected function getDataKey()
     {
         $key = $this->getKey() ?: Str::random(8);
@@ -77,49 +66,4 @@ EOT;
 
         return $this->grid->getName().$key.'-'.static::$counter;
     }
-
-    protected function addScript()
-    {
-        $script = <<<'JS'
-$('.grid-expand').off('click').on('click', function () {
-    var _th = $(this), url = _th.data('url');
-    
-    if ($(this).data('inserted') == '0') {
-    
-        var key = _th.data('key');
-        var row = _th.closest('tr');
-        var html = $('template.grid-expand-'+key).html();
-        var id = 'expand-'+key+Dcat.helpers.random(10);
-        var rowKey = _th.data('id');
-        
-        $(this).attr('data-expand', '#'+id);
-
-        row.after("<tr id="+id+"><td colspan='"+(row.find('td').length)+"' style='padding:0 !important; border:0;height:0;'>"+html+"</td></tr>");
-        
-        if (url) {
-            var collapse = $('#grid-collapse-'+key);
-            collapse.find('div').loading();
-            $('.dcat-loading').css({position: 'inherit', 'padding-top': '70px'});
-        
-            Dcat.helpers.asyncRender(url+'&key='+rowKey, function (html) {
-                collapse.html(html);
-            })
-        }
-
-        $(this).data('inserted', 1);
-    } else {
-        if ($("i", this).hasClass('icon-chevrons-right')) {
-            $(_th.data('expand')).show();
-        } else {
-            setTimeout(function() {
-              $(_th.data('expand')).hide();
-            }, 250);
-        }
-    }
-    
-    $("i", this).toggleClass("icon-chevrons-right icon-chevrons-down");
-});
-JS;
-        Admin::script($script);
-    }
 }

+ 1 - 1
src/Grid/Displayers/QRCode.php

@@ -10,7 +10,7 @@ use Dcat\Admin\Admin;
 class QRCode extends AbstractDisplayer
 {
     protected static $js = [
-        '@admin/dcat/plugins/jquery-qrcode/dist/jquery-qrcode.min.js',
+        '@qrcode',
     ];
 
     protected function addScript()

+ 9 - 72
src/Grid/Displayers/Radio.php

@@ -12,82 +12,19 @@ class Radio extends AbstractDisplayer
             $options = $options->call($this, $this->row);
         }
 
-        $radios = '';
-        $name = $this->column->getName();
-
-        foreach ($options as $value => $label) {
-            $checked = ($value == $this->value) ? 'checked' : '';
-
-            $radios .= <<<EOT
-<div class="vs-radio-con">
-    <input type="radio" name="grid-radio-{$name}[]" value="{$value}" $checked >
-    <span class="vs-radio">
-      <span class="vs-radio--border"></span>
-      <span class="vs-radio--circle"></span>
-    </span>
-    <span class="">{$label}</span>
-</div>           
-EOT;
-        }
-
-        Admin::script($this->addScript($refresh));
-
-        return <<<EOT
-<form class="form-group {$this->getElementClass()}" style="text-align: left" data-key="{$this->getKey()}">
-    $radios
-    <button type="submit" class="btn btn-primary btn-sm pull-left">
-        <i class="feather icon-save"></i>&nbsp;{$this->trans('save')}
-    </button>
-    <button type="reset" class="btn btn-white btn-sm pull-left" style="margin-left:5px;">
-        <i class="feather icon-trash"></i>&nbsp;{$this->trans('reset')}
-    </button>
-</form>
-EOT;
+        return Admin::view('admin::grid.displayer.radio', [
+            'options'  => $options,
+            'key'      => $this->getKey(),
+            'column'   => $this->column->getName(),
+            'value'    => $this->value,
+            'class'    => $this->getElementClass(),
+            'resource' => $this->resource(),
+            'refresh'  => $refresh,
+        ]);
     }
 
     protected function getElementClass()
     {
         return 'grid-radio-'.$this->column->getName();
     }
-
-    protected function addScript($refresh)
-    {
-        return <<<JS
-(function () {
-    $('form.{$this->getElementClass()}').on('submit', function () {
-        var value = $(this).find('input:radio:checked').val(), 
-            btn = $(this).find('[type="submit"]'),
-            reload = '{$refresh}';
-        
-        if (btn.attr('loading')) {
-            return;
-        }
-        btn.attr('loading', 1);
-        btn.buttonLoading();
-    
-        $.ajax({
-            url: "{$this->resource()}/" + $(this).data('key'),
-            type: "POST",
-            data: {
-                {$this->column->getName()}: value,
-                _method: 'PUT'
-            },
-            success: function (data) {
-                btn.buttonLoading(false);
-                btn.removeAttr('loading');
-                Dcat.success(data.message);
-                reload && Dcat.reload()
-            },
-            error: function (a, b, c) {
-                btn.buttonLoading(false);
-                btn.removeAttr('loading');
-                Dcat.handleAjaxError(a, b, c);
-            },
-        });
-    
-        return false;
-    });
-})()
-JS;
-    }
 }

+ 7 - 59
src/Grid/Displayers/Select.php

@@ -6,75 +6,23 @@ use Dcat\Admin\Admin;
 
 class Select extends AbstractDisplayer
 {
-    public static $js = '@select2';
-    public static $css = '@select2';
-
-    protected $selector = 'grid-column-select';
-
     public function display($options = [], $refresh = false)
     {
         if ($options instanceof \Closure) {
             $options = $options->call($this, $this->row);
         }
 
-        $this->addScript($refresh);
-
-        $optionsHtml = '';
-
-        foreach ($options as $option => $text) {
-            $selected = (string) $option === (string) $this->value ? 'selected' : '';
-            $optionsHtml .= "<option value=\"$option\" $selected>$text</option>";
-        }
-
-        return <<<EOT
-<div class="input-group input-group-sm">
-    <select style="width: 100%;" class="{$this->selector}" data-url="{$this->url()}" data-name="{$this->column->getName()}">
-    $optionsHtml
-    </select>
-</div>
-EOT;
+        return Admin::view('admin::grid.displayer.select', [
+            'column'  => $this->column->getName(),
+            'value'   => $this->value,
+            'url'     => $this->url(),
+            'options' => $options,
+            'refresh' => $refresh,
+        ]);
     }
 
     protected function url()
     {
         return $this->resource().'/'.$this->getKey();
     }
-
-    protected function addScript($refresh)
-    {
-        $script = <<<JS
-$('.{$this->selector}').off('change').select2().on('change', function(){
-    var value = $(this).val(),
-        name = $(this).data('name'),
-        url = $(this).data('url'),
-        data = {
-            _method: 'PUT'
-        },
-        reload = '{$refresh}';
-    
-    if (name.indexOf('.') === -1) {
-        data[name] = value;
-    } else {
-        name = name.split('.');
-        
-        data[name[0]] = {};
-        data[name[0]][name[1]] = value;
-    }
-    
-    Dcat.NP.start();
-    $.ajax({
-        url: url,
-        type: "POST",
-        data: data,
-        success: function (data) {
-            Dcat.NP.done();
-            Dcat.success(data.message);
-            reload && Dcat.reload();
-        }
-    });
-});
-JS;
-
-        Admin::script($script);
-    }
 }

+ 6 - 71
src/Grid/Displayers/SwitchDisplay.php

@@ -6,14 +6,6 @@ use Dcat\Admin\Admin;
 
 class SwitchDisplay extends AbstractDisplayer
 {
-    public static $js = '@switchery';
-    public static $css = '@switchery';
-
-    protected $selector = 'grid-column-switch';
-
-    /**
-     * @var string
-     */
     protected $color;
 
     public function color($color)
@@ -29,76 +21,19 @@ class SwitchDisplay extends AbstractDisplayer
             $this->color($color);
         }
 
-        $this->addScript($refresh);
-
+        $column = $this->column->getName();
         $checked = $this->value ? 'checked' : '';
         $color = $this->color ?: Admin::color()->primary();
+        $url = $this->url();
 
-        return <<<EOF
-<input class="{$this->selector}" data-url="{$this->url()}" data-size="small" name="{$this->column->getName()}" {$checked} type="checkbox" data-color="{$color}"/>
-EOF;
+        return Admin::view(
+            'admin::grid.displayer.switch',
+            compact('column', 'color', 'refresh', 'checked', 'url')
+        );
     }
 
     protected function url()
     {
         return $this->resource().'/'.$this->getKey();
     }
-
-    protected function addScript($refresh)
-    {
-        Admin::script(
-            <<<JS
-(function() {
-    var swt = $('.{$this->selector}'), 
-    that, 
-    reload = '{$refresh}';
-    function initSwitchery(){
-        swt.parent().find('.switchery').remove();
-        swt.each(function(k){
-            that = $(this);
-            new Switchery(that[0], that.data())
-        })
-    } 
-    initSwitchery();
-    
-    swt.off('change').change(function(e) {
-        var that = $(this), 
-         url = that.data('url'),
-         checked = that.is(':checked'),
-         name = that.attr('name'), 
-         data = {
-            _method: 'PUT'
-         },
-         value = checked ? 1 : 0;
-        
-        if (name.indexOf('.') === -1) {
-            data[name] = value;
-        } else {
-            name = name.split('.');
-            
-            data[name[0]] = {};
-            data[name[0]][name[1]] = value;
-        }
-        
-        Dcat.NP.start();
-    
-        $.ajax({
-            url: url,
-            type: "POST",
-            data: data,
-            success: function (d) {
-                Dcat.NP.done();
-                if (d.status) {
-                    Dcat.success(d.message);
-                    reload && Dcat.reload();
-                } else {
-                    Dcat.error(d.message);
-                }
-            }
-        });
-    });
-})();
-JS
-        );
-    }
 }

+ 8 - 80
src/Grid/Displayers/SwitchGroup.php

@@ -7,16 +7,12 @@ use Illuminate\Support\Arr;
 
 class SwitchGroup extends SwitchDisplay
 {
-    protected $selector = 'grid-column-switch-group';
-
     public function display($columns = [], $color = '', $refresh = false)
     {
         if ($columns instanceof \Closure) {
             $columns = $columns->call($this->row, $this);
         }
 
-        $this->addScript($refresh);
-
         if ($color) {
             $this->color($color);
         }
@@ -26,83 +22,15 @@ class SwitchGroup extends SwitchDisplay
             $columns = array_combine($columns, $labels);
         }
 
-        $html = [];
-
-        foreach ($columns as $column => $label) {
-            $html[] = $this->buildSwitch($column, $label);
-        }
-
-        return '<table>'.implode('', $html).'</table>';
-    }
-
-    protected function buildSwitch($name, $label = '')
-    {
-        $checked = Arr::get($this->row->toArray(), $name) ? 'checked' : '';
         $color = $this->color ?: Admin::color()->primary();
 
-        return <<<EOT
-<tr style="box-shadow: none;background: transparent">
-    <td style="padding: 3px 0;height:23px;">{$label}:&nbsp;&nbsp;&nbsp;</td>
-    <td style="padding: 3px 0;height:23px;"><input name="{$name}" data-path="{$this->resource()}" data-key="{$this->getKey()}" $checked 
-        type="checkbox" class="{$this->selector}" data-size="small" data-color="{$color}"/></td>
-</tr>
-EOT;
-    }
-
-    protected function addScript($refresh)
-    {
-        $script = <<<JS
-(function () {
-    var swt = $('.{$this->selector}'),
-        reload = '{$refresh}', 
-        that;
-    function initSwitchery() {
-        swt.each(function() {
-             that = $(this);
-             that.parent().find('.switchery').remove();
-             
-             new Switchery(that[0], that.data())
-        })
-    } 
-    initSwitchery();
-    swt.off('change').change(function(e) {
-        var that = $(this), 
-            id = that.data('key'),
-            url = that.data('path') + '/' + id,
-            checked = that.is(':checked'), 
-            name = that.attr('name'), 
-            data = {
-                _method: 'PUT'
-            },
-            value = checked ? 1 : 0;
-        
-        if (name.indexOf('.') === -1) {
-            data[name] = value;
-        } else {
-            name = name.split('.');
-            
-            data[name[0]] = {};
-            data[name[0]][name[1]] = value;
-        }
-        Dcat.NP.start();
-    
-         $.ajax({
-            url: url,
-            type: "POST",
-            data: data,
-            success: function (d) {
-                Dcat.NP.done();
-                 if (d.status) {
-                    Dcat.success(d.message);
-                    reload && Dcat.reload()
-                } else {
-                    Dcat.error(d.message);
-                }
-            }
-        });
-    });
-})();
-JS;
-        Admin::script($script);
+        return Admin::view('admin::grid.displayer.switchgroup', [
+            'row'      => $this->row->toArray(),
+            'key'      => $this->getKey(),
+            'columns'  => $columns,
+            'resource' => $this->resource(),
+            'color'    => $color,
+            'refresh'  => $refresh,
+        ]);
     }
 }

+ 3 - 0
src/Layout/Asset.php

@@ -183,6 +183,9 @@ class Asset
             'js' => '@admin/dcat/plugins/bootstrap-colorpicker/js/bootstrap-colorpicker.min.js',
             'css' => '@admin/dcat/plugins/bootstrap-colorpicker/css/bootstrap-colorpicker.min.css',
         ],
+        '@qrcode' => [
+            'js' => '@admin/dcat/plugins/jquery-qrcode/dist/jquery-qrcode.min.js',
+        ],
     ];
 
     /**

+ 21 - 0
src/Support/Helper.php

@@ -645,6 +645,27 @@ class Helper
         return (string) $value1 === (string) $value2;
     }
 
+    /**
+     * 判断给定的数组是是否包含给定元素.
+     *
+     * @param mixed $value
+     * @param array $array
+     *
+     * @return bool
+     */
+    public static function inArray($value, array $array)
+    {
+        $array = array_map(function ($v) {
+            if (is_scalar($v) || $v === null) {
+                $v = (string) $v;
+            }
+
+            return $v;
+        }, $array);
+
+        return in_array((string) $value, $array, true);
+    }
+
     /**
      * Limit the number of characters in a string.
      *

+ 0 - 28
src/Widgets/Tree.php

@@ -8,21 +8,8 @@ use Illuminate\Support\Str;
 
 class Tree extends Widget
 {
-    public static $js = [
-        '@jstree',
-    ];
-    public static $css = [
-        '@jstree',
-    ];
-
-    /**
-     * @var string
-     */
     protected $view = 'admin::widgets.tree';
 
-    /**
-     * @var array
-     */
     protected $options = [
         'plugins' => ['checkbox', 'types'],
         'core'    => [
@@ -43,33 +30,18 @@ class Tree extends Widget
         ],
     ];
 
-    /**
-     * @var string
-     */
     protected $id;
 
-    /**
-     * @var array
-     */
     protected $columnNames = [
         'id'     => 'id',
         'text'   => 'name',
         'parent' => 'parent_id',
     ];
 
-    /**
-     * @var array
-     */
     protected $nodes = [];
 
-    /**
-     * @var array
-     */
     protected $value = [];
 
-    /**
-     * @var bool
-     */
     protected $checkAll = false;
 
     public function __construct($nodes = [])

+ 1 - 1
src/Widgets/Widget.php

@@ -209,7 +209,7 @@ abstract class Widget implements Renderable
             return;
         }
 
-        return view($this->view, $this->variables())->render();
+        return Admin::view($this->view, $this->variables());
     }
 
     /**