Skip to content
This repository was archived by the owner on Jul 5, 2024. It is now read-only.

Commit ca846f1

Browse files
authored
Merge pull request #13 from subzero10/master
Add support for DynamicSelect in Laravel Nova Actions
2 parents 3b18406 + 3622395 commit ca846f1

File tree

5 files changed

+91
-13
lines changed

5 files changed

+91
-13
lines changed

README.md

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ composer require royduin/laravel-nova-field-dynamic-select
1212

1313
## Usage
1414

15-
Class have 2 special methods on top of default Select from Laravel Nova.
15+
Class has 3 special methods on top of default Select from Laravel Nova.
1616
- `dependsOn` can take a list of other fields this one depends on.
17-
- `options` can be either an array or a callable.
17+
- `options` can be either an array or a callable.
18+
- `forAction` to indicate that the dynamic select is running in an action
1819

1920
If its a callable, it will receive array with selected dependency values as first argument and should return an array of items to be shown on the select field.
2021

@@ -53,3 +54,39 @@ public function fields(Request $request)
5354
5455
```
5556

57+
## Example for use in Nova Actions
58+
59+
```
60+
public function fields(Request $request)
61+
{
62+
return [
63+
ID::make()->sortable(),
64+
65+
DynamicSelect::make('Country', 'country')
66+
->forAction(self::class)
67+
->options(['US' => 'United States', 'UK' => 'United Kingdom'])
68+
->rules('required')
69+
,
70+
71+
DynamicSelect::make('Provider', 'provider')
72+
->forAction(self::class)
73+
->options(['PR' => 'Premium', 'ST' => 'Standard'])
74+
->rules('required')
75+
,
76+
77+
DynamicSelect::make('Product', 'product')
78+
->forAction(self::class)
79+
->dependsOn(['country', 'provider'])
80+
->options(function($values) {
81+
if($values['country'] === 'UK' && $values['provider'] === 'PR') {
82+
return ['A' => 'Fast shipping', 'B' => 'Normal shipping', 'C' => 'Free shipping'];
83+
} else {
84+
return ['A' => 'Fast shipping', 'B' => 'Normal shipping'];
85+
}
86+
})
87+
->rules('required')
88+
,
89+
];
90+
}
91+
92+
```

dist/js/field.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

resources/js/components/FormField.vue

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,19 @@ export default {
142142
? dependsOnValue.field.originalAttribute.toLowerCase()
143143
: dependsOnValue.field.attribute.toLowerCase();
144144
145+
const depends = this.getDependValues(dependsOnValue.value, originalDependsOnAttribute);
146+
let jsoned = {};
147+
for (let i in depends) {
148+
if (!depends.hasOwnProperty(i)) {
149+
continue;
150+
}
151+
jsoned[i] = depends[i];
152+
}
153+
145154
this.options = (await Nova.request().post("/nova-vendor/dynamic-select/options/"+this.resourceName, {
146155
attribute: this.field.originalAttribute ? this.field.originalAttribute : this.removeFlexibleContentPrefix(this.field.attribute),
147-
depends: this.getDependValues(dependsOnValue.value, originalDependsOnAttribute)
156+
depends: this.getDependValues(dependsOnValue.value, originalDependsOnAttribute),
157+
action: this.field.action,
148158
})).data.options;
149159
150160
if(this.value) {

src/DynamicSelect.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class DynamicSelect extends Field
1717
public $component = 'dynamic-select';
1818
public $labelKey;
1919
public $multiselect = false;
20+
public $action = null;
2021

2122
public function resolve($resource, $attribute = null)
2223
{
@@ -111,6 +112,12 @@ public function labelKey($labelKey)
111112
return $this;
112113
}
113114

115+
public function forAction(string $className) {
116+
$this->action = $className;
117+
118+
return $this;
119+
}
120+
114121
public function meta()
115122
{
116123
$this->meta = parent::meta();
@@ -124,6 +131,7 @@ public function meta()
124131
'selectedLabel' => __('Selected'),
125132
'labelKey' => $this->labelKey,
126133
'multiselect' => $this->multiselect,
134+
'action' => $this->action
127135
], $this->meta);
128136
}
129137
}

src/Http/Controllers/OptionsController.php

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,28 @@ public function index(NovaRequest $request)
1313
$attribute = $request->input('attribute');
1414
$dependValues = $request->input('depends');
1515

16+
if ($request->has('action')) {
17+
$field = $this->getFieldFromAction($request, $attribute);
18+
}
19+
else {
20+
$field = $this->getFieldFromResource($request, $attribute);
21+
}
22+
23+
abort_if(is_null($field), 400);
24+
25+
/** @var DynamicSelect $field */
26+
$options = $field->getOptions($dependValues);
27+
28+
return [
29+
'options' => $options,
30+
];
31+
}
32+
33+
private function getFieldFromResource(NovaRequest $request, $attribute) {
1634
$resource = $request->newResource();
1735

36+
$field = null;
37+
1838
// Nova tabs compatibility:
1939
// https://github.com/eminiarts/nova-tabs
2040
if (method_exists($resource, 'parentUpdateFields')) {
@@ -42,17 +62,17 @@ public function index(NovaRequest $request)
4262
}
4363
}
4464

45-
// Dependency container compatibility:
46-
// https://github.com/epartment/nova-dependency-container
65+
// Dependency container compatibility:
66+
// https://github.com/epartment/nova-dependency-container
4767
} elseif ($updateField->component == 'nova-dependency-container') {
4868
foreach ($updateField->meta['fields'] as $layoutField) {
4969
if ($layoutField->attribute === $attribute) {
5070
$field = $layoutField;
5171
}
5272
}
5373

54-
// Conditional container compatibility:
55-
// https://github.com/dcasia/conditional-container
74+
// Conditional container compatibility:
75+
// https://github.com/dcasia/conditional-container
5676
} elseif ($updateField->component === 'conditional-container') {
5777
foreach ($updateField->fields as $layouts) {
5878
if ($layouts->component === 'nova-flexible-content') {
@@ -69,11 +89,14 @@ public function index(NovaRequest $request)
6989
}
7090
}
7191

72-
/** @var DynamicSelect $field */
73-
$options = $field->getOptions($dependValues);
92+
return $field;
93+
}
7494

75-
return [
76-
'options' => $options,
77-
];
95+
private function getFieldFromAction(NovaRequest $request, $attribute) {
96+
$class = $request->input('action');
97+
$action = new $class();
98+
return collect($action->fields())->first(function ($f) use ($attribute) {
99+
return $f->attribute === $attribute;
100+
});
78101
}
79102
}

0 commit comments

Comments
 (0)