Skip to content

Commit 5e78c35

Browse files
committed
Allow multiple form submissions
1 parent f036d61 commit 5e78c35

2 files changed

Lines changed: 116 additions & 10 deletions

File tree

src/Livewire/FilamentForm/Show.php

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,11 @@ class Show extends Component implements HasActions, HasForms
3535

3636
public bool $preview;
3737

38+
public bool $allowMultipleSubmissions = false;
39+
3840
public ?array $data = [];
3941

40-
public function mount(FilamentForm $form, bool $blockRedirect = false, bool $preview = false)
42+
public function mount(FilamentForm $form, bool $blockRedirect = false, bool $preview = false, bool $allowMultipleSubmissions = false): void
4143
{
4244
$this->preview = $preview;
4345

@@ -46,6 +48,7 @@ public function mount(FilamentForm $form, bool $blockRedirect = false, bool $pre
4648
$this->form->fill($this->data);
4749

4850
$this->blockRedirect = $blockRedirect;
51+
$this->allowMultipleSubmissions = $allowMultipleSubmissions;
4952
}
5053

5154
public function form(Schema $schema): Schema
@@ -218,15 +221,7 @@ public function create()
218221
}
219222

220223
if (Auth::check()) {
221-
$entryModel = FilamentFormUser::updateOrCreate(
222-
[
223-
'user_id' => Auth::user()->id ?? null,
224-
'filament_form_id' => $this->filamentForm->id,
225-
],
226-
[
227-
'entry' => $entry,
228-
],
229-
);
224+
$entryModel = $this->persistFormEntry($entry);
230225
} else {
231226
$entryModel = FilamentFormUser::create(
232227
[
@@ -325,6 +320,34 @@ public static function extractMultiSelectValue(array $value, array $options): st
325320
return implode(', ', $valuesArray);
326321
}
327322

323+
/**
324+
* @param array<int, array<string, mixed>> $entry
325+
*/
326+
protected function persistFormEntry(array $entry): FilamentFormUser
327+
{
328+
$attributes = [
329+
'user_id' => Auth::user()->id ?? null,
330+
'filament_form_id' => $this->filamentForm->id,
331+
];
332+
333+
if ($this->allowMultipleSubmissions) {
334+
return FilamentFormUser::create([
335+
...$attributes,
336+
'entry' => $entry,
337+
]);
338+
}
339+
340+
return FilamentFormUser::updateOrCreate(
341+
[
342+
'user_id' => $attributes['user_id'],
343+
'filament_form_id' => $attributes['filament_form_id'],
344+
],
345+
[
346+
'entry' => $entry,
347+
],
348+
);
349+
}
350+
328351
public function render()
329352
{
330353
/** @phpstan-ignore-next-line */
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Illuminate\Database\Schema\Blueprint;
6+
use Illuminate\Foundation\Auth\User;
7+
use Illuminate\Support\Facades\Schema;
8+
use Tapp\FilamentFormBuilder\Livewire\FilamentForm\Show;
9+
use Tapp\FilamentFormBuilder\Models\FilamentForm;
10+
use Tapp\FilamentFormBuilder\Models\FilamentFormUser;
11+
12+
beforeEach(function (): void {
13+
Schema::create('users', function (Blueprint $table): void {
14+
$table->id();
15+
$table->string('name');
16+
$table->string('email')->unique();
17+
$table->string('password');
18+
$table->timestamps();
19+
});
20+
21+
$migration = require dirname(__DIR__).'/database/migrations/create_dynamic_filament_form_tables.php.stub';
22+
$migration->up();
23+
});
24+
25+
function createFormBuilderTestUser(string $email): User
26+
{
27+
$user = new User;
28+
$user->forceFill([
29+
'name' => 'Test User',
30+
'email' => $email,
31+
'password' => bcrypt('password'),
32+
]);
33+
$user->save();
34+
35+
return $user;
36+
}
37+
38+
it('updates the existing entry by default for authenticated users', function (): void {
39+
$user = createFormBuilderTestUser('default@example.com');
40+
41+
$form = FilamentForm::query()->create([
42+
'name' => 'Feedback',
43+
'permit_guest_entries' => false,
44+
'locked' => false,
45+
]);
46+
47+
$this->actingAs($user);
48+
49+
$show = new Show;
50+
$show->filamentForm = $form;
51+
$show->allowMultipleSubmissions = false;
52+
53+
$method = new ReflectionMethod(Show::class, 'persistFormEntry');
54+
$method->invoke($show, [['field' => 'rating', 'answer' => 'Agree']]);
55+
$method->invoke($show, [['field' => 'rating', 'answer' => 'Disagree']]);
56+
57+
expect(FilamentFormUser::query()->count())->toBe(1)
58+
->and(FilamentFormUser::query()->first()->entry[0]['answer'])->toBe('Disagree');
59+
});
60+
61+
it('creates a new entry on each submission when allowMultipleSubmissions is enabled', function (): void {
62+
$user = createFormBuilderTestUser('multi@example.com');
63+
64+
$form = FilamentForm::query()->create([
65+
'name' => 'Feedback',
66+
'permit_guest_entries' => false,
67+
'locked' => false,
68+
]);
69+
70+
$this->actingAs($user);
71+
72+
$show = new Show;
73+
$show->filamentForm = $form;
74+
$show->allowMultipleSubmissions = true;
75+
76+
$method = new ReflectionMethod(Show::class, 'persistFormEntry');
77+
$method->invoke($show, [['field' => 'rating', 'answer' => 'Agree']]);
78+
$method->invoke($show, [['field' => 'rating', 'answer' => 'Disagree']]);
79+
80+
expect(FilamentFormUser::query()->count())->toBe(2)
81+
->and(FilamentFormUser::query()->orderBy('id')->pluck('entry')->map(fn (array $entry) => $entry[0]['answer'])->all())
82+
->toBe(['Agree', 'Disagree']);
83+
});

0 commit comments

Comments
 (0)