Skip to content

Commit f0660a0

Browse files
authored
Merge pull request #6 from kirschbaum-development/feature/replace-input-with-nova-field
Replace input with nova field
2 parents 3d43fc7 + 8f0ceb5 commit f0660a0

19 files changed

Lines changed: 1066 additions & 561 deletions

README.md

Lines changed: 213 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
# Nova Inline Relationship
22

33
## Introduction
4-
Nova Inline Relationship is meant to present a relationship based property as an inline property for a Laravel Nova Resource. This project is under active development, and currently only supports singular relationships. You are welcome to request or contribute by opening an issue.
4+
Nova Inline Relationship is meant to present a relationship based property as an inline property for a Laravel Nova Resource. You are welcome to request or contribute by opening an issue.
55

6+
![Nova Inline Relationship](screenshots/NovaInlineRelationship.png "Nova Inline Relationship")
67

78
## Requirements
89

9-
This Nova resource tool requires Nova 2.0 or higher.
10+
This Nova field requires Nova 2.0 or higher.
1011

1112
## Installation
1213

@@ -20,9 +21,8 @@ composer require kirschbaum-development/nova-inline-relationship
2021

2122
After installation, your model should include the `KirschbaumDevelopment\NovaInlineRelationship\Traits\HasRelatedAttributes` trait and you must implement the `KirschbaumDevelopment\NovaInlineRelationship\Contracts\MappableRelationships` Contract.
2223

23-
You must also define a static `getPropertyMap` function in the model which should return the required mapping between local and related attribute.
24-
25-
**_NOTE:_** You must add relationships in `relationship.attribute` format in the map. Nested relationships are currently not supported.
24+
You must also define a static `getPropertyMap` function in the model which should return the required list of properties from your related models you want to show inline.
25+
In this example `Employee` model has two related models `EmployeeProfile` and `EmployeeBill`
2626

2727
```php
2828
use KirschbaumDevelopment\NovaInlineRelationship\Traits\HasRelatedAttributes;
@@ -39,6 +39,15 @@ class Employee extends Model implements MappableRelationships
3939
{
4040
return $this->hasOne(EmployeeProfile::class);
4141
}
42+
43+
/**
44+
* @return HasMany
45+
*/
46+
public function bills(): HasMany
47+
{
48+
return $this->hasMany(EmployeeBill::class);
49+
}
50+
4251

4352
/**
4453
* Should return property map as key value pair.
@@ -47,7 +56,64 @@ class Employee extends Model implements MappableRelationships
4756
*/
4857
public static function getPropertyMap(): array
4958
{
50-
return ['phone' => 'profile.phone', 'fax' => 'profile.fax'];
59+
return [
60+
'profile' => [
61+
'nickname' => [
62+
'label' => 'nickname',
63+
'component' => \Laravel\Nova\Fields\Text::class,
64+
'rules' => 'required',
65+
'placeholder' => 'Add Nickname',
66+
'messages' => ['required' => 'You must add a :attribute for this profile.'],
67+
],
68+
'phone' => [
69+
'component' => \Laravel\Nova\Fields\Number::class,
70+
'label' => 'Phone',
71+
'rules' => 'required|numeric',
72+
'placeholder' => 'Add Phone',
73+
],
74+
'photo' => [
75+
'component' => \Laravel\Nova\Fields\Image::class,
76+
],
77+
'snippet' => [
78+
'component' => \Laravel\Nova\Fields\Code::class,
79+
],
80+
'country' => [
81+
'component' => \Laravel\Nova\Fields\Country::class,
82+
],
83+
'settings' => [
84+
'component' => \Laravel\Nova\Fields\KeyValue::class,
85+
],
86+
'dob' => [
87+
'component' => \Laravel\Nova\Fields\Date::class,
88+
],
89+
],
90+
'bills' => [
91+
'pending' => [
92+
'component' => \Laravel\Nova\Fields\Boolean::class,
93+
'label' => 'Pending',
94+
],
95+
'description' => [
96+
'component' => \Laravel\Nova\Fields\Trix::class,
97+
'label' => 'Description',
98+
'placeholder' => 'Add your description here',
99+
],
100+
'address' => [
101+
'component' => \Laravel\Nova\Fields\Place::class,
102+
],
103+
'amount' => [
104+
'component' => \Laravel\Nova\Fields\Currency::class,
105+
],
106+
'submitted_at' => [
107+
'component' => \Laravel\Nova\Fields\DateTime::class,
108+
],
109+
'auth_code' => [
110+
'component' => \Laravel\Nova\Fields\Password::class,
111+
],
112+
'notes' => [
113+
'component' => \Laravel\Nova\Fields\Markdown::class,
114+
],
115+
],
116+
];
51117
}
52118

53119
// ...
@@ -56,9 +122,7 @@ class Employee extends Model implements MappableRelationships
56122

57123
## Usage
58124

59-
Once you add this relationship map you can use the keys for this relationship map as a normal attribute inside your model's nova resource.
60-
61-
**_NOTE:_** These fields are in essence [Computed Fields](https://nova.laravel.com/docs/2.0/resources/fields.html#computed-fields), and are subjected to the same limitations. Since they are not associated with a database column, these fields will not be `sortable`.
125+
Once you add this relationship map you can add `NovaInlineRelationship` to your Model's resource with a relationship.
62126

63127
```php
64128
namespace App\Nova;
@@ -72,13 +136,150 @@ class Employee extends Resource
72136
return [
73137
//...
74138

75-
Text::make('Phone #', 'phone')
76-
->rules('required'),
139+
NovaInlineRelationship::make('Profile'),
140+
141+
NovaInlineRelationship::make('Bills'),
142+
];
143+
}
144+
}
145+
```
146+
**_NOTE:_** These fields are in essence [Computed Fields](https://nova.laravel.com/docs/2.0/resources/fields.html#computed-fields), and are subjected to the same limitations. Since they are not associated with a database column, these fields will not be `sortable`.
147+
148+
## Adding related models
149+
150+
![Create View](screenshots/CreateView.png "Create View")
151+
152+
After setup you can add new related models directly while creating a new base model. For example, If you have added an `EmployeeProfile` model as a related model for your `Employee` model, you can infact add information for a related `EmployeeProfile` model without going through an additional step. You can use the `Add new Profile` button to add a new blank profile
153+
154+
![Create Related Model](screenshots/CreateRelatedModel.png "Create Related Model")
155+
156+
## Adding multiple related models
157+
158+
If your relationship is a `one-to-many` relationship you can add multiple related models in a one go.
159+
160+
![Multiple Related Model](screenshots/MultipleRelatedModels.png "Multiple Related Model")
161+
162+
## Viewing related models
163+
164+
Once you add your related models and visit your base model's detail view you can watch your related models in a collapsible view. So when you will watch an `Employee` model, you can watch `EmployeeProfile` models in a collapsible view.
165+
166+
![Detail View](screenshots/DetailView.png "Detail View")
167+
168+
## Updating related models
169+
170+
When you will edit your base model, you will be able to add, update and remove your related model's in a view similar to create form.
171+
172+
For `one-to-many` relationships you can drag and drop related models to rearrange them in relation to your base model.
173+
174+
![Rearrange Models](screenshots/RearrangeModels.png "Rearrange Models")
175+
176+
## Deleting related models
177+
178+
You can delete related models from the base model's update view by using the `delete button` at the top right corner.
77179

78-
Number::make('Fax Number', 'fax'),
180+
## Validating related models
181+
182+
You can specify the validation rule for the fields in your related model using the `getPropertyMap()` function.
183+
184+
An error will be displayed next to field if a validation rule is not met.
185+
186+
![Validating Models](screenshots/Validation.png "Validating Models")
187+
188+
### Specifying custom error messages
189+
190+
You can specify custom error messages for field in format specified in the [laravel documentation](https://laravel.com/docs/5.8/validation#customizing-the-error-messages).
191+
192+
For every field you can specify validation messages for each rule. You can use attribute wildcards like `:attribute` in your error messages as well.
193+
194+
```php
195+
use KirschbaumDevelopment\NovaInlineRelationship\Traits\HasRelatedAttributes;
196+
use KirschbaumDevelopment\NovaInlineRelationship\Contracts\MappableRelationships;
197+
198+
class Employee extends Model implements MappableRelationships
199+
{
200+
// ...
201+
202+
/**
203+
* Should return property map as key value pair.
204+
*
205+
* @return array
206+
*/
207+
public static function getPropertyMap(): array
208+
{
209+
return [
210+
'profile' => [
211+
'phone' => [
212+
'component => Number::class,
213+
'label' => 'Phone',
214+
'rules' => 'required|numeric',
215+
'placeholder' => 'Add Phone',
216+
'messages' => [
217+
'required' => 'You must add a :attribute for this profile.',
218+
'numeric' => 'Your :attribute must be numeric'
219+
],
220+
],
221+
],
79222
];
80223
}
224+
225+
// ...
81226
}
227+
```
228+
229+
## Settings
230+
231+
You can pass on following items for your related model's attributes:-
232+
1. `component`: The component use to render the field. You should provide the component name specified in the field like Text::class, Number::class, Boolean::class and so on.
233+
2. `label`: Label for your field. This will also be used as the field name in error messages.
234+
3. `rules`: A rule string in [Laravel Validation format](https://laravel.com/docs/5.8/validation#available-validation-rules).
235+
4. `messages`: An array of error messages to be used in validation.
236+
5. `placeholder`: A placeholder for your field.
237+
6. `options`: Additional options for your components
238+
239+
## Supported fields
240+
241+
You can use any field you can add to your Nova resource with `Field::make` syntax. The following native Nova 2.0 fields are confirmed to work.
242+
243+
- Boolean Field
244+
- Code Field
245+
- Country Field
246+
- Currency Field
247+
- Date Field
248+
- DateTime Field
249+
- Markdown Field
250+
- Number Field
251+
- Password Field
252+
- Place Field
253+
- Select Field
254+
- Text Field
255+
- Textarea Field
256+
- Timezone Field
257+
- Trix Field
258+
- Avatar Field
259+
- Image Field
260+
- File Field
261+
262+
### Select Component
263+
To pass dropdown options to your select component, pass an array of key values to options
264+
```php
265+
'component => Select::class,
266+
'options' => [
267+
'options' => [
268+
['label' => 'Yes', 'value' => true],
269+
['label' => 'No', 'value' => false],
270+
],
271+
]
272+
```
273+
274+
### Number/Currency Component
275+
You can pass `min`, `max` and `step` to number and currency field
276+
```php
277+
'component' => Currency::class,
278+
'options' => [
279+
'min' => 0,
280+
'max' => 100,
281+
'step' => 10,
282+
],
82283
```
83284

84285
## Changelog

0 commit comments

Comments
 (0)