alexwenzel/nova-dependency-container

一个用于分组依赖于其他字段值的 Laravel Nova 4 表单容器。

1.12 2024-06-02 20:37 UTC

This package is auto-updated.

Last update: 2024-09-02 21:15:47 UTC


README

一个用于分组依赖于其他字段值的 Laravel Nova 4 表单容器。可以在任何字段类型或值上设置依赖。

特性

  • 在无限嵌套容器内进行工作表单验证
  • 支持 ebess/advanced-nova-media-library

此插件基于 epartment/nova-dependency-container,仅支持 Nova 4.xPHP 8.x

演示

Demo

安装

可以通过 Composer 安装此包。

composer require alexwenzel/nova-dependency-container

使用方法

  1. Alexwenzel\DependencyContainer\HasDependencies 特性添加到您的 Nova 资源中。
  2. Alexwenzel\DependencyContainer\DependencyContainer 添加到您的 Nova 资源 fields() 方法中。
  3. 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),
        ];
    }
}

可用的依赖项

此包支持这些类型的依赖

  1. ->dependsOn('field', 'value')
  2. ->dependsOnNot('field', 'value')
  3. ->dependsOnEmpty('field')
  4. ->dependsOnNotEmpty('field')
  5. ->dependsOnNullOrZero('field')
  6. ->dependsOnIn('field', [array])
  7. ->dependsOnNotIn('field', [array])

可以通过在 DependencyContainer 字段上链式调用方法来组合这些依赖

DependencyContainer::make([
  // dependency fields
])
->dependsOn('field1', 'value1')
->dependsOnNotEmpty('field2')
->dependsOn('field3', 'value3')

用作依赖的字段可以是任何 Laravel Nova 字段类型。目前仅支持两种关系字段类型,BelongsToMorphTo

以下是一个使用复选框的示例

Demo

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个模型;CommentVideoPost。在这里,Comment拥有可变形字段commentable_idcommentable_type

对于MorphTo依赖,需要以下结构。

Commentable变为小写commentable,依赖的值是资源单数形式。在这个例子中,依赖容器将仅当选择Post资源时,添加两个额外的字段,Additional TextVisible

MorphTo::make('Commentable')->types([
    Post::class,
    Video::class,
]),

DependencyContainer::make([
    Text::make('Additional Text', 'additional'),
    Boolean::make('Visible', 'visible')
])
->dependsOn('commentable', 'Post') 

索引或详情页面的解决方案

在资源方法fieldsForCreatefieldsForUpdate中使用该字段

DependencyContainer::make([
    Select::make('Parent name', 'parent_id')
        ->options(...)
])->dependsOn('code', 'column'),

要在索引或详情页面上显示一些值,请在资源方法fieldsForIndexfieldsForDetail中使用任何喜欢的字段来显示值

Select::make('Parent name', 'parent_id')
        ->options(...),
        
// OR

Text::make('Parent name', 'parent_id'),

许可证

MIT许可证(MIT)。请参阅许可证文件以获取更多信息。