stepanenko3 / nova-json
Nova json field to spread a json column throughout multiple fields.
Installs: 134 809
Dependents: 0
Suggesters: 0
Security: 0
Stars: 39
Watchers: 3
Forks: 8
Open Issues: 8
Language:Vue
Type:package
Requires
- php: >=8.0
- laravel/nova: ^4.0
README
Description
The JSON
field wrapper allows you to specify multiple fields which will be resolved into a single model attribute. This allows you to validate every information you store inside a json column seperately.
Features
- Fields for JSON keys
- Array of fields
- Repeatable field groups
- Works with Tabs
Requirements
php: >=8.0
laravel/nova: ^4.0
Installation
# Install the package
composer require stepanenko3/nova-json
Usage
use Stepanenko3\NovaJson\Fields\JsonArray; use Stepanenko3\NovaJson\Fields\JsonRepeatable; ... JsonArray::make('Mails', 'mails->main') ->fullWidth() ->rules([ 'required', 'array', 'between:1,10', ]) ->field( field: Email::make('Email', 'value') ->fullWidth() ->rules([ 'required', 'email:rfc,dns', ]), ), JsonRepeatable::make('Mails For Countries', 'mails->countries') ->fullWidth() ->rules([ 'required', 'array', 'between:1,10', ]) ->fields([ Country::make('Country', 'country') ->fullWidth() ->rules([ 'required', ]), JsonArray::make('Mails', 'mails') ->fullWidth() ->rules([ 'required', 'array', 'between:1,10', ]) ->field( field: Email::make('Email', 'value') ->fullWidth() ->rules([ 'required', 'email:rfc,dns', ]), ), ]),
The Big Example
use Stepanenko3\NovaJson\Fields\JsonArray; use Stepanenko3\NovaJson\Fields\JsonRepeatable; ... new Tabs('JSON', [ 'Address' => [ Text::make('Country', 'settings->address->country') ->rules([ 'required', ]), Text::make('City', 'settings->address->city') ->readonly() ->rules([ 'required', ]) ->dependsOn( attributes: ['settings->address->country'], mixin: function (Text $field, NovaRequest $request, FormData $formData) { if ($formData->{'settings->address->country'}) { $field->readonly(false); } }, ), Text::make('Street', 'settings->address->street') ->readonly() ->rules([ 'required', ]) ->dependsOn( attributes: ['settings->address->city'], mixin: function (Text $field, NovaRequest $request, FormData $formData) { if ($formData->{'settings->address->city'}) { $field->readonly(false); } }, ), Heading::make('Location'), Text::make('Latitude', 'settings->address->location->latitude') ->readonly() ->rules([ 'required', ]) ->dependsOn( attributes: ['settings->address->city'], mixin: function (Text $field, NovaRequest $request, FormData $formData) { if ($formData->{'settings->address->city'}) { $field->readonly(false); } }, ), Text::make('Longitude', 'settings->address->location->longitude') ->readonly() ->rules([ 'required', ]) ->dependsOn( attributes: ['settings->address->city'], mixin: function (Text $field, NovaRequest $request, FormData $formData) { if ($formData->{'settings->address->city'}) { $field->readonly(false); } }, ), ], 'Brand' => [ Color::make('Primary Color', 'settings->brand->colors->primary') ->rules([ 'required', ]), Color::make('Secondary Color', 'settings->brand->colors->secondary') ->rules([ 'required', ]), ], 'Links' => [ Text::make('Website', 'settings->links->website') ->rules(['required', 'string', 'nullable', 'min:3', 'url']), Text::make('iOS', 'settings->links->ios') ->rules(['string', 'nullable', 'min:3', 'url']), Text::make('Android', 'settings->links->android') ->rules(['string', 'nullable', 'min:3', 'url']), ], 'Mailing' => [ JsonArray::make('Mails', 'settings->mails->main') ->fullWidth() ->rules([ 'required', 'array', 'between:1,10', ]) ->field( field: Email::make('Email', 'value') ->fullWidth() ->rules([ 'required', 'email:rfc,dns', ]), ), JsonRepeatable::make('Mails For Countries', 'settings->mails->countries') ->fullWidth() ->rules([ // 'required', 'array', 'between:1,10', ]) ->fields([ Country::make('Country', 'country') ->fullWidth() ->rules([ 'required', ]), JsonArray::make('Mails', 'mails') ->fullWidth() ->rules([ 'required', 'array', 'between:1,10', ]) ->field( field: Email::make('Email', 'value') ->fullWidth() ->rules([ 'required', 'email:rfc,dns', ]), ), ]), ], 'Tiles' => [ JsonRepeatable::make('Tiles', 'settings->tiles') ->fullWidth() ->stacked() ->rules([ 'required', 'array', 'between:2,1000', ]) ->fields([ Number::make('count', 'count') ->fullWidth() ->rules([ 'required', 'numeric', 'between:0,100', ]), Number::make('height', 'height') ->fullWidth() ->step(0.01) ->rules([ 'required', 'numeric', 'between:0,100', ]), BooleanGroup::make('Settings', 'settings') ->fullWidth() ->options([ 'display' => 'Display', 'primary' => 'Primary', ]), ]), ], 'Demo' => [ JsonRepeatable::make('Layouts', 'settings->layouts') ->fullWidth() ->stacked() ->rules([ 'required', 'array', 'max:3', ]) ->fields([ Currency::make('Currency', 'value1') ->fullWidth() ->rules(['required', 'in:100,200,300,400,500']), Currency::make('Currency 2', 'value2') ->fullWidth() ->rules(['required', 'in:100,200,300,400,500']), BooleanGroup::make('Demo', 'demo') ->fullWidth() ->options([ 'demo' => 'Demo', 'demo2' => 'Demo2', ]), Markdown::make('Demo2', 'demo2') ->fullWidth(), JsonArray::make('Demo3', 'demo3') ->fullWidth() ->field( field: Text::make('Value', 'value') ->fullWidth(), ), JsonArray::make('Demo4', 'demo4') ->fullWidth() ->field( JsonRepeatable::make('Value', 'value') ->fullWidth() ->rules([ 'required', 'array', 'max:3', ]) ->fields([ Currency::make('Currency', 'value1') ->fullWidth()->rules(['required', 'in:100,200,300,400,500']), Currency::make('Currency 2', 'value2') ->fullWidth()->rules(['required', 'in:100,200,300,400,500']), ]), ), ]), ] ]),
Stored json data
{ "mails": { "main": [ "demo@gmail.com" ], "countries": [ { "mails": [ "demo1@gmail.com", "demo2@gmail.com" ], "country": "UA" }, { "mails": [ "demo3@gmail.com" ], "country": "AS" } ] }, "brand": { "colors": { "secondary": "#b1dd8c", "primary": "#d95000" } }, "tiles": [ { "settings": { "primary": false, "display": true }, "count": "3", "height": "2" }, { "settings": { "primary": true, "display": true }, "count": "1", "height": "0.75" } ], "address": { "street": "Maidan", "city": "Kyiv", "country": "Ukraine", "location": { "longitude": "200", "latitude": "100" } }, "links": { "android": null, "ios": null, "website": "https:\/\/laravel.com\/" } }
Screenshots
Credits
Contributing
Thank you for considering contributing to this package! Please create a pull request with your contributions with detailed explanation of the changes you are proposing.
License
This package is open-sourced software licensed under the MIT license.