For a project we need a form for saving subscribers.
You should be able to input 4 values: subscribers_f, subscribers_m, subscribers_d, and the sum of all subscribers.
You can also select a category from a dropdown.
For categories 2 and 3 you need to check that the actual sum (f+m+d) matches the “sum” input field.
If the sum does not match up, you should show a validation error next to the input field.
Thats how you do it:
Create a Request with
php artisan make:request StoreItemRequest
Use the new Request in your update
/store
controller actions. This is an example of a combined update
/store
action, it needs the id
of the updated Item as a form field.
public function store(StoreItemRequest $request) {
$validated = $request->validated();
if($validated['id'] ?? false) {
$item = Item::find($validated['id']);
$item->update($validated);
} else {
$item = Item::create($validated);
}
return redirect()->route('item.show')->with('success','Item saved.');
}
Then you can create custom validation rules in your StoreItemRequest class like this:
class StoreItemRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'id' => 'integer',
'category_id' => ['integer','required'],
'subscribers_f' => ['integer','required'],
'subscribers_m' => ['integer','required'],
'subscribers_d' => ['integer','required'],
'subscribers_sum' => ['integer',
function (string $attribute, mixed $value, Closure $fail) {
if(in_array($this->category_id, [2,3])) {
if (($this->subscribers_f + $this->subscribers_m + $this->subscribers_d) != $this->subscribers_sum) {
$fail("Sum subscribers (".$this->subscribers_sum.") not equal to sum of f+m+d (".$this->subscribers_f + $this->subscribers_m + $this->subscribers_d.")");
}
}
},
],
]
}
}
In your blade view you can show the errors as usual (Note: This uses TailwindCSS):
{{html()->text('subscribers_sum')->value($item?->subscribers_sum?? 0)}}
@if($errors->has('subscribers_sum'))
<div class="alert alert-danger alert-dismissible fade show sm:rounded-lg p-2" role="alert">{{$errors->first('subscribers_sum')}}</div>
@endif
If you want to prefill the Form values when updating, i recommend using livewire for your form and prefilling the values there in your mount()
action. There you can implement a logic that respects old()
and existing values.