Sfoglia il codice sorgente

Merge branch '2.0' into patch-2

Jiang Qinghua 5 anni fa
parent
commit
05756de5fd

+ 0 - 4
phpunit.dusk.xml

@@ -13,10 +13,6 @@
             <directory suffix="Test.php">./tests/Browser</directory>
         </testsuite>
 
-        <testsuite name="Unit">
-            <directory suffix="Test.php">./tests/Unit</directory>
-        </testsuite>
-
         <testsuite name="Feature">
             <directory suffix="Test.php">./tests/Feature</directory>
         </testsuite>

+ 5 - 1
resources/assets/dcat/js/Dcat.js

@@ -113,7 +113,7 @@ export default class Dcat {
             };
 
         self.onPjaxComplete(clear, true);
-        $document.one('pjax:responded', clear);
+        $document.one('init:off', clear);
 
         clear();
 
@@ -136,6 +136,10 @@ export default class Dcat {
         }, options);
     }
 
+    offInit() {
+        $(document).trigger('init:off')
+    }
+
     /**
      * 主动触发 ready 事件
      */

+ 2 - 2
resources/assets/dcat/js/bootstrappers/DataActions.js

@@ -28,7 +28,7 @@ let defaultActions = {
                         response.data.detail = msg;
 
                         if (! response.then) {
-                            response.them = {action: 'redirect', value: redirect}
+                            response.then = {action: 'redirect', value: redirect}
                         }
 
                         Dcat.handleJsonResponse(response);
@@ -58,7 +58,7 @@ let defaultActions = {
                         Dcat.NP.done();
 
                         if (! response.then) {
-                            response.them = {action: 'refresh', value: true}
+                            response.then = {action: 'refresh', value: true}
                         }
 
                         Dcat.handleJsonResponse(data);

File diff suppressed because it is too large
+ 0 - 0
resources/dist/adminlte/adminlte.css


File diff suppressed because it is too large
+ 0 - 0
resources/dist/adminlte/adminlte.js.map


File diff suppressed because it is too large
+ 0 - 0
resources/dist/dcat/extra/action.js.map


File diff suppressed because it is too large
+ 0 - 0
resources/dist/dcat/extra/select-table.js.map


File diff suppressed because it is too large
+ 0 - 0
resources/dist/dcat/js/dcat-app.js


File diff suppressed because it is too large
+ 0 - 0
resources/dist/dcat/js/dcat-app.js.map


File diff suppressed because it is too large
+ 0 - 9
resources/dist/dcat/plugins/vendors.min.css


+ 1 - 3
resources/views/form/hasmany.blade.php

@@ -14,9 +14,7 @@
 
             <div class="has-many-{{$columnClass}}-form fields-group">
 
-                @foreach($form->fields() as $field)
-                    {!! $field->render() !!}
-                @endforeach
+                {!! $form->render() !!}
 
                 @if($options['allowDelete'])
                 <div class="form-group row">

+ 1 - 3
resources/views/form/hasmanytab.blade.php

@@ -37,9 +37,7 @@
 
         @foreach($forms as $pk => $form)
             <div class="tab-pane fields-group has-many-{{$columnClass}}-form @if ($form == reset($forms)) active @endif" id="{{ $relationName . '_' . $pk }}">
-                @foreach($form->fields() as $field)
-                    {!! $field->render() !!}
-                @endforeach
+                {!! $form->render() !!}
             </div>
         @endforeach
     </div>

+ 178 - 5
resources/views/form/map.blade.php

@@ -6,11 +6,11 @@
 
         @include('admin::form.error')
 
-        @if(config('admin.map.provider') == 'baidu')
+        @if($type === 'baidu')
             <div class="row">
                 <div class="col-md-6 col-md-offset-3">
                     <div class="input-group">
-                        <input type="text" class="form-control" id="search-{{$id['lat'].$id['lng']}}">
+                        <input type="text" class="form-control" id="{{ $searchId }}">
                         <span class="input-group-btn">
                         <button type="button" class="btn btn-info btn-flat"><i class="fa fa-search"></i></button>
                     </span>
@@ -19,11 +19,184 @@
             </div>
         @endif
 
-        <div id="map_{{$id['lat'].$id['lng']}}" style="width: 100%;height: 300px"></div>
-        <input type="hidden" id="{{$id['lat']}}" name="{{$name['lat']}}" value="{{ $value['lat'] ?? null }}" {!! $attributes !!} />
-        <input type="hidden" id="{{$id['lng']}}" name="{{$name['lng']}}" value="{{ $value['lng'] ?? null }}" {!! $attributes !!} />
+        <div class="{{ $class }}">
+            <div class="form-map"></div>
+            <input type="hidden" class="form-lat" name="{{ $name['lat'] }}" value="{{ $value['lat'] ?? null }}" {!! $attributes !!} />
+            <input type="hidden" class="form-lng" name="{{$name['lng']}}" value="{{ $value['lng'] ?? null }}" {!! $attributes !!} />
+        </div>
 
         @include('admin::form.help-block')
 
     </div>
 </div>
+<script init="{!! $selector !!}">
+    var lat = $this.find('.form-lat'),
+        lng = $this.find('.form-lng'),
+        container = $this.find('.form-map'),
+        mapId = "_" + Dcat.helpers.random();
+
+    container.attr('id', mapId);
+
+    @if($type === 'google')
+    function initGoogleMap() {
+        var LatLng = new google.maps.LatLng(lat.val(), lng.val());
+
+        var options = {
+            zoom: 13,
+            center: LatLng,
+            panControl: false,
+            zoomControl: true,
+            scaleControl: true,
+            mapTypeId: google.maps.MapTypeId.ROADMAP
+        }
+
+        var map = new google.maps.Map(container[0], options);
+
+        var marker = new google.maps.Marker({
+            position: LatLng,
+            map: map,
+            title: 'Drag Me!',
+            draggable: true
+        });
+
+        google.maps.event.addListener(marker, 'dragend', function (event) {
+            lat.val(event.latLng.lat());
+            lng.val(event.latLng.lng());
+        });
+    }
+
+    initGoogleMap();
+    @endif
+
+    @if($type === 'tencent')
+    function initTencentMap() {
+        var center = new qq.maps.LatLng(lat.val(), lng.val());
+
+        var map = new qq.maps.Map(container[0], {
+            center: center,
+            zoom: 13
+        });
+
+        var marker = new qq.maps.Marker({
+            position: center,
+            draggable: true,
+            map: map
+        });
+
+        if( ! lat.val() || ! lng.val()) {
+            var citylocation = new qq.maps.CityService({
+                complete : function(result){
+                    map.setCenter(result.detail.latLng);
+                    marker.setPosition(result.detail.latLng);
+                }
+            });
+
+            citylocation.searchLocalCity();
+        }
+
+        qq.maps.event.addListener(map, 'click', function(event) {
+            marker.setPosition(event.latLng);
+        });
+
+        qq.maps.event.addListener(marker, 'position_changed', function(event) {
+            var position = marker.getPosition();
+            lat.val(position.getLat());
+            lng.val(position.getLng());
+        });
+    }
+
+    initTencentMap();
+    @endif
+
+
+    @if($type === 'yandex')
+    function initYandexMap() {
+        ymaps.ready(function(){
+            var myMap = new ymaps.Map(mapId, {
+                center: [lat.val(), lng.val()],
+                zoom: 18
+            });
+
+            var myPlacemark = new ymaps.Placemark([lat.val(), lng.val()], {
+            }, {
+                preset: 'islands#redDotIcon',
+                draggable: true
+            });
+
+            myPlacemark.events.add(['dragend'], function (e) {
+                lat.val(myPlacemark.geometry.getCoordinates()[0]);
+                lng.val(myPlacemark.geometry.getCoordinates()[1]);
+            });
+
+            myMap.geoObjects.add(myPlacemark);
+        });
+    }
+
+    initYandexMap();
+    @endif
+
+    @if($type === 'baidu')
+    function initBaiduMap() {
+        var map = new BMap.Map(mapId);
+        var point = new BMap.Point(lng.val(), lat.val());
+        map.centerAndZoom(point, 15);
+        map.enableScrollWheelZoom(true);
+
+        var marker = new BMap.Marker(point);
+        map.addOverlay(marker);
+        marker.enableDragging();
+
+        if( ! lat.val() || ! lng.val()) {
+            var geolocation = new BMap.Geolocation();
+            geolocation.getCurrentPosition(function(e){
+                if(this.getStatus() == BMAP_STATUS_SUCCESS){
+                    map.panTo(e.point);
+                    marker.setPosition(e.point);
+
+                    lat.val(e.point.lat);
+                    lng.val(e.point.lng);
+
+                } else {
+                    console.log('failed'+this.getStatus());
+                }
+            },{enableHighAccuracy: true})
+        }
+
+        map.addEventListener("click", function(e){
+            marker.setPosition(e.point);
+            lat.val(e.point.lat);
+            lng.val(e.point.lng);
+        });
+
+        marker.addEventListener("dragend", function(e){
+            lat.val(e.point.lat);
+            lng.val(e.point.lng);
+        });
+        var ac = new BMap.Autocomplete(
+            {"input" : "{{ $searchId }}"
+                ,"location" : map
+            });
+        var address;
+        ac.addEventListener("onconfirm", function(e) {    //鼠标点击下拉列表后的事件
+            var _value = e.item.value;
+            address = _value.province +  _value.city +  _value.district +  _value.street +  _value.business;
+            setPlace();
+        });
+        function setPlace(){
+            function myFun(){
+                var pp = local.getResults().getPoi(0).point;
+                map.centerAndZoom(pp, 15);
+                marker.setPosition(pp);
+                lat.val(pp.lat);
+                lng.val(pp.lng);
+            }
+            var local = new BMap.LocalSearch(map, {
+                onSearchComplete: myFun
+            });
+            local.search(address);
+        }
+    }
+
+    initBaiduMap();
+    @endif
+</script>

+ 1 - 1
resources/views/form/select-script.blade.php

@@ -46,7 +46,7 @@
                         d.text = d.{{ $loads['textField'] }};
                         return d;
                     })
-                }).val(target.data('value').split(',')).trigger('change');
+                }).val(String(target.data('value')).split(',')).trigger('change');
             });
         };
 

+ 98 - 98
resources/views/scripts/select.blade.php

@@ -1,98 +1,98 @@
-<script>
-@section('admin.select-ajax')
-    @if(isset($ajax))
-        configs = $.extend(configs, {
-        ajax: {
-            url: "{{ $ajax['url'] }}",
-            dataType: 'json',
-            delay: 250,
-            data: function (params) {
-                return {
-                    q: params.term,
-                    page: params.page
-                };
-            },
-            processResults: function (data, params) {
-                params.page = params.page || 1;
-
-                return {
-                    results: $.map(data.data, function (d) {
-                        d.id = d.{{ $ajax['idField'] }};
-                        d.text = d.{{ $ajax['textField'] }};
-                        return d;
-                    }),
-                    pagination: {
-                        more: data.next_page_url
-                    }
-                };
-            },
-            cache: true
-        },
-        escapeMarkup: function (markup) {
-            return markup;
-        }
-    });
-    @endif
-@overwrite
-</script>
-
-@section('admin.select-load')
-    @if(isset($load))
-    <script once>
-        var selector = '{!! $selector !!}';
-
-        $(document).off('change', selector);
-        $(document).on('change', selector, function () {
-            var target = $(this).closest('{{ $load['group'] ?? '.fields-group' }}').find(".{{ $load['class'] }}");
-            target.find("option").remove();
-
-            if (String(this.value) !== '0' && ! this.value) {
-                return;
-            }
-            $.ajax("{!! $load['url'].(strpos($load['url'],'?')?'&':'?') !!}q="+this.value).then(function (data) {
-                $.map(data, function (d) {
-                    var newOption = new Option(d.{{ $load['textField'] }}, d.{{ $load['idField'] }}, false, false);
-                    target.append(newOption);
-                });
-                target.val(target.attr('data-value').split(',')).trigger('change');
-            });
-        });
-        $(selector).trigger('change');
-    </script>
-    @endif
-@overwrite
-
-@section('admin.select-lang')
-@if (config('app.locale') !== 'en')
-    {{--本地化--}}
-    <script once>
-        @php
-            $lang = trans('select2') ?: [];
-            $locale = config('app.locale');
-        @endphp
-        if ($.fn.select2) {
-            var e = $.fn.select2.amd;
-
-            e.define("select2/i18n/{{ $locale }}", [], function () {
-                return {
-                    errorLoading: function () {
-                        return "{{ $lang['error_loading'] ?? '' }}"
-                    }, inputTooLong: function (e) {
-                        return "{{ $lang['input_too_long'] ?? '' }}".replace(':num', e.input.length - e.maximum)
-                    }, inputTooShort: function (e) {
-                        return "{{ $lang['input_too_short'] ?? '' }}".replace(':num', e.minimum - e.input.length)
-                    }, loadingMore: function () {
-                        return "{{ $lang['loading_more'] ?? '' }}"
-                    }, maximumSelected: function (e) {
-                        return "{{ $lang['maximum_selected'] ?? '' }}".replace(':num', e.maximum)
-                    }, noResults: function () {
-                        return "{{ $lang['no_results'] ?? '' }}"
-                    }, searching: function () {
-                        return "{{ $lang['searching'] ?? '' }}"
-                    }
-                }
-            }), {define: e.define, require: e.require}
-        }
-    </script>
-@endif
-@overwrite
+<script>
+@section('admin.select-ajax')
+    @if(isset($ajax))
+        configs = $.extend(configs, {
+        ajax: {
+            url: "{{ $ajax['url'] }}",
+            dataType: 'json',
+            delay: 250,
+            data: function (params) {
+                return {
+                    q: params.term,
+                    page: params.page
+                };
+            },
+            processResults: function (data, params) {
+                params.page = params.page || 1;
+
+                return {
+                    results: $.map(data.data, function (d) {
+                        d.id = d.{{ $ajax['idField'] }};
+                        d.text = d.{{ $ajax['textField'] }};
+                        return d;
+                    }),
+                    pagination: {
+                        more: data.next_page_url
+                    }
+                };
+            },
+            cache: true
+        },
+        escapeMarkup: function (markup) {
+            return markup;
+        }
+    });
+    @endif
+@overwrite
+</script>
+
+@section('admin.select-load')
+    @if(isset($load))
+    <script once>
+        var selector = '{!! $selector !!}';
+
+        $(document).off('change', selector);
+        $(document).on('change', selector, function () {
+            var target = $(this).closest('{{ $load['group'] ?? '.fields-group' }}').find(".{{ $load['class'] }}");
+
+            if (String(this.value) !== '0' && ! this.value) {
+                return;
+            }
+            target.find("option").remove();
+
+            $.ajax("{!! $load['url'].(strpos($load['url'],'?')?'&':'?') !!}q="+this.value).then(function (data) {
+                $.map(data, function (d) {
+                    target.append(new Option(d.{{ $load['textField'] }}, d.{{ $load['idField'] }}, false, false));
+                });
+                target.val(String(target.attr('data-value')).split(',')).trigger('change');
+            });
+        });
+        $(selector).trigger('change');
+    </script>
+    @endif
+@overwrite
+
+@section('admin.select-lang')
+@if (config('app.locale') !== 'en')
+    {{--本地化--}}
+    <script once>
+        @php
+            $lang = trans('select2') ?: [];
+            $locale = config('app.locale');
+        @endphp
+        if ($.fn.select2) {
+            var e = $.fn.select2.amd;
+
+            e.define("select2/i18n/{{ $locale }}", [], function () {
+                return {
+                    errorLoading: function () {
+                        return "{{ $lang['error_loading'] ?? '' }}"
+                    }, inputTooLong: function (e) {
+                        return "{{ $lang['input_too_long'] ?? '' }}".replace(':num', e.input.length - e.maximum)
+                    }, inputTooShort: function (e) {
+                        return "{{ $lang['input_too_short'] ?? '' }}".replace(':num', e.minimum - e.input.length)
+                    }, loadingMore: function () {
+                        return "{{ $lang['loading_more'] ?? '' }}"
+                    }, maximumSelected: function (e) {
+                        return "{{ $lang['maximum_selected'] ?? '' }}".replace(':num', e.maximum)
+                    }, noResults: function () {
+                        return "{{ $lang['no_results'] ?? '' }}"
+                    }, searching: function () {
+                        return "{{ $lang['searching'] ?? '' }}"
+                    }
+                }
+            }), {define: e.define, require: e.require}
+        }
+    </script>
+@endif
+@overwrite

+ 2 - 1
src/Form.php

@@ -58,7 +58,7 @@ use Symfony\Component\HttpFoundation\Response;
  * @method Field\SwitchField            switch($column, $label = '')
  * @method Field\Display                display($column, $label = '')
  * @method Field\Rate                   rate($column, $label = '')
- * @method Field\Divide                 divider()
+ * @method Field\Divide                 divider(string $title = null)
  * @method Field\Password               password($column, $label = '')
  * @method Field\Decimal                decimal($column, $label = '')
  * @method Field\Html                   html($html, $label = '')
@@ -822,6 +822,7 @@ class Form implements Renderable
                 $this->response()
                     ->success(trans('admin.update_succeeded'))
                     ->redirectIf($url !== false, $url)
+                    ->refreshIf($url === false)
             );
         } catch (\Throwable $e) {
             $response = $this->handleException($e);

+ 1 - 1
src/Form/EmbeddedForm.php

@@ -38,7 +38,7 @@ use Illuminate\Support\Collection;
  * @method Field\SwitchField            switch($column, $label = '')
  * @method Field\Display                display($column, $label = '')
  * @method Field\Rate                   rate($column, $label = '')
- * @method Field\Divide                 divider()
+ * @method Field\Divide                 divider(string $title = null)
  * @method Field\Password               password($column, $label = '')
  * @method Field\Decimal                decimal($column, $label = '')
  * @method Field\Html                   html($html, $label = '')

+ 16 - 1
src/Form/Field/Divide.php

@@ -6,8 +6,23 @@ use Dcat\Admin\Form\Field;
 
 class Divide extends Field
 {
+    public function __construct($label = null)
+    {
+        $this->label = $label;
+    }
+
     public function render()
     {
-        return '<hr>';
+        if (! $this->label) {
+            return '<hr/>';
+        }
+
+        return <<<HTML
+<div class="mt-2 text-center" style="height: 20px; border-bottom: 1px solid #eee; margin-bottom: 25px">
+  <span style="font-size: 16px; background-color: #ffffff; padding: 0 10px;">
+    {$this->label}
+  </span>
+</div>
+HTML;
     }
 }

+ 13 - 192
src/Form/Field/Map.php

@@ -4,6 +4,7 @@ namespace Dcat\Admin\Form\Field;
 
 use Dcat\Admin\Admin;
 use Dcat\Admin\Form\Field;
+use Illuminate\Support\Str;
 
 class Map extends Field
 {
@@ -58,19 +59,17 @@ class Map extends Field
          */
         switch (static::getUsingMap()) {
             case 'tencent':
-                $this->useTencentMap();
+                $this->tencent();
                 break;
             case 'google':
-                $this->useGoogleMap();
+                $this->google();
                 break;
             case 'yandex':
-                $this->useYandexMap();
+                $this->yandex();
                 break;
             case 'baidu':
-                $this->useBaiduMap();
-                break;
             default:
-                $this->useBaiduMap();
+                $this->baidu();
         }
     }
 
@@ -79,201 +78,23 @@ class Map extends Field
         return config('admin.map.provider') ?: config('admin.map_provider');
     }
 
-    public function useGoogleMap()
+    public function google()
     {
-        $this->script = <<<JS
-        (function() {
-            function initGoogleMap(name) {
-                var lat = $('#{$this->id['lat']}');
-                var lng = $('#{$this->id['lng']}');
-    
-                var LatLng = new google.maps.LatLng(lat.val(), lng.val());
-    
-                var options = {
-                    zoom: 13,
-                    center: LatLng,
-                    panControl: false,
-                    zoomControl: true,
-                    scaleControl: true,
-                    mapTypeId: google.maps.MapTypeId.ROADMAP
-                }
-    
-                var container = document.getElementById("map_"+name);
-                var map = new google.maps.Map(container, options);
-    
-                var marker = new google.maps.Marker({
-                    position: LatLng,
-                    map: map,
-                    title: 'Drag Me!',
-                    draggable: true
-                });
-    
-                google.maps.event.addListener(marker, 'dragend', function (event) {
-                    lat.val(event.latLng.lat());
-                    lng.val(event.latLng.lng());
-                });
-            }
-    
-            initGoogleMap('{$this->id['lat']}{$this->id['lng']}');
-        })();
-JS;
+        return $this->addVariables(['type' => 'google']);
     }
 
-    public function useTencentMap()
+    public function tencent()
     {
-        $this->script = <<<JS
-        (function() {
-            function initTencentMap(name) {
-                var lat = $('#{$this->id['lat']}');
-                var lng = $('#{$this->id['lng']}');
-    
-                var center = new qq.maps.LatLng(lat.val(), lng.val());
-    
-                var container = document.getElementById("map_"+name);
-                var map = new qq.maps.Map(container, {
-                    center: center,
-                    zoom: 13
-                });
-    
-                var marker = new qq.maps.Marker({
-                    position: center,
-                    draggable: true,
-                    map: map
-                });
-    
-                if( ! lat.val() || ! lng.val()) {
-                    var citylocation = new qq.maps.CityService({
-                        complete : function(result){
-                            map.setCenter(result.detail.latLng);
-                            marker.setPosition(result.detail.latLng);
-                        }
-                    });
-    
-                    citylocation.searchLocalCity();
-                }
-    
-                qq.maps.event.addListener(map, 'click', function(event) {
-                    marker.setPosition(event.latLng);
-                });
-    
-                qq.maps.event.addListener(marker, 'position_changed', function(event) {
-                    var position = marker.getPosition();
-                    lat.val(position.getLat());
-                    lng.val(position.getLng());
-                });
-            }
-    
-            initTencentMap('{$this->id['lat']}{$this->id['lng']}');
-        })();
-JS;
+        return $this->addVariables(['type' => 'tencent']);
     }
 
-    public function useYandexMap()
+    public function yandex()
     {
-        $this->script = <<<JS
-        (function() {
-            function initYandexMap(name) {
-                ymaps.ready(function(){
-        
-                    var lat = $('#{$this->id['lat']}');
-                    var lng = $('#{$this->id['lng']}');
-        
-                    var myMap = new ymaps.Map("map_"+name, {
-                        center: [lat.val(), lng.val()],
-                        zoom: 18
-                    }); 
-    
-                    var myPlacemark = new ymaps.Placemark([lat.val(), lng.val()], {
-                    }, {
-                        preset: 'islands#redDotIcon',
-                        draggable: true
-                    });
-    
-                    myPlacemark.events.add(['dragend'], function (e) {
-                        lat.val(myPlacemark.geometry.getCoordinates()[0]);
-                        lng.val(myPlacemark.geometry.getCoordinates()[1]);
-                    });                
-    
-                    myMap.geoObjects.add(myPlacemark);
-                });
-    
-            }
-            
-            initYandexMap('{$this->id['lat']}{$this->id['lng']}');
-        })();
-JS;
+        return $this->addVariables(['type' => 'yandex']);
     }
 
-    public function useBaiduMap()
+    public function baidu()
     {
-        $this->script = <<<JS
-        (function() {
-            function initBaiduMap(name) {
-                var lat = $('#{$this->id['lat']}');
-                var lng = $('#{$this->id['lng']}');
-
-                var map = new BMap.Map("map_"+name);
-                var point = new BMap.Point(lng.val(), lat.val());
-                map.centerAndZoom(point, 15);
-                map.enableScrollWheelZoom(true);
-
-                var marker = new BMap.Marker(point);
-                map.addOverlay(marker);
-                marker.enableDragging();
-
-                if( ! lat.val() || ! lng.val()) {
-                    var geolocation = new BMap.Geolocation();
-                    geolocation.getCurrentPosition(function(e){
-                        if(this.getStatus() == BMAP_STATUS_SUCCESS){
-                            map.panTo(e.point);
-                            marker.setPosition(e.point);
-
-                            lat.val(e.point.lat);
-                            lng.val(e.point.lng);
-
-                        } else {
-                            console.log('failed'+this.getStatus());
-                        }
-                    },{enableHighAccuracy: true})
-                }
-
-                map.addEventListener("click", function(e){
-                    marker.setPosition(e.point);
-                    lat.val(e.point.lat);
-                    lng.val(e.point.lng);
-                });
-
-                marker.addEventListener("dragend", function(e){
-                    lat.val(e.point.lat);
-                    lng.val(e.point.lng);
-                });
-                var ac = new BMap.Autocomplete(
-                    {"input" : "search-{$this->id['lat']}{$this->id['lng']}"
-                    ,"location" : map
-                });
-                var address;
-                ac.addEventListener("onconfirm", function(e) {    //鼠标点击下拉列表后的事件
-                    var _value = e.item.value;
-                    address = _value.province +  _value.city +  _value.district +  _value.street +  _value.business;
-                    setPlace();
-                });
-                function setPlace(){
-                    function myFun(){
-                        var pp = local.getResults().getPoi(0).point;
-                        map.centerAndZoom(pp, 15);
-                        marker.setPosition(pp);
-                        lat.val(pp.lat);
-                        lng.val(pp.lng);
-                    }
-                    var local = new BMap.LocalSearch(map, {
-                        onSearchComplete: myFun
-                    });
-                    local.search(address);
-                }
-            }
-
-            initBaiduMap('{$this->id['lat']}{$this->id['lng']}');
-        })()
-JS;
+        return $this->addVariables(['type' => 'baidu', 'searchId' => 'bdmap'.Str::random()]);
     }
 }

+ 25 - 29
src/Grid.php

@@ -119,14 +119,14 @@ class Grid
     protected $view = 'admin::grid.table';
 
     /**
-     * @var Closure
+     * @var Closure[]
      */
-    protected $header;
+    protected $header = [];
 
     /**
-     * @var Closure
+     * @var Closure[]
      */
-    protected $footer;
+    protected $footer = [];
 
     /**
      * @var Closure
@@ -582,15 +582,11 @@ class Grid
      *
      * @param Closure|string|Renderable $content
      *
-     * @return $this|Closure
+     * @return $this
      */
-    public function header($content = null)
+    public function header($content)
     {
-        if (! $content) {
-            return $this->header;
-        }
-
-        $this->header = $content;
+        $this->header[] = $content;
 
         return $this;
     }
@@ -606,15 +602,25 @@ class Grid
             return '';
         }
 
-        $content = Helper::render($this->header, [$this->processFilter(false)]);
+        return <<<HTML
+<div class="card-header clearfix" style="border-bottom: 0;background: transparent;padding: 0">{$this->renderHeaderOrFooter($this->header)}</div>
+HTML;
+    }
+
+    protected function renderHeaderOrFooter($callbacks)
+    {
+        $target = [$this->processFilter(false)];
+        $content = [];
+
+        foreach ($callbacks as $callback) {
+            $content[] = Helper::render($callback, $target);
+        }
 
         if (empty($content)) {
             return '';
         }
 
-        return <<<HTML
-<div class="card-header clearfix" style="border-bottom: 0;background: transparent;padding: 0"><div class="col-md-12">{$content}</div></div>
-HTML;
+        return implode('<div class="mb-1 clearfix"></div>', $content);
     }
 
     /**
@@ -622,15 +628,11 @@ HTML;
      *
      * @param Closure|string|Renderable $content
      *
-     * @return $this|Closure
+     * @return $this
      */
-    public function footer($content = null)
+    public function footer($content)
     {
-        if (! $content) {
-            return $this->footer;
-        }
-
-        $this->footer = $content;
+        $this->footer[] = $content;
 
         return $this;
     }
@@ -646,14 +648,8 @@ HTML;
             return '';
         }
 
-        $content = Helper::render($this->footer, [$this->processFilter(false)]);
-
-        if (empty($content)) {
-            return '';
-        }
-
         return <<<HTML
-<div class="box-footer clearfix">{$content}</div>
+<div class="box-footer clearfix">{$this->renderHeaderOrFooter($this->footer)}</div>
 HTML;
     }
 

+ 1 - 1
src/Widgets/Form.php

@@ -57,7 +57,7 @@ use Illuminate\Validation\Validator;
  * @method Field\SwitchField         switch($column, $label = '')
  * @method Field\Display             display($column, $label = '')
  * @method Field\Rate                rate($column, $label = '')
- * @method Field\Divide              divider()
+ * @method Field\Divide              divider(string $title = null)
  * @method Field\Password            password($column, $label = '')
  * @method Field\Decimal             decimal($column, $label = '')
  * @method Field\Html                html($html, $label = '')

Some files were not shown because too many files changed in this diff