This package allows you to include your nested relationships' forms into a parent form.
Add package to your composer with git reference
"repositories": [
{
"url": "https://github.com/handleglobal/laravel-nova-nested-form.git",
"type": "git"
}
]
composer require handleglobal/nova-nested-form:dev-master
As I did not anticipate so many people would use that package (which is awesome) and simply do not have enough time to update/enhance this package more regularly on my own, I am looking for other contributors to help me with the maintenance and feature requests. Don't hesitate to contact me if you're interested!
Simply add a NestedForm into your fields. The first parameter must be an existing NovaResource class and the second parameter (optional) must be an existing HasOneOrMany relationship in your model.
namespace App\Nova;
use Laravel\Nova\Fields\ID;
use Illuminate\Http\Request;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Fields\Gravatar;
use Laravel\Nova\Fields\Password;
// Add use statement here.
use Handleglobal\NestedForm\NestedForm;
class User extends Resource
{
...
public function fields(Request $request)
{
return [
ID::make()->sortable(),
Gravatar::make(),
Text::make('Name')
->sortable()
->rules('required', 'max:255'),
Text::make('Email')
->sortable()
->rules('required', 'email', 'max:254')
->creationRules('unique:users,email')
->updateRules('unique:users,email,{{resourceId}}'),
Password::make('Password')
->onlyOnForms()
->creationRules('required', 'string', 'min:6')
->updateRules('nullable', 'string', 'min:6'),
// Add NestedForm here.
NestedForm::make('Posts'),
];
}
For instance, if the nested form should only be available if the value of the "has_comments" attirbute is true, you can use:
class Post extends Resource
{
...
public function fields(Request $request)
{
return [
Boolean::make('Has Comments'),
NestedForm::make('Comments')->displayIf(function ($nestedForm, $request) {
return [
[ 'attribute' => 'has_comments', 'is' => true ]
];
];
}
})
The displayIf method is excepted to return an array of array as you may want to add several conditions.
class Post extends Resource
{
...
public function fields(Request $request)
{
return [
Boolean::make('Has Comments'),
Text::make('Title'),
Text::make('Subtitle')->nullable(),
Number::make('Number of comments allowed'),
NestedForm::make('Comments')->displayIf(function ($nestedForm, $request) {
return [
[ 'attribute' => 'has_comments', 'is' => true ],
[ 'attribute' => 'title', 'isNotNull' => true ],
[ 'attribute' => 'subtitle', 'isNull' => true ],
[ 'attribute' => 'title', 'includes' => 'My' ],
[ 'attribute' => 'number_of_comments_allowed', 'moreThanOrEqual' => 1 ],
// Integration for nova booleanGroup field
[ 'attribute' => 'my_multiple_checkbox', 'booleanGroup' => 'the_checkbox_key_to_target' ],
];
})
];
}
}
The package will then add those conditions and dynamically update your form as you fill the fields. The available rules are:
- is
- isNot
- isNull
- isNotNull
- isMoreThan
- isMoreThanOrEqual
- isLessThan
- isLessThanOrEqual
- includes
- booleanGroup
For instance, if you want every user to have at least 3 posts and at most 5 posts, simply use:
NestedForm::make('Posts')->min(3)->max(5),
Please note that the package automatically detects whether the relationship excepts many children or a single child, and sets the maximum value accordingly.
When creating a new user, 3 blank posts will be displayed. If you reach the maximum number of posts, the "Add a new post" button will disappear.
If you want the nested forms to be opened by default, simply use:
NestedForm::make('Posts')->open(true),
You can modify the default heading using the heading() method. You can use the helper method wrapIndex() to add the current child index to your header.
NestedForm::make('Posts')->heading(NestedForm::wrapIndex() . ' // Post'),
You can also add any attribute of the current child into your heading using the helper method wrapAttribute().
NestedForm::make('Posts')->heading(NestedForm::wrapIndex() . ' // ' . NestedForm::wrapAttribute('title', 'My default title')),
You can modify the default index separator using the separator() method when you have nested forms (e.g. 1. Post, 1.1. Comment, 1.1.1. Like).
NestedForm::make('Posts')->separator('\'),