fourstacks / nova-repeatable-fields
Laravel Nova 字段。
Requires
- php: >=7.1.0
README
注意
强烈建议您使用 Nova Flexible Content 软件包而不是此软件包
Nova Flexible Content 软件包正在积极维护,允许您将任何有效的 Nova 字段用作子字段。由于其他承诺,此软件包仅偶尔维护,不太可能添加新功能,因此新用户应强烈考虑使用 Nova Flexible Content 而不是此软件包。
希望迁移到 Nova Flexible Content 的此软件包现有用户需要做一点工作来迁移数据。请参阅下面的附录,提供迁移数据的一个潜在解决方案。
Nova 应用程序的重复字段
此软件包包含一个 Laravel Nova 字段,允许创建可重复的“子”字段集。Nova 用户可以自由创建、重新排序和删除多行数据,这些数据通过您定义的子字段。数据以 JSON 格式保存到数据库中。
示例
安装
您可以通过 composer 将此软件包安装到使用 Nova 的 Laravel 应用程序中
composer require fourstacks/nova-repeatable-fields
使用方法
要添加重复字段,请使用 Nova 资源中的 Fourstacks\NovaRepeatableFields\Repeater
字段
namespace App\Nova; use Fourstacks\NovaRepeatableFields\Repeater; // ... class Petstore extends Resource { // ... public function fields(Request $request) { return [ // ... Repeater::make('Dogs'), // ... ]; } }
为了使用此软件包,您还应确保代表 Nova 资源的 Eloquent 模型将您希望用作重复字段的属性强制转换为数组
namespace App; // ... class Petstore extends Model { protected $casts = [ 'dogs' => 'array' ] }
底层数据库字段应该是 string
或 text
类型字段。
配置
此软件包包含各种选项,您可以使用这些选项定义重复字段内的子字段
addField
参数:array
您创建的每个重复字段至少应包含一个通过 addField
添加的子字段。addField
方法接受一个子字段配置选项数组
Repeater::make('Dogs') ->addField([ // configuation options ])
配置选项包括:
label
[ 'label' => 'Dog name', //... ]
所有子字段必须至少定义一个“标签”。这是一个可读性强的字符串,将出现在 Nova UI 中。
name
[ 'name' => 'dog_name', //... ]
默认情况下,子字段的 name
(在数据库中保存数据时使用)将自动生成,使用子字段 label
的蛇形版本。或者,您可以自由地覆盖此约定并定义一个用于的名称。
类型
[ 'type' => 'number', //... ]
默认情况下,子字段的输入类型将是一个标准文本字段。如果您希望,可以定义不同的字段类型。当前支持的子字段类型有:'text'、'number'、'select'、'textarea'。
占位符
[ 'placeholder' => 'Name that dog', //... ]
默认情况下,输入的 placeholder
将与子字段的 label
相同。但是,您可以使用此选项定义一个自定义占位符,它将代替显示。
宽度
[ 'width' => 'w-1/2', //... ]
如果您选择在行中显示您的子字段(而不是堆叠 - 请参阅下面的 displayStackedForm
选项),则可以使用 Tailwind 的分数宽度类 定义您的字段宽度。除非您想要这样做,否则无需定义所有字段的宽度。如果没有为任何子字段输入宽度,则所有子字段将具有相同的宽度。
请注意,您可以混合和匹配宽度。例如,您可能希望将前两个字段的宽度设置为 50%,使用 w-1/2
,然后将最后一个字段设置为全宽度通过 w-full
。
如果您正在显示堆叠布局中的子字段,则宽度选项将不起作用。
选项
[ 'options' => [ 'fido' => 'Fido', 'mr_bubbles' => 'Mr Bubbles', 'preston' => 'Preston' ], //... ]
如果您正在定义的子字段的 type
是 'select',则需要为选择字段定义一个选项数组。这些是通过键/值对数组定义的。
属性
[ 'attributes' => [ 'min' => 1, 'max' => '20', 'style' => 'color: red' ], //... ]
通过 attributes
键,您可以自由定义任何您希望通过关联数组添加到输入的自定义属性。这些将通过 v-bind
添加。例如,您可能希望向数字字段或文本字段添加最小或最大步骤,或添加样式属性。
添加按钮文本
Repeater::make('Dogs') ->addButtonText('Add new dog');
您可以配置用于在 Nova UI 中添加新子字段集的按钮的文本。默认情况下,此按钮标记为 '添加行',但您可以使用 addButtonText
选项覆盖此内容。
摘要标签
Repeater::make('Dogs') ->summaryLabel('Dogs');
详细视图和索引视图显示使用重复字段输入的数据的摘要。默认情况下,这将是行的计数,例如 '3 行',以及一个链接以展开以显示输入的全部数据。
您可以覆盖此摘要文本以使其更具体,例如 '3 只狗'。
显示堆叠表单
Repeater::make('Dogs') ->displayStackedForm();
默认情况下,一组子字段将作为一系列水平对齐的输入字段显示。
这对于只有 2 或 3 个子字段的重复字段来说效果很好,但对于较大的字段集,一个显示重复子字段堆叠的表单布局通常更易于使用。您可以使用此选项切换到堆叠布局。
初始行数
Repeater::make('Dogs') ->initialRows(4);
设置在表单初始化时预添加的初始行数。对于具有现有行的表单,它将追加到设置的行数。
最大行数
Repeater::make('Dogs') ->maximumRows(4);
设置行数的上限。达到此限制后,您将无法添加新行。
标题
Repeater::make('Dogs') ->heading('Dog');
设置每行之间的标题(例如:狗 #1,狗 #2)。仅在“displayStackedForm”使用时有效。
附录 - 将数据迁移到Nova灵活内容
本指南仅适用于希望使用Nova灵活内容包的现有用户,并希望了解如何迁移数据。
请注意,以下解决方案仅为指南。您需要根据您的数据实现和测试解决方案,并且在运行任何可能更改多个数据库行的代码之前,强烈建议您备份任何数据。
我对于您使用以下代码对现有数据造成的任何更改不承担任何责任。明白了?好的,让我们继续...
本指南假设您已经安装了Nova灵活内容包,并且已经为要迁移的数据设置了一个布局。
接下来,在您的应用程序中创建一个新的Artisan命令:php artisan make:command MigrateRepeaterData
添加以下代码,以便您的命令看起来像这样
<?php namespace App\Console\Commands; use Illuminate\Console\Command; use Illuminate\Support\Facades\Schema; class MigrateRepeaterData extends Command { /** * The name and signature of the console command. * * @var string */ protected $signature = 'nfc:migrate'; /** * The console command description. * * @var string */ protected $description = 'Migrate your repeater data to be compatible with Nova Flexible Content'; /** * Execute the console command. * * @return mixed */ public function handle() { // Get the model to run this command for $model = $this->ask('Which model do you want to migrate data for? Enter the full namespace e.g. App\Post'); if(! class_exists($model)){ $this->error("Sorry - could not find a model called {$model}"); return; } // Get the attribute on the model that holds the old repeater data $attribute = $this->ask('Which model attribute holds the data you want to migrate?'); if(! Schema::hasColumn((new $model)->getTable(), $attribute) ){ $this->error("Sorry - could not find a database column called {$attribute} for {$model}"); return; } // Get the Nova Flexible Content layout name $layout = $this->ask('What is the name of the Nova Flexible Content layout for this data?'); $models = $model::all(); if ($this->confirm("About to migrate data for {$models->count()} models. Do you wish to continue?")) { $models->each(function($model) use ($attribute, $layout){ $model->$attribute = $this->updateValues($model->$attribute, $layout); $model->save(); }); $this->info('All done! Please check your data to ensure it was migrated correctly'); } } protected function updateValues($data, $layout) { // Skip anything that is not an array with elements and keep the value the same if(! $data){ return $data; } return collect($data) ->map(function($attributes) use ($layout){ return [ // Create a random key 'key' => $this->generateKey(), // my_nova_flexible_content_layout should match the name // you gave to your Nova Flexible Content layout 'layout' => $layout, // The data for a given repeater 'row' 'attributes' => $attributes ]; }) ->all(); } protected function generateKey() { if (function_exists("random_bytes")) { $bytes = random_bytes(ceil(16/2)); } elseif (function_exists("openssl_random_pseudo_bytes")) { $bytes = openssl_random_pseudo_bytes(ceil(16/2)); } else { throw new \Exception("No cryptographically secure random function available"); } return substr(bin2hex($bytes), 0, 16); } }
变更日志
有关最近更改的更多信息,请参阅变更日志。
致谢
许可
MIT许可(MIT)。有关更多信息,请参阅许可文件。