以下方法且新增在控制元件相關檔案中
1. table元件圖片在修改時丟失
配置好的圖片在修改時直接丟失,只能重新上傳
方法如下:有一定弊端,圖片配置不會丟失但也無法刪除,可用額外欄位作刪除標記
$form->saving(function (Form $form) {
$images = $form->images;
foreach ($images as $key => &$item) {
if (isset($item['image']) && \request()->hasFile("images.{$key}.image")) {
unset($item['image']);
$item['image'] = \request()->file("images.{$key}.image")->store(config('filesystems.disks.public.directory.image'), 'public');
} else {
$item['image'] = $form->model()->images[$key]['image'] ?? "";
}
}
$form->model()->images = $images;
}
2.1. 表單輸入框聯動①:第二級隨第一級切換而改變輸入框型別
示例:如程式碼所示,需求為根據version切換顯示channel_id還是coid
$form->select('version', '配置版本')
->options([0 => '渠道版', 1 => '企業版'])
->hideField(['channel_id', 'coid'], [[0 => 'channel_id'], [1 => 'coid']]);
$form->select('channel_id', '指定渠道')->options(Channel::all(['name', 'id'])->pluck('name', 'id'));
$form->select('coid', '指定企業')->options(Company::all(['id', 'name'])->pluck('name', 'id'));
我們只需要在select控制元件Select.php(App\Http\Admin\Extensions)中新增一下方法:
/**
* 通過選擇值,展示或隱藏某些欄位
* @param $fieldsGroup //參與隱藏或展示的欄位組
* @param $condition //條件:當值等於X的時候展示Y欄位 [value=>fields]
* @return $this
*/
public function hideField($fieldsGroup, $condition)
{
$fieldsGroupClass = [];
foreach ($fieldsGroup as $fieldName) {
$fieldClassName = '.' . trim($fieldName, '.');
$fieldsGroupClass[] = $fieldClassName;
}
$fieldClassName = implode(',', $fieldsGroupClass);
foreach ($condition as &$fieldName) {
$fieldName = array_map(function ($v) {
return '.' . $v;
}, $fieldName);
$fieldName = implode(',', $fieldName);
}
unset($fieldName);
$jsonCondition = json_encode($condition);
$script = <<<EOT
$(function(){
$(document).on('change',"{$this->getElementClassSelector()}",function(){
var _this=$(this);
var _val = _this.val();
var _condition=$jsonCondition
$("{$fieldClassName}").parents('.form-group').hide();
$("{$fieldClassName}").attr('disable',true)
if(_condition[_val]!=undefined){
var e =_condition[_val];
$(e).parents('.form-group').show();
$(e).attr('disable',false)
}
});
$("{$this->getElementClassSelector()}").trigger('change');
})
EOT;
Admin::script($script);
return $this;
}
2.2. 表單輸入框聯動②:第二級隨第一級切換而展示/隱藏
示例:如程式碼所示,需求為根據auto_product切換展示/隱藏app_id,secret配置
$form->select('auto_product', '產品自增')
->options([1 => '手動新增產品', 0 => '自動同步產品'])
->hideField2(['appid', 'secret']);
$form->text('appid', 'appid');
$form->text('secret', 'secret');
方法如下:
/**
* 通過選擇值,展示或隱藏某些欄位 過去 現在 未來
* @param $fieldsGroup //參與隱藏/展示的欄位
* @return $this
*/
public function hideField2($fieldsGroup)
{
$fieldsGroupClass = [];
foreach ($fieldsGroup as $fieldName) {
$fieldClassName = '.' . trim($fieldName, '.');
$fieldsGroupClass[] = $fieldClassName;
}
$script = <<<EOT
$(function(){
$(document).on('change',"{$this->getElementClassSelector()}",function(){
var _this=$(this);
var _val = _this.val();
if(_val == 1){
$("{$fieldsGroupClass[0]}").parents('.form-group').hide();
$("{$fieldsGroupClass[0]}").attr('disable',true);
$("{$fieldsGroupClass[1]}").parents('.form-group').hide();
$("{$fieldsGroupClass[1]}").attr('disable',true);
}
if(_val == 0){
$("{$fieldsGroupClass[0]}").parents('.form-group').show();
$("{$fieldsGroupClass[0]}").attr('disable',false);
$("{$fieldsGroupClass[1]}").parents('.form-group').show();
$("{$fieldsGroupClass[1]}").attr('disable',false);
}
});
$("{$this->getElementClassSelector()}").trigger('change');
})
EOT;
Admin::script($script);
return $this;
}
小結:
上面兩種不同情況都很簡單,一些簡單的js,jQuery知識。有額外情況只需仿照以上程式碼,觀察表單的dom結構做出相應修改即可。
3. 二級聯動初始化問題
select二級聯動在修改/新增介面的時候無法展示已有的配置,即使第一級有預設值
方法:重寫聯動select的load方法,新增以下程式碼$("{$this->getElementClassSelector()}").trigger('change');
. 即在頁面載入時就觸發一次change事件,載入出我們已有的配置
方法如下:
/**
* Load options for other select on change.
*
* @param string $field
* @param string $sourceUrl
* @param string $idField
* @param string $textField
*
* @return $this
*/
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'),
]);
$script = <<<EOT
$(document).off('change', "{$this->getElementClassSelector()}");
$(document).on('change', "{$this->getElementClassSelector()}", function () {
var select_value = $(this).attr('data-value');
var target = $(this).closest('.fields-group').find(".$class");
$.get("$sourceUrl",{q : this.value}, function (data) {
target.find("option").remove();
var data_value = target.attr("data-value");
var values = data_value.split(',');
$(target).select2({
placeholder: $placeholder,
allowClear: $allowClear,
data: $.map(data, function (d) {
d.id = d.$idField;
d.text = d.$textField;
console.log(String(d.id));
if($.inArray(String(d.id), values) != -1){
d.selected = true;
}
return d;
})
}).trigger('change');
});
});
$("{$this->getElementClassSelector()}").trigger('change');
EOT;
Admin::script($script);
return $this;
}
4. 複製當前資料並修改後新增
public function copy($id)
{
return Admin::content(function (Content $content) use ($id) {
$content->header('新建員工中心');
$form = $this->form()->edit($id);
$form->builder()->setMode();
$form->setAction(route('employee.store'));
$content->body($form);
});
}
表格
$grid->actions(function (Grid\Displayers\Actions $actions) {
$url = route('employee.copy', ['id' => $actions->row->id]);
$actions->append("<a href={$url}><i class='fa fa-copy'></i></a>");
});
本作品採用《CC 協議》,轉載必須註明作者和本文連結