Custom View Form Validation

I have a route that triggers a view that looks like this:
@php
$livewire = new \App\Http\Livewire\ResetPassword();
@endphp
<div class="fi-simple-layout flex min-h-screen flex-col items-center">
<div class="fi-simple-main-ctn flex w-full flex-grow items-center justify-center">

<main
class="fi-simple-main my-16 w-full bg-white px-6 py-12 shadow-sm ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10 sm:rounded-xl sm:px-12 sm:max-w-lg">

<x-filament-panels::layout.base :livewire="$livewire">

<x-filament-panels::header.simple :heading="$heading ??= $livewire->getHeading()"
:subheading="$subheading ??= $livewire->getSubHeading()" />


{{-- Content --}}
<x-filament-panels::form action="{{ route('password.reset.process') }}" method="POST"
style="margin-top: 5%;">
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
<input type="hidden" name="token" value="{{ request()->token }}" />
<input type="hidden" name="email" value="{{ request()->query('email') }}" />



<x-filament-forms::field-wrapper.label prefix="Password" />
<x-filament::input.wrapper>
<x-filament::input type="password" name="password" placeholder="Enter Password" id="password" />
</x-filament::input.wrapper>

<x-filament-forms::field-wrapper.label prefix="Confirm Password" />
<x-filament::input.wrapper>
<x-filament::input type="password" name="password_confirmation" placeholder="Confirm Password"
id="password_confirmation" />
</x-filament::input.wrapper>


<x-filament::button type="submit" color="primary">
Reset Password
</x-filament::button>

</x-filament-panels::form>

</x-filament-panels::layout.base>
</main>
</div>
</div>
@php
$livewire = new \App\Http\Livewire\ResetPassword();
@endphp
<div class="fi-simple-layout flex min-h-screen flex-col items-center">
<div class="fi-simple-main-ctn flex w-full flex-grow items-center justify-center">

<main
class="fi-simple-main my-16 w-full bg-white px-6 py-12 shadow-sm ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10 sm:rounded-xl sm:px-12 sm:max-w-lg">

<x-filament-panels::layout.base :livewire="$livewire">

<x-filament-panels::header.simple :heading="$heading ??= $livewire->getHeading()"
:subheading="$subheading ??= $livewire->getSubHeading()" />


{{-- Content --}}
<x-filament-panels::form action="{{ route('password.reset.process') }}" method="POST"
style="margin-top: 5%;">
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
<input type="hidden" name="token" value="{{ request()->token }}" />
<input type="hidden" name="email" value="{{ request()->query('email') }}" />



<x-filament-forms::field-wrapper.label prefix="Password" />
<x-filament::input.wrapper>
<x-filament::input type="password" name="password" placeholder="Enter Password" id="password" />
</x-filament::input.wrapper>

<x-filament-forms::field-wrapper.label prefix="Confirm Password" />
<x-filament::input.wrapper>
<x-filament::input type="password" name="password_confirmation" placeholder="Confirm Password"
id="password_confirmation" />
</x-filament::input.wrapper>


<x-filament::button type="submit" color="primary">
Reset Password
</x-filament::button>

</x-filament-panels::form>

</x-filament-panels::layout.base>
</main>
</div>
</div>
Solution:
Thank you for your help @toeknee Appreciate it 🙂
Jump to solution
49 Replies
Jamie Cee
Jamie Cee2mo ago
It has a component that looks like this:
<?php

namespace App\Http\Livewire;

use Illuminate\View\View;
use Livewire\Component;

class ResetPassword extends Component
{
protected $title = 'Reset Password';
protected ?string $heading = null;

/**
* Page title
*
* @return string
*/
public function getTitle(): string
{
return $this->title;
}

/**
* Page heading
*
* @return string
*/
public function getHeading(): string
{
return 'Reset Password';
}

/**
* Page subheading
*
* @return boolean
*/
public function getSubHeading(): bool
{
return "";
}

/**
* Render two fa blade
*
* @return View
*/
public function render(): View
{
return view('livewire.password-reset');
}
}
<?php

namespace App\Http\Livewire;

use Illuminate\View\View;
use Livewire\Component;

class ResetPassword extends Component
{
protected $title = 'Reset Password';
protected ?string $heading = null;

/**
* Page title
*
* @return string
*/
public function getTitle(): string
{
return $this->title;
}

/**
* Page heading
*
* @return string
*/
public function getHeading(): string
{
return 'Reset Password';
}

/**
* Page subheading
*
* @return boolean
*/
public function getSubHeading(): bool
{
return "";
}

/**
* Render two fa blade
*
* @return View
*/
public function render(): View
{
return view('livewire.password-reset');
}
}
But when I submit my form to a controller, I want to display the validation errors, how can I do this?
toeknee
toeknee2mo ago
Why not just have the component implement forms? and not custom it?
Jamie Cee
Jamie Cee2mo ago
Not sure if that would work in my use case. So the reset password comes from an API call, the way we used to handle reset passwords is now jank, so we have gone the route of just having a custom blade view for it But instead of a dead styling, im trying to keep filament styling
toeknee
toeknee2mo ago
Why wouldn't it? On save, you can handle all the function calling your api?
Jamie Cee
Jamie Cee2mo ago
I may be getting confused then, could you guide me where to look for info at setting this up?
toeknee
toeknee2mo ago
<form wire:submit="reset">
{{ $this->form }}

<button type="submit">
Submit
</button>
</form>

<x-filament-actions::modals />
<form wire:submit="reset">
{{ $this->form }}

<button type="submit">
Submit
</button>
</form>

<x-filament-actions::modals />
public function form(Form $form): Form
{
return $form
->schema([
TextInput::make('password')
->password()
->revealable()
])
->statePath('data');
}


public function reset() {
$data = $this->form->getState();

// Call API and validate

}
public function form(Form $form): Form
{
return $form
->schema([
TextInput::make('password')
->password()
->revealable()
])
->statePath('data');
}


public function reset() {
$data = $this->form->getState();

// Call API and validate

}
Jamie Cee
Jamie Cee2mo ago
Invalid route action: [App\Http\Livewire\ResetPassword].
Invalid route action: [App\Http\Livewire\ResetPassword].
Route::get('password-reset/{token}', ResetPassword::class)->name('password.reset')->middleware('web');
Route::get('password-reset/{token}', ResetPassword::class)->name('password.reset')->middleware('web');
This is my route
toeknee
toeknee2mo ago
Why are you routing I thought you had the page rendering already?
Jamie Cee
Jamie Cee2mo ago
It was rendering with the route I had defined
toeknee
toeknee2mo ago
So why have you changed the route? you would likel yneed to clear your route cache for the new one to work if you created a new one
Jamie Cee
Jamie Cee2mo ago
The docs say to create it that way?
use App\Livewire\CreatePost;
use Illuminate\Support\Facades\Route;

Route::get('posts/create', CreatePost::class);
use App\Livewire\CreatePost;
use Illuminate\Support\Facades\Route;

Route::get('posts/create', CreatePost::class);
toeknee
toeknee2mo ago
So you absolutely can, but you already had the route? So you just needed to implment the extend
Jamie Cee
Jamie Cee2mo ago
So if I undo back to what I had, it pointed to my controller, that looked like this:
public function resetPassword(string $token)
{
return view('livewire.reset-password', ['token' => $token]);
}
public function resetPassword(string $token)
{
return view('livewire.reset-password', ['token' => $token]);
}
But that cant find the component? Unable to find component: [reset-password] Think this is the blade part im getting stuck with though: @livewire('reset-password', ['token' => request()->token, 'email' => request()->query('email')]) Tried that ^ still not working
toeknee
toeknee2mo ago
Ok I am so confused with what you are doing here. Just make a normal livewire component: https://livewire.laravel.com/docs/quickstart Then implement: https://filamentphp.com/docs/3.x/forms/adding-a-form-to-a-livewire-component And problem solved.
Laravel
Quickstart | Laravel
A full-stack framework for Laravel that takes the pain out of building dynamic UIs.
Jamie Cee
Jamie Cee2mo ago
Now the page just hangs, no idea why its trying to claim so much memory:
[2024-05-22 07:05:33] local.ERROR: Allowed memory size of 268435456 bytes exhausted (tried to allocate 528384 bytes) {"exception":"[object] (Symfony\\Component\\ErrorHandler\\Error\\FatalError(code: 0): Allowed memory size of 268435456 bytes exhausted (tried to allocate 528384 bytes) at /var/www/html/vendor/livewire/livewire/src/Component.php:105)
[stacktrace]
[2024-05-22 07:05:33] local.ERROR: Allowed memory size of 268435456 bytes exhausted (tried to allocate 528384 bytes) {"exception":"[object] (Symfony\\Component\\ErrorHandler\\Error\\FatalError(code: 0): Allowed memory size of 268435456 bytes exhausted (tried to allocate 528384 bytes) at /var/www/html/vendor/livewire/livewire/src/Component.php:105)
[stacktrace]
No description
Jamie Cee
Jamie Cee2mo ago
I re-done following this guide
Jamie Cee
Jamie Cee2mo ago
That issue has been fixed, but now I have no styling:
No description
Jamie Cee
Jamie Cee2mo ago
Followed, still no styling. Trying to run npm run dev just hangs
No description
Jamie Cee
Jamie Cee2mo ago
And attempted npm run build returns:
Error: [postcss] Cannot find module './vendor/filament/support/tailwind.config.preset'
Error: [postcss] Cannot find module './vendor/filament/support/tailwind.config.preset'
But I've ran the npm install etc that the documentation said to
toeknee
toeknee2mo ago
IF it was followed the assets shoud be loaded for filament forms really... so it can't find th efilament present... you must have it linked wrong
Jamie Cee
Jamie Cee2mo ago
Literally gone through step by step on every document linked
Jamie Cee
Jamie Cee2mo ago
It generated these js and css files etc, I've uploaded the app.blade.php file as instructed.
No description
toeknee
toeknee2mo ago
Ok... so in the blade are you rendering any css/js? I have a feeling you don't have any app styling if it's all been setup correctly
Jamie Cee
Jamie Cee2mo ago
I think its being a bitch around my docker containers So I have the components/layouts/app.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

<head>
<meta charset="utf-8">

<meta name="application-name" content="{{ config('app.name') }}">
<meta name="csrf-token" content="{{ csrf_token() }}">
<meta name="viewport" content="width=device-width, initial-scale=1">

<title>{{ config('app.name') }}</title>

<style>
[x-cloak] {
display: none !important;
}
</style>

@filamentStyles
@vite('resources/css/app.css')
</head>

<body class="antialiased">
{{ $slot }}

@filamentScripts
@vite('resources/js/app.js')
</body>

</html>
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

<head>
<meta charset="utf-8">

<meta name="application-name" content="{{ config('app.name') }}">
<meta name="csrf-token" content="{{ csrf_token() }}">
<meta name="viewport" content="width=device-width, initial-scale=1">

<title>{{ config('app.name') }}</title>

<style>
[x-cloak] {
display: none !important;
}
</style>

@filamentStyles
@vite('resources/css/app.css')
</head>

<body class="antialiased">
{{ $slot }}

@filamentScripts
@vite('resources/js/app.js')
</body>

</html>
By rendered blade view
@php
$show = $this->show;
@endphp

<div>
@if ($show)
<form wire:submit="resetProcess">
{{ $this->form }}

<button type="submit">
Submit
</button>
</form>

<x-filament-actions::modals />
@else
<h1>Password Reset</h1>
@endif
</div>
@php
$show = $this->show;
@endphp

<div>
@if ($show)
<form wire:submit="resetProcess">
{{ $this->form }}

<button type="submit">
Submit
</button>
</form>

<x-filament-actions::modals />
@else
<h1>Password Reset</h1>
@endif
</div>
toeknee
toeknee2mo ago
That looks good, and you are sure the filament systels are loading if you check the network tab
Jamie Cee
Jamie Cee2mo ago
No description
Jamie Cee
Jamie Cee2mo ago
Okay, so npm run build has randomly just worked after failing about 20 times.
Jamie Cee
Jamie Cee2mo ago
But now its blocked by csp, which I think is docker related
No description
Jamie Cee
Jamie Cee2mo ago
http://[::1]:5173/resources/css/app.css
http://[::1]:5173/resources/css/app.css
For some reason, isn't setting as localhost either If its doing all this locally, its gonna be a right ball ache for prod
toeknee
toeknee2mo ago
It is telling you... CSP. You need to ensure the app .env runs the same URL as the url you are accessing it from.
Jamie Cee
Jamie Cee2mo ago
http://127.0.0.1:5173/css/filament/forms/forms.css?v=3.2.71.0
http://127.0.0.1:5173/css/filament/forms/forms.css?v=3.2.71.0
Its running from localhost like the rest of my application? I've added that port to my docker-compose
ports:
- 5173:5173
ports:
- 5173:5173
This is more effort than it should be like
toeknee
toeknee2mo ago
What is your .env app url? If you were using Herd it'd be work 😉 But these are basic setup issues of your laravel dev instance
Jamie Cee
Jamie Cee2mo ago
set to http://localhost:8080 I removed asset_url and now it loads them without blocking, but the styling doesn't exist
Jamie Cee
Jamie Cee2mo ago
No description
toeknee
toeknee2mo ago
Did you resolve finding the tailwind preset?
Jamie Cee
Jamie Cee2mo ago
That had to change into this:
import preset from '../../../../vendor/filament/filament/tailwind.config.preset'
import preset from '../../../../vendor/filament/filament/tailwind.config.preset'
If thats to pick up livewire.js then yeah, its in the list if I try to go to localhost:5173, i get connection reset so it doesnt load Like the styling does look like somethings being picked up, but not in the format other filament forms are Unless its the theme css thats missing?...
{
"resources/css/app.css": {
"file": "assets/app-6480a7f1.css",
"isEntry": true,
"src": "resources/css/app.css"
},
"resources/css/filament/admin/theme.css": {
"file": "assets/theme-504cbb9e.css",
"isEntry": true,
"src": "resources/css/filament/admin/theme.css"
},
"resources/js/app.js": {
"file": "assets/app-a5991337.js",
"isEntry": true,
"src": "resources/js/app.js"
}
}
{
"resources/css/app.css": {
"file": "assets/app-6480a7f1.css",
"isEntry": true,
"src": "resources/css/app.css"
},
"resources/css/filament/admin/theme.css": {
"file": "assets/theme-504cbb9e.css",
"isEntry": true,
"src": "resources/css/filament/admin/theme.css"
},
"resources/js/app.js": {
"file": "assets/app-a5991337.js",
"isEntry": true,
"src": "resources/js/app.js"
}
}
I can see it in my manifest, but not in my network tab
toeknee
toeknee2mo ago
Why not just use Herd for your app? so much easier! run: npm run build, if it's still not picking it up provide your tailwind config as it'll be missing the inclusion of the filament design
Jamie Cee
Jamie Cee2mo ago
Just not the way work has things setup, Ill mention it to look into
Jamie Cee
Jamie Cee2mo ago
The theme does exist in here, but doesn't appear in the network tab still
No description
Jamie Cee
Jamie Cee2mo ago
No description
Jamie Cee
Jamie Cee2mo ago
Adding this to my app.blade.php layout file
@vite('resources/css/filament/admin/theme.css')
@vite('resources/css/filament/admin/theme.css')
Has made the styling sort of better. now I need it in this sort of view
Jamie Cee
Jamie Cee2mo ago
This is what I have
No description
Jamie Cee
Jamie Cee2mo ago
But I want it in this kinda layout:
No description
toeknee
toeknee2mo ago
So copy the filament sign page html for that?
Jamie Cee
Jamie Cee2mo ago
Finally working Instead of extending component, I've gone down extending SimplePage instead all works Done and buried
Solution
Jamie Cee
Jamie Cee2mo ago
Thank you for your help @toeknee Appreciate it 🙂
toeknee
toeknee2mo ago
Perfect