webfactor/laravel-backpack-instant-fields

在 Laravel Backpack 中动态创建/编辑/删除相关实体的即时字段

3.0.1 2019-10-04 10:12 UTC

README

Latest Version on Packagist Software License StyleCI Build Status Coverage Status Quality Score Total Downloads

这是一个为 Laravel Backpack 提供的包,它提供了 CRUD 字段类型,允许在添加/编辑另一个实体时动态创建/编辑/删除相关的 CRUD 实体。

Screenshot

Screenshot

安装

通过 Composer

composer require webfactor/laravel-backpack-instant-fields

用法

EntityCrudController

为了简单起见,将此包中的 InstantFields 特性添加到所有应该提供“即时字段”或由“即时字段”触发的 EntityCrudController。

<?php

use Webfactor\Laravel\Backpack\InstantFields\InstantFields;

class EntityCrudController extends CrudController
{
    use InstantFields;

    //
}

该特性提供所有必要的路由入口点和 AJAX 响应方法。

路由

在你的路由文件中,你必须为使用该包特质的每个实体在你的 CRUD::resource 中添加一个额外的路由。为了清晰起见,我们建议使用 with() 辅助函数。

<?php

CRUD::resource('entity', 'EntityCrudController')->with(function () {
   Route::any('entity/ajax/{mode?}', 'EntityCrudController@handleAjaxRequest');
});

特性和路由将为您处理以下请求

  • 搜索触发实体
  • 检索创建/编辑/删除模态框的 HTML
  • 存储/更新/销毁外部实体

可用字段

此包中有两种字段类型可供使用,允许您即时创建相关的模型(1-n 和 n-m)。它们是 Laravel Backpack 中已存在的等效字段类型的修改版。

注意

编辑和删除按钮仅适用于 select2_from_ajax
使用删除按钮时,请考虑数据库约束!

字段定义

请使用(外部)实体CrudController中 setup() 方法的设置器设置 $ajaxEntity 属性,该Controller被“即时字段”触发。

<?php

use Webfactor\Laravel\Backpack\InstantFields\InstantFields;

class EntityCrudController extends CrudController
{
   use InstantFields;

   public function setup()
   {
       // other Backpack options
       
       $this->setAjaxEntity('entity');
       
       // fields/columns definitions
   }
}

在设置即时字段的 EntityCrudController 的字段定义中,您必须在 on_the_fly 数组中设置上述名称。

注意:如果您使用 Laravel Backpack Crud >= 3.4.11,则无需发布提供的字段,可以直接从包中使用,使用 view_namespace 键。

示例

[
    'name'                 => 'entity_id',
    'type'                 => 'select2_from_ajax',
    'label'                => 'Entity',
    'view_namespace'       => 'webfactor::fields',
    'model'                => Entity::class,
    'entity'               => 'entity',
    'attribute'            => 'name',
    'placeholder'          => 'Choose',
    'pagination'           => 20, // optional, default: 10
    'minimum_input_length' => 0,
    'on_the_fly'           => [
        'entity'        => 'entity', // e. g. user, contact, company etc...
        
        // optional:
        
        'create'        => false
        'edit'          => false
        'delete'        => false
        'create_modal'  => 'path to custom create modal'
        'edit_modal'    => 'path to custom edit modal'
        'attribute'     => '...' // see auto-fill below in readme
    ],
    'dependencies'         => ['field1', 'field2'...], // optional, resets this field when changing the given ones
],

即时字段将在创建新条目后尝试自动填充 select2 输入框。它将假设存在一个名为 name 的输入字段,并使用其值进行触发的 AJAX 搜索。如果您想使用其他字段,只需将 attribute 添加到 on_the_fly 数组中,包含您想使用的字段名称。

有时您可能需要一个简单的按钮/链接到“真实”的外部实体而不使用模态框:在这种情况下,只需添加 'crud' => true

列表视图

使用此包,您还可以在 Backpack 的列表视图中添加创建外部 CRUD 实体的按钮!只需在 EntityCrudController 中添加以下行:

<?php

    $this->addInstantCreateButtonToList(
        $entity, // foreign entity 
        $content, // content of the button
        $entity_id, // the name of the ID of the current entity will be forwarded by this  
        $class, // optional, default: 'btn btn-xs btn-default', the css class of the button
        $position, // optional, default: beginning, the position of the button in the line 
        $button_view // optional, you can override the used button blade by your own
    );
        
        // Example:
    
    $this->addInstantCreateButtonToList(
        'order', 
        '<i class="fa fa-cart-plus"></i>', 
        'task_id', 
        'btn btn-sm btn-info', 
        'end'
    );

定制

模态视图

通过路由

默认情况下,模态通过在字段定义中的 on_the_fly 使用 entity 自动加载,例如,对于创建模态,结果为 backpack_url($field['on_the_fly']['entity']).'/ajax/create'

您可以通过设置属性来覆盖此行为。

'on_the_fly' => [
    'entity' => 'entity',
    'create_modal'  => 'route/to/modal/html',
    'edit_modal'    => 'route/to/modal/html',
    'delete_modal'  => 'route/to/modal/html',
]

请注意,通过使用此属性,您将完全负责模态的内容!定义的请求必须提供有效的 HTML,然后将其填充到 <div class="modal-content"></div>

通过视图

您可以选择使用自定义视图而不是定义路由

'on_the_fly' => [
    'entity' => 'entity',
    'create_modal_view' => 'view.to.create.modal',
    'edit_modal_view'   => 'view.to.edit.modal',
    'delete_modal_view' => 'view.to.delete.modal',
]

搜索逻辑

“即时字段”会触发在字段定义中定义的 EntityCrudControllerajaxIndex() 方法,并使用 modelattribute 参数在关联模型上执行搜索。

通过将 search_logic 添加到字段定义中,您可以实现自己的搜索行为

'search_logic' => function($query, $searchTerm, $form) { // Collection $form is optional
    return $query->where('name', 'like', '%'.$searchTerm.'%')
                 ->whereActive()
                 ->whereSomethingElse();
},

Collecion $form 是一个可选参数,提供您 CRUD 表单的所有当前值。您可以使用它根据实际输入来操作搜索,并结合 dependencies(请参阅 Backpack 文档

此外,您还可以使用 attibute 通过在模型上使用访问器来在下拉菜单中显示丰富的值。

搜索数据源

如果需要,您可以使用 Laravel Backpack 原始字段视图中的 data_sourcemethod 属性。这是触发搜索的字段 select2 触发的 URL。

请求验证

您还可以使用请求验证!只需使用提供的设置方法设置 $ajaxStoreRequest 和/或 $ajaxUpdateRequest 属性

<?php

use Webfactor\Laravel\Backpack\InstantFields\InstantFields;

class EntityCrudController extends CrudController
{
    use InstantFields;

    public function setup()
    {
        // other Backpack options
        
        $this->setAjaxEntity('entity');
        $this->setAjaxStoreRequest(\RequestNamespace\StoreRequest::class);
        $this->setAjaxUpdateRequest(\RequestNamespace\UpdateRequest::class);
        
        // fields/columns definitions
    }
}

存储/更新后自动填充

即时字段会在创建新条目后尝试自动填充 select2 输入。它将假设存在一个名为 name 的输入字段,并使用其值进行触发的 AJAX 搜索。

如果您想定义一个或多个自动填充列,可以添加 autofill_attributes 数组

'on_the_fly' => [
    'entity' => 'entity',
    'autofill_attributes' => [ 
        'company',
        'contact_name',
        'address',
    ]
]

请注意,这仅适用于列(或附加访问器)。

为了在多个列上正常工作,您应该为此字段实现自定义搜索逻辑。

搜索逻辑示例

'search_logic' => function ($query, $searchTerms) {
    return $query->where(function ($q) use ($searchTerms) {
        collect(explode(' ', $searchTerms))->each(function ($searchTerm) use ($q) {
            $q->where(function ($sq) use ($searchTerm) {
                $sq->where('company', 'LIKE', '%' . $searchTerm . '%')
                   ->orWhere('contact_name', 'LIKE', '%' . $searchTerm . '%')
                   ->orWhereRaw('LOWER(JSON_EXTRACT(address, "$.postcode")) LIKE \'%' . strtolower($searchTerm) . '%\'');
            });
        });
    })->orderBy('name');

将当前字段值传递给外部的 EntityCrudController

有时您需要使用当前值来创建外部实体。您可以在存储请求中定义 serialize,包括所需字段的 ID

'on_the_fly' => [
    'serialize' => ['type_id', 'name'],
]

因此,type_idname 的当前值将在您的 EntityCrudControllerajaxStore 方法中的 $request 中可用(您将需要覆盖它)。

字段

在项目中发布字段并修改功能

php artisan vendor:publish --tag=instantfields

变更日志

有关最近更改的更多信息,请参阅 CHANGELOG

贡献

有关详细信息,请参阅 CONTRIBUTINGCODE_OF_CONDUCT

安全

如果您发现任何安全相关的问题,请通过电子邮件 thomas.swonke@webfactor.de 联系我们,而不是使用问题跟踪器。

鸣谢

许可

MIT 许可证(MIT)。有关更多信息,请参阅 许可文件