Adding a form to a Livewire component

I added custom livewire component https://filamentphp.com/docs/3.x/forms/adding-a-form-to-a-livewire-component gettitng error Livewire page component layout view not found: [components.layouts.app] Here is route inside web.php i Route::get('/admin/suppliers/{record}/line-items', ListSupplierLineItem::class);
27 Replies
Dennis Koch
Dennis Koch2mo ago
Laravel
Components | Laravel
A full-stack framework for Laravel that takes the pain out of building dynamic UIs.
Umar Farooq
Umar Farooq2mo ago
I want to use filament layout path?
Dennis Koch
Dennis Koch2mo ago
What do you mean by "Filament layout path"? You want to use Filaments layout? Why don't you create a Filament Page then?
Umar Farooq
Umar Farooq2mo ago
I created the filament page
<?php

namespace App\Filament\Pages\LineItem;

// import

class ListSupplierLineItem extends Component implements HasForms, HasTable
{
use InteractsWithTable;
use InteractsWithForms;

/**
* @param $record
* @return void
*/
public function mount($record): void
{
$this->record = LineItem::find($record);
}

/**
* @param array $parameters
* @return bool
*/
public static function canAccess(array $parameters = []): bool
{
return auth()->user()->can('view_supplier_items_' . $parameters['record']->id);
}

/**
* @param Tables\Table $table
* @return Tables\Table
*/
public function table(Tables\Table $table): Tables\Table
{
return $table
->query($this->getTableQuery())
->columns([
// ..
])
->actions([
Tables\Actions\EditAction::make()
->url(fn ($record) => SupplierResource::getUrl('edit-line-item', ['record' => $record]))
]);
}

/**
* @deprecated Override the `table()` method to configure the table.
*/
protected function getTableQuery(): Builder | Relation | null
{
return LineItem::query()->where('supplier_id', $this->record->id);
}

/**
* @return Application|Factory|View|\Illuminate\Foundation\Application
*/
public function render(): Application|Factory|View|\Illuminate\Foundation\Application
{
return view('table.line-items.list-records');
}
}
<?php

namespace App\Filament\Pages\LineItem;

// import

class ListSupplierLineItem extends Component implements HasForms, HasTable
{
use InteractsWithTable;
use InteractsWithForms;

/**
* @param $record
* @return void
*/
public function mount($record): void
{
$this->record = LineItem::find($record);
}

/**
* @param array $parameters
* @return bool
*/
public static function canAccess(array $parameters = []): bool
{
return auth()->user()->can('view_supplier_items_' . $parameters['record']->id);
}

/**
* @param Tables\Table $table
* @return Tables\Table
*/
public function table(Tables\Table $table): Tables\Table
{
return $table
->query($this->getTableQuery())
->columns([
// ..
])
->actions([
Tables\Actions\EditAction::make()
->url(fn ($record) => SupplierResource::getUrl('edit-line-item', ['record' => $record]))
]);
}

/**
* @deprecated Override the `table()` method to configure the table.
*/
protected function getTableQuery(): Builder | Relation | null
{
return LineItem::query()->where('supplier_id', $this->record->id);
}

/**
* @return Application|Factory|View|\Illuminate\Foundation\Application
*/
public function render(): Application|Factory|View|\Illuminate\Foundation\Application
{
return view('table.line-items.list-records');
}
}
but do not want to register with any resource as it has it's own permissions
Dennis Koch
Dennis Koch2mo ago
That's a Livewire component and not a full page. Why don't you just create a page via artisan make:filament-page?
Umar Farooq
Umar Farooq2mo ago
can I create a page without adding into any resources? I want to give different permission to the page as resource use canViewAny and my page has different permission
Dennis Koch
Dennis Koch2mo ago
Yes, you can.
Umar Farooq
Umar Farooq2mo ago
getting 404
class SupplierLineItems extends Page
{
protected static ?string $navigationIcon = 'heroicon-o-document-text';

protected static string $view = 'filament.pages.supplier-line-items';

protected static ?string $slug = '/admin/suppliers/{record}/line-items';

use InteractsWithTable;
use InteractsWithForms;
use InteractsWithRecord;

/**
* @param $record
* @return void
*/
public function mount($record): void
{
$this->record = LineItem::find($record);
}

/**
* @param array $parameters
* @return bool
*/
public static function canAccess(array $parameters = []): bool
{
return auth()->user()->can('view_supplier_items_');
}

/**
* @param Tables\Table $table
* @return Tables\Table
*/
public function table(Tables\Table $table): Tables\Table
{
return $table
->query($this->getTableQuery())
->columns([
// ..
])
->actions([
Tables\Actions\EditAction::make()
->url(fn ($record) => SupplierResource::getUrl('edit-line-item', ['record' => $record]))
]);
}

/**
* @deprecated Override the `table()` method to configure the table.
*/
protected function getTableQuery(): Builder | Relation | null
{
return LineItem::query()->where('supplier_id', $this->record->id);
}
}
class SupplierLineItems extends Page
{
protected static ?string $navigationIcon = 'heroicon-o-document-text';

protected static string $view = 'filament.pages.supplier-line-items';

protected static ?string $slug = '/admin/suppliers/{record}/line-items';

use InteractsWithTable;
use InteractsWithForms;
use InteractsWithRecord;

/**
* @param $record
* @return void
*/
public function mount($record): void
{
$this->record = LineItem::find($record);
}

/**
* @param array $parameters
* @return bool
*/
public static function canAccess(array $parameters = []): bool
{
return auth()->user()->can('view_supplier_items_');
}

/**
* @param Tables\Table $table
* @return Tables\Table
*/
public function table(Tables\Table $table): Tables\Table
{
return $table
->query($this->getTableQuery())
->columns([
// ..
])
->actions([
Tables\Actions\EditAction::make()
->url(fn ($record) => SupplierResource::getUrl('edit-line-item', ['record' => $record]))
]);
}

/**
* @deprecated Override the `table()` method to configure the table.
*/
protected function getTableQuery(): Builder | Relation | null
{
return LineItem::query()->where('supplier_id', $this->record->id);
}
}
Dennis Koch
Dennis Koch2mo ago
Does the page show in the sidebar?
Umar Farooq
Umar Farooq2mo ago
unfortunately no
Dennis Koch
Dennis Koch2mo ago
Just noticed, you cannot auto register it anyway. Cause you require a url param. You should link to it from the table. Also I think /admin is redundant, because your panel is probably admin which would result in /admin/admin/ url
Umar Farooq
Umar Farooq2mo ago
after removing /admin getting Missing required parameter for [Route: filament.admin.pages..suppliers.{record}.line-items] [URI: admin/suppliers/{record}/line-items] [Missing parameter: record].
->url(function () use ($id) {
return SupplierLineItems::getUrl(['record' => $id]);
})
->url(function () use ($id) {
return SupplierLineItems::getUrl(['record' => $id]);
})
even I passing the record
Dennis Koch
Dennis Koch2mo ago
Where does that $id come from? Did you check that it’s not empty?
Umar Farooq
Umar Farooq2mo ago
yes, it's not empty I did receive the $record on mount
/**
* @param $record
* @return void
*/
public function mount($record): void
{
$this->record = Supplier::find($record);
}
/**
* @param $record
* @return void
*/
public function mount($record): void
{
$this->record = Supplier::find($record);
}
slug creating the issue
protected static ?string $slug = '/suppliers/{record}/line-items';
protected static ?string $slug = '/suppliers/{record}/line-items';
Umar Farooq
Umar Farooq2mo ago
and I think it's a query base parameter. will not work with path parameter
Dennis Koch
Dennis Koch2mo ago
Where did you put that part of code and where is $id coming from? I wanted to know whether $id is set
Umar Farooq
Umar Farooq2mo ago
inside AdminPanelProvider
if (Schema::hasTable(Supplier::getTableName())) {
suppliers = Supplier::all()->pluck('name', 'id');
}

$suppliersNavItem = [];

foreach ($suppliers as $id => $supplier) {
$suppliersNavItem[] = NavigationItem::make($supplier)
->url(function () use ($id) {
return SupplierLineItems::getUrl(['record' => $id]);
})
->visible(function () use ($id) {
return auth()->user()->can("view_supplier_items_$id");
})
->isActiveWhen(function () use ($id) {
$route = Route::current();

return $route->uri() === "admin/suppliers/{record}/line-items" && $route->parameter('record') === "$id";
})
->icon('heroicon-o-building-storefront')
->group('Order Management')
->sort($id);
}
if (Schema::hasTable(Supplier::getTableName())) {
suppliers = Supplier::all()->pluck('name', 'id');
}

$suppliersNavItem = [];

foreach ($suppliers as $id => $supplier) {
$suppliersNavItem[] = NavigationItem::make($supplier)
->url(function () use ($id) {
return SupplierLineItems::getUrl(['record' => $id]);
})
->visible(function () use ($id) {
return auth()->user()->can("view_supplier_items_$id");
})
->isActiveWhen(function () use ($id) {
$route = Route::current();

return $route->uri() === "admin/suppliers/{record}/line-items" && $route->parameter('record') === "$id";
})
->icon('heroicon-o-building-storefront')
->group('Order Management')
->sort($id);
}
Dennis Koch
Dennis Koch2mo ago
What do you mean by "slug creating the issues" when you say that you received "record" on mount?
Umar Farooq
Umar Farooq2mo ago
the error [URI: admin/suppliers/{record}/line-items] [Missing parameter: record]. the record should be resolved as it's get on mount function
Dennis Koch
Dennis Koch2mo ago
Hm. The method call and slug look good to me.
Umar Farooq
Umar Farooq2mo ago
No description
Umar Farooq
Umar Farooq2mo ago
Where I can access the parameters pass to getUrl inside page? Should I open an issue on GitHub?
Dennis Koch
Dennis Koch2mo ago
I am still not sure this is a Filament issue
Umar Farooq
Umar Farooq2mo ago
I don't know it's filament issue or livewire Is there another way I can achieve the same functionality?