本来写好的省市区 三级联动好好的 composer update 一下 好像突然不管用了 于是只能 重新找解决方案 和 研究源码去了
(和我使用相同方法并正在寻找解决办法的朋友可以直接看最后)
这里我使用的是 load 方式加载的三级联动
Controller文件
use Illuminate\Http\Request; use Encore\Admin\Layout\Content; // 编辑方法 public function edit($id, Content $content) { return $content ->title($this->title()) ->description($this->description['edit'] ?? trans('admin.edit')) ->body($this->form(true, $id)->edit($id)); } //form protected function form($isEditing = false, $id = false) { $form = new Form(new xxxxx()); if ($id) { $model = xxxxx::find($id); } // 修改地址 if ($isEditing && $model->province) { $form->select('province', '省')->options('/admin/api/province/'.$model->province)->load('city', '/admin/api/city/'.$model->city)->required(); $form->select('city', '市')->options(function($id){ return Province::where('id' , $id)->pluck('name' , 'id'); })->load('area', '/admin/api/area/'.$model->area)->required(); $form->select('area', '区县')->options(function($id){ return Province::where('id' , $id)->pluck('name' , 'id'); })->required(); } else { $form->select('province', '省')->options( Province::where(['city'=>0])->pluck('name', 'id') )->load('city', '/admin/api/city')->required(); $form->select('city', '市')->load('area', '/admin/api/area')->required(); $form->select('area', '区县')->required(); } }
api方法
public function getProvince($id = false,Request $request) { $province = Province::where(['city'=>0])->get(['id', 'name AS text']); if ($id) { foreach ($province as $key) { if ($key->id == $id) { $key->selected = true; } } } return $province; }
api数据返回格式
[{ "id": 781, "text": "黄浦区" }, { "id": 782, "text": "徐汇区",
// 原本默认选中 增加 selected true就可以了 "selected": true }, { "id": 783, "text": "长宁区" }]
select2 手册地址:https://select2.org/programmatic-control/add-select-clear-items
本来在返回数据中 增加
selected : true
就可以默认选择的不知道为什么突然不行了 找了一下网上的几种解决方式 试了一下都不太好用不过提供了一些解决思路
去翻阅 select2 的手册的时候发现了 可以使用 来动态设置默认值
$('#mySelect2').val(['1', '2']);
$('#mySelect2').trigger('change');
于是就去 vendor\encore\laravel-admin\src\Form\Field\Select.php
里面调试了起来 感觉可能是
province
city
area
这三个关键字影响了 因为在我接口里面返回的只有id 和 值 但是在插件生成的html 中 多了地区编号等数据 例如 data-value="782,310104,徐汇区,31,01,04,0"
<select class="form-control area select2-hidden-accessible" style="width: 100%;" name="area" required="1" data-value="782,310104,徐汇区,31,01,04,0" tabindex="-1" aria-hidden="true"> <option value="781">黄浦区</option> <option value="782">徐汇区</option> <option value="783">长宁区</option> <option value="784">静安区</option> </select>
在vendor\encore\laravel-admin\src\Form\Field\Select.php 文件的 load() 方法中 console.log() 的时候 发现
$(target).val(target.data('value')); 里面 target.data('value') 的值是 "782,310104,徐汇区,31,01,04,0" 这明显是和我数据的值是对不上的 于是强行获取并修改了下 load方法
public function load($field, $sourceUrl, $idField = 'id', $textField = 'text', bool $allowClear = true) { if (Str::contains($field, '.')) { $field = $this->formatName($field); $class = str_replace(['[', ']'], '_', $field); } else { $class = $field; } $placeholder = json_encode([ 'id' => '', 'text' => trans('admin.choose'), ]); $strAllowClear = var_export($allowClear, true); $script = <<<EOT $(document).off('change', "{$this->getElementClassSelector()}"); $(document).on('change', "{$this->getElementClassSelector()}", function () { var target = $(this).closest('.fields-group').find(".$class"); // 修改后新增代码 var selected_value = null; $.get("$sourceUrl",{q : this.value}, function (data) { target.find("option").remove(); $(target).select2({ placeholder: $placeholder, allowClear: $strAllowClear, data: $.map(data, function (d) { d.id = d.$idField; d.text = d.$textField; // 修改后新增代码 if (d.selected) { selected_value = d.id; } return d; }) }); if (target.data('value')) { // 源代码 // $(target).val(target.data('value')); // 修改后新增代码 $(target).val(selected_value); } $(target).trigger('change'); }); }); EOT; Admin::script($script); return $this; }
在页面试了下 问题顺利解决 如果有其他解决办法欢迎分享