alexwenzel / nova-dependency-container
一个用于分组依赖于其他字段值的 Laravel Nova 4 表单容器。
Requires
- php: ^8.0
- laravel/framework: ^8.0|^9.0|^10.0|^11.0
- laravel/nova: ^4.0
README
一个用于分组依赖于其他字段值的 Laravel Nova 4 表单容器。可以在任何字段类型或值上设置依赖。
特性
- 在无限嵌套容器内进行工作表单验证
- 支持 ebess/advanced-nova-media-library
此插件基于 epartment/nova-dependency-container,仅支持 Nova 4.x 和 PHP 8.x。
演示
安装
可以通过 Composer 安装此包。
composer require alexwenzel/nova-dependency-container
使用方法
- 将
Alexwenzel\DependencyContainer\HasDependencies
特性添加到您的 Nova 资源中。 - 将
Alexwenzel\DependencyContainer\DependencyContainer
添加到您的 Nova 资源fields()
方法中。 - 将
Alexwenzel\DependencyContainer\ActionHasDependencies
特性添加到您希望使用依赖项的 Nova 动作中。
class Page extends Resource { use HasDependencies; public function fields(Request $request) { return [ Select::make('Name format', 'name_format')->options([ 0 => 'First Name', 1 => 'First Name / Last Name', 2 => 'Full Name' ])->displayUsingLabels(), DependencyContainer::make([ Text::make('First Name', 'first_name') ])->dependsOn('name_format', 0), ]; } }
可用的依赖项
此包支持这些类型的依赖
->dependsOn('field', 'value')
->dependsOnNot('field', 'value')
->dependsOnEmpty('field')
->dependsOnNotEmpty('field')
->dependsOnNullOrZero('field')
->dependsOnIn('field', [array])
->dependsOnNotIn('field', [array])
可以通过在 DependencyContainer
字段上链式调用方法来组合这些依赖
DependencyContainer::make([ // dependency fields ]) ->dependsOn('field1', 'value1') ->dependsOnNotEmpty('field2') ->dependsOn('field3', 'value3')
用作依赖的字段可以是任何 Laravel Nova 字段类型。目前仅支持两种关系字段类型,BelongsTo
和 MorphTo
。
以下是一个使用复选框的示例
BelongsTo 依赖
如果我们遵循 Novas 文档中 Post 模型属于 User 模型 的示例,取自 Novas 文档 BelongsTo,依赖设置具有以下结构。
我们使用 belongsTo
资源的单数形式,以小写形式表示,在本例中 Post
变为 post
。然后我们使用点表示法定义我们想要依赖的资源属性。在本例中我们只使用 id
属性,即 post.id
。
BelongsTo::make('Post'), DependencyContainer::make([ Boolean::make('Visible') ]) ->dependsOn('post.id', 2)
当选择具有 id
2 的 Post
资源时,将出现一个 Boolean
字段。
BelongsToMany 依赖
BelongsToMany 设置类似于 BelongsTo。
dependsOn
方法应指向中间表名称。如果它被称为 role_user
,则设置如下
BelongsToMany::make('Roles') ->fields(function() { return [ DependencyContainer::make([ // pivot field rules_all Boolean::make('Rules All', 'rules_all') ]) ->dependsOn('role_user', 1) ] }),
如果枢轴字段名称出现多次,请考虑使用 自定义中间表模型 并在适当的模型关系方法中定义它。我找到的唯一可靠解决方案是使用 mutator 来获取/设置被多次使用的字段。虽然这看起来有些丑陋,但使用观察者时,在中间模型实例上触发的事件可能会在每个新的 Nova 版本中不可靠。
如果 Nova 能够可靠地在中间表上触发 Eloquent 事件,我将更新此示例,使用事件而不是 mutator 来提供一个更优雅的方法。
以下是一个使用名为 type
的枢轴字段的中继表 get/set mutator 设置的(丑陋)示例。
// model User class User ... { public function roles() { return $this->belongsToMany->using(RoleUser::class)->withPivot('rules_all'); } } // model Role class Role ... { public function users() { return $this->belongsToMany->using(RoleUser::class)->withPivot('rules_all'); } } // intermediate table use Illuminate\Database\Eloquent\Relations\Pivot; class RoleUser extends Pivot { protected $table 'role_user'; public function getType1Attribute() { return $this->type; } public function setType1Attribute($value) { $this->attributes['type'] = $value; } // ... repeat for as many types as needed }
现在我们来谈谈依赖容器。
->fields(function() { return [ DependencyContainer::make([ // pivot field rules_all Select::make('Type', 'type_1') ->options([ /* some options */ ]) ->displayUsingLabels() ]) ->dependsOn('role_user', 1), DependencyContainer::make([ // pivot field rules_all Select::make('Type', 'type_2') ->options([ /* different options */ ]) ->displayUsingLabels() ]) ->dependsOn('role_user', 2), // .. and so on ] }),
MorphTo依赖
从Novas文档中摘取的一个类似示例,用于MorphTo,称为commentable。它使用了3个模型;Comment
、Video
和Post
。在这里,Comment
拥有可变形字段commentable_id
和commentable_type
对于MorphTo
依赖,需要以下结构。
Commentable
变为小写commentable
,依赖的值是资源单数形式。在这个例子中,依赖容器将仅当选择Post
资源时,添加两个额外的字段,Additional Text
和Visible
。
MorphTo::make('Commentable')->types([ Post::class, Video::class, ]), DependencyContainer::make([ Text::make('Additional Text', 'additional'), Boolean::make('Visible', 'visible') ]) ->dependsOn('commentable', 'Post')
索引或详情页面的解决方案
在资源方法fieldsForCreate
或fieldsForUpdate
中使用该字段
DependencyContainer::make([ Select::make('Parent name', 'parent_id') ->options(...) ])->dependsOn('code', 'column'),
要在索引或详情页面上显示一些值,请在资源方法fieldsForIndex
或fieldsForDetail
中使用任何喜欢的字段来显示值
Select::make('Parent name', 'parent_id') ->options(...), // OR Text::make('Parent name', 'parent_id'),
许可证
MIT许可证(MIT)。请参阅许可证文件以获取更多信息。