Custom Validation

I'm having a 2 fields: (1) Price (2) Checkbox Task 1) If the price is less than a specific amount then the checkbox check is required. Task 2) Display a validation error message only if the price is less than a specific amount. Form submit will be allowed I've done below code and it's not working properly: Forms\Components\TextInput::make('price') ->label('Price'), Forms\Components\Toggle::make('checkbox') ->label('Checkbox') ->rules(['required_if:price,(X Amount)']), I've tried with custom rule but it's not working properly. How can I do this?
28 Replies
toeknee
toeknee2y ago
1) Set the field required if price is less than 100 2) Set the validation attribute Forms\Components\TextInput::make('price') ->reactive() ->label('Price'), Forms\Components\Toggle::make('checkbox') ->label('Checkbox') ->reactive() ->required(fn(Closure $get, $set) => (float) $get('price') < 100) ->validationAttribute('You must check if value less than 100'),
ZedoX
ZedoX2y ago
Ummm I wouldn't add the validation attribute there, - it's not needed - it would mess up the validation message (it is validation attribute not validation message)
toeknee
toeknee2y ago
Cool, add your own advice then 🙂
Kuldeep
KuldeepOP2y ago
Thank you @toeknee_iom It's not displaying validation message.
toeknee
toeknee2y ago
You could use a custom validation rule, but I was trying to keep it simple for you.
Kuldeep
KuldeepOP2y ago
Can we do it with custom validation? Right now I'm getting this only as a response. No validation error messages on the form Forms\Components\TextInput::make('price') ->label('Price'), Forms\Components\Toggle::make('checkbox') ->label('Checkbox') ->rules([ function (Closure $get, $state) { \Log::info("Price: " . $get('profile_data_combined_household_income')); \Log::info("Actual: " . (100)); if ($get('profile_data_combined_household_income') < (100)) { \Log::info("In "); return function (string $attribute, $value, Closure $fail) { $fail("You must check if value less than " . (100)); }; } }, ]), This works and gets the record on the Log file, but from submit process is continue going. Not get any error message or etc.
toeknee
toeknee2y ago
You will need to cast your get to an integer. Does Log::info 'In' get hit?
Kuldeep
KuldeepOP2y ago
Yes, I got it
toeknee
toeknee2y ago
It looks ok to me. Can't see why it wouldn't be responding
Dennis Koch
Dennis Koch2y ago
Maybe use rule() (not plural) and without the array. Not sure if we support closures for every array item. Also you could try to use Validator Facade in afterValidation hook on that page to do a custom validation
Kuldeep
KuldeepOP2y ago
It's not working. Should I try with a livewire validation process like this? $this->addError('email', 'The email field is invalid.');
Dennis Koch
Dennis Koch2y ago
What is not working?
Kuldeep
KuldeepOP2y ago
plural: rule() Validator Facade in afterValidation hook both not working.
Dennis Koch
Dennis Koch2y ago
Show some code you used. And please format it as stated in #✅┊rules
Kuldeep
KuldeepOP2y ago
Right now I've done like this:
Forms\Components\TextInput::make('price')
->label('Price'),
Forms\Components\Toggle::make('checkbox')
->label('Checkbox')
->rules([
function (Closure $get, $state) {
\Log::info("Price: " . $get('price'));
\Log::info("Actual: 100");

if ((float) $get('price') < 100) {
\Log::info("In");

return function (string $attribute, $value, Closure $fail) {
$fail("You must check if value less than 100");
};
}
},
])
->inline(false),
Forms\Components\TextInput::make('price')
->label('Price'),
Forms\Components\Toggle::make('checkbox')
->label('Checkbox')
->rules([
function (Closure $get, $state) {
\Log::info("Price: " . $get('price'));
\Log::info("Actual: 100");

if ((float) $get('price') < 100) {
\Log::info("In");

return function (string $attribute, $value, Closure $fail) {
$fail("You must check if value less than 100");
};
}
},
])
->inline(false),
Another Custom Rule:
Forms\Components\TextInput::make('price')
->label('Price'),
Forms\Components\Toggle::make('checkbox')
->label('Checkbox')
->rules([
function (callable $get){
\Log::info($get('price'));

return new NeedGuarantorRule( $get('price'), 100 );
},
])
->inline(false),


NeedGuarantorRule:

public function passes($attribute, $value)
{
\Log::info('total_price' . $this->total_price);
if ($this->total_price > $this->fill_price) {
return false;
}
}
Forms\Components\TextInput::make('price')
->label('Price'),
Forms\Components\Toggle::make('checkbox')
->label('Checkbox')
->rules([
function (callable $get){
\Log::info($get('price'));

return new NeedGuarantorRule( $get('price'), 100 );
},
])
->inline(false),


NeedGuarantorRule:

public function passes($attribute, $value)
{
\Log::info('total_price' . $this->total_price);
if ($this->total_price > $this->fill_price) {
return false;
}
}
Dennis Koch
Dennis Koch2y ago
So you didn't try?
function (Closure $get, $state) {
\Log::info("Price: " . $get('price'));
\Log::info("Actual: 100");

if ((float) $get('price') < 100) {
\Log::info("In");

return function (string $attribute, $value, Closure $fail) {
$fail("You must check if value less than 100");
};
}
}
function (Closure $get, $state) {
\Log::info("Price: " . $get('price'));
\Log::info("Actual: 100");

if ((float) $get('price') < 100) {
\Log::info("In");

return function (string $attribute, $value, Closure $fail) {
$fail("You must check if value less than 100");
};
}
}
Kuldeep
KuldeepOP2y ago
Yes, I tried it not working.
Dennis Koch
Dennis Koch2y ago
I guess you need a DataAware rule then Instead of $get.
LeandroFerreira
Filament
Editing records - Resources - Admin Panel - Filament
The elegant TALL stack admin panel for Laravel artisans.
Dennis Koch
Dennis Koch2y ago
That what I recommended, too. But only got "not working" as an answer
LeandroFerreira
@Kuldeep ?
Kuldeep
KuldeepOP2y ago
Let me try once
Dennis Koch
Dennis Koch2y ago
If it doesn't work, show your code
LeandroFerreira
You can use $this->data to get the values update error messages if you want:
use Illuminate\Validation\ValidationException;
throw ValidationException::withMessages(['data.field_name' => 'This value is incorrect']);
use Illuminate\Validation\ValidationException;
throw ValidationException::withMessages(['data.field_name' => 'This value is incorrect']);
Kuldeep
KuldeepOP2y ago
<?php

namespace App\Http\Livewire;

use Livewire\Component;

use Filament\Forms;

class TestForm extends Component implements Forms\Contracts\HasForms
{
use Forms\Concerns\InteractsWithForms;

public $price;
public $checkbox;

protected function getFormSchema(): array
{
return [
Forms\Components\TextInput::make('price')
->label('Price'),
Forms\Components\Toggle::make('checkbox')
->label('Checkbox')
->inline(false),
];
}

protected function afterValidate(): void
{
echo "123";
dd($this->data);
}

protected function prepareModelData($data): array
{
$preparedData = [
'price' => $data['price'],
'checkbox' => $data['checkbox'],
];

return $preparedData;
}

public function completeProfile()
{
echo "456";
$preparedData = $this->prepareModelData($this->form->getState());
dd($preparedData);
}

public function render()
{
$view = view('livewire.test-form');

$view->layout('filament::components.layouts.base', [
'title' => 'Test Form',
]);

return $view;
}
}
<?php

namespace App\Http\Livewire;

use Livewire\Component;

use Filament\Forms;

class TestForm extends Component implements Forms\Contracts\HasForms
{
use Forms\Concerns\InteractsWithForms;

public $price;
public $checkbox;

protected function getFormSchema(): array
{
return [
Forms\Components\TextInput::make('price')
->label('Price'),
Forms\Components\Toggle::make('checkbox')
->label('Checkbox')
->inline(false),
];
}

protected function afterValidate(): void
{
echo "123";
dd($this->data);
}

protected function prepareModelData($data): array
{
$preparedData = [
'price' => $data['price'],
'checkbox' => $data['checkbox'],
];

return $preparedData;
}

public function completeProfile()
{
echo "456";
$preparedData = $this->prepareModelData($this->form->getState());
dd($preparedData);
}

public function render()
{
$view = view('livewire.test-form');

$view->layout('filament::components.layouts.base', [
'title' => 'Test Form',
]);

return $view;
}
}
After submit form it's going directly to the the method: completeProfile()
LeandroFerreira
You can develop the validations in completeProfile method My suggestion is about resources
Dennis Koch
Dennis Koch2y ago
afterValidate is an admin-panel thing Just use a Validator in completeProfile then
Kuldeep
KuldeepOP2y ago
Ok, @Dennis Koch @Leandro Ferreira @toeknee_iom Thank you for your support
Want results from more Discord servers?
Add your server