diff --git a/packages/forms/docs/03-fields/03-select.md b/packages/forms/docs/03-fields/03-select.md index f64aa14eec..1da5a36f40 100644 --- a/packages/forms/docs/03-fields/03-select.md +++ b/packages/forms/docs/03-fields/03-select.md @@ -264,6 +264,21 @@ Select::make('author_id') ->searchable(['first_name', 'last_name']) ``` +### Saving pivot data to the relationship + +If you're using a `multiple()` relationship and your pivot table has additional columns, you can use the `pivotData()` method to specify the data that should be saved in them: + +```php +use Filament\Forms\Components\Select; + +Select::make('primaryTechnologies') + ->relationship(name: 'technologies', titleAttribute: 'name') + ->multiple() + ->pivotData([ + 'is_primary' => true, + ]) +``` + ### Creating a new option in a modal You may define a custom form that can be used to create a new record and attach it to the `BelongsTo` relationship: diff --git a/packages/forms/docs/03-fields/06-checkbox-list.md b/packages/forms/docs/03-fields/06-checkbox-list.md index 0969434b9a..c6155c4983 100644 --- a/packages/forms/docs/03-fields/06-checkbox-list.md +++ b/packages/forms/docs/03-fields/06-checkbox-list.md @@ -240,6 +240,20 @@ CheckboxList::make('authors') ->getOptionLabelFromRecordUsing(fn (Model $record) => "{$record->first_name} {$record->last_name}") ``` +### Saving pivot data to the relationship + +If your pivot table has additional columns, you can use the `pivotData()` method to specify the data that should be saved in them: + +```php +use Filament\Forms\Components\CheckboxList; + +CheckboxList::make('primaryTechnologies') + ->relationship(name: 'technologies', titleAttribute: 'name') + ->pivotData([ + 'is_primary' => true, + ]) +``` + ## Setting a custom no search results message When you're using a searchable checkbox list, you may want to display a custom message when no search results are found. You can do this using the `noSearchResultsMessage()` method: diff --git a/packages/forms/src/Components/CheckboxList.php b/packages/forms/src/Components/CheckboxList.php index 28db14e1dc..fc9576fb8b 100644 --- a/packages/forms/src/Components/CheckboxList.php +++ b/packages/forms/src/Components/CheckboxList.php @@ -24,6 +24,7 @@ class CheckboxList extends Field implements Contracts\CanDisableOptions, Contrac use Concerns\HasGridDirection; use Concerns\HasNestedRecursiveValidationRules; use Concerns\HasOptions; + use Concerns\HasPivotData; /** * @var view-string @@ -185,7 +186,15 @@ class CheckboxList extends Field implements Contracts\CanDisableOptions, Contrac }); $this->saveRelationshipsUsing(static function (CheckboxList $component, ?array $state) { - $component->getRelationship()->sync($state ?? []); + $pivotData = $component->getPivotData(); + + if ($pivotData === []) { + $component->getRelationship()->sync($state ?? []); + + return; + } + + $component->getRelationship()->syncWithPivotValues($state ?? [], $pivotData); }); $this->dehydrated(false); diff --git a/packages/forms/src/Components/Concerns/HasPivotData.php b/packages/forms/src/Components/Concerns/HasPivotData.php new file mode 100644 index 0000000000..ea4b817171 --- /dev/null +++ b/packages/forms/src/Components/Concerns/HasPivotData.php @@ -0,0 +1,31 @@ + | Closure + */ + protected array | Closure $pivotData = []; + + /** + * @param array | Closure $data + */ + public function pivotData(array | Closure $data): static + { + $this->pivotData = $data; + + return $this; + } + + /** + * @return array + */ + public function getPivotData(): array + { + return $this->evaluate($this->pivotData) ?? []; + } +} diff --git a/packages/forms/src/Components/Select.php b/packages/forms/src/Components/Select.php index d196f28e7a..ebed92312e 100644 --- a/packages/forms/src/Components/Select.php +++ b/packages/forms/src/Components/Select.php @@ -46,6 +46,7 @@ class Select extends Field implements Contracts\CanDisableOptions, Contracts\Has use Concerns\HasLoadingMessage; use Concerns\HasNestedRecursiveValidationRules; use Concerns\HasOptions; + use Concerns\HasPivotData; use Concerns\HasPlaceholder; use HasExtraAlpineAttributes; @@ -963,7 +964,15 @@ class Select extends Field implements Contracts\CanDisableOptions, Contracts\Has return; } - $relationship->sync($state ?? []); + $pivotData = $component->getPivotData(); + + if ($pivotData === []) { + $relationship->sync($state ?? []); + + return; + } + + $relationship->syncWithPivotValues($state ?? [], $pivotData); }); $this->createOptionUsing(static function (Select $component, array $data, Form $form) {