bwurtz999
bwurtz999
FFilament
Created by bwurtz999 on 10/17/2024 in #❓┊help
Reuse Component Function
Hello - is there a way to reuse a function on a form component? For example, I have a Select element and I only want it to be required if it is visible
Select::make('name')
->required(function ($get) {
$id = $get('category_id');
$category = Category::find($id);
return !$category->page_one;
})
->visible(function ($get) {
$id = $get('category_id');
$category = Category::find($id);
return !$category->page_one;
})
Select::make('name')
->required(function ($get) {
$id = $get('category_id');
$category = Category::find($id);
return !$category->page_one;
})
->visible(function ($get) {
$id = $get('category_id');
$category = Category::find($id);
return !$category->page_one;
})
I have to write two separate checks - one for visible and one for required. But they are the same thing. It feels inefficient. Is there a better way to do this? Thank you
1 replies
FFilament
Created by bwurtz999 on 10/15/2024 in #❓┊help
Refresh Form Data in Modal
Hello - I have a form in a modal. I fill the form data initially using ->fillForm(). I have an action within in the form where the user can create a new model. Is there a way to call ->fillForm() again after the user submits the action form? I want to fill the form with fresh data.
4 replies
FFilament
Created by bwurtz999 on 9/27/2024 in #❓┊help
Table Export Action Format Columns
No description
6 replies
FFilament
Created by bwurtz999 on 9/17/2024 in #❓┊help
Set Repeater Data from Action Form
Hello - I am trying to generate a repeater from a form action.
Actions::make([
Action::make('extras')
->label('')
->color('primary')
->icon('heroicon-o-plus')
->form(function ($state, $form) {
$selectedItem = TeamProfileSelectedItem::find($state['id']);
return $form
->schema([
Repeater::make('extras')
->relationship('extras')
->model($selectedItem)
->columns(2)
->schema([
TextInput::make('qty'),
TextInput::make('name')
])
])
->model($selectedItem);
})
->action(function ($data) {
dd($data);
}),
]),
Actions::make([
Action::make('extras')
->label('')
->color('primary')
->icon('heroicon-o-plus')
->form(function ($state, $form) {
$selectedItem = TeamProfileSelectedItem::find($state['id']);
return $form
->schema([
Repeater::make('extras')
->relationship('extras')
->model($selectedItem)
->columns(2)
->schema([
TextInput::make('qty'),
TextInput::make('name')
])
])
->model($selectedItem);
})
->action(function ($data) {
dd($data);
}),
]),
The form opens but without the existing data. How do I specify the model for a Repeater when it is not a part of a traditional form? Thank you
11 replies
FFilament
Created by bwurtz999 on 9/14/2024 in #❓┊help
How to make custom forms more efficient
Hello - I have multiple forms on a Filament page. The forms all work, but the performance is very slow. Each update call takes between 2-3 seconds in my local environment. I'm worried that in production each request will take 5-10 seconds. Between all the forms on the page, there are roughly 500 form components. I tried breaking the forms up into even more forms (with each form containing less data), but the performance stayed the same. Does anyone have any advice for how to improve this performance? Each field is reactive and updates the relevant record when modified using afterStateUpdated. I would like to avoid using a traditional Update button like with standard EditRecord pages. There are a lot of data fields and if the user forgot to hit Update it would take them a long time to recreate their work. Thank you!
12 replies
FFilament
Created by bwurtz999 on 9/5/2024 in #❓┊help
Customizing Section Classes
No description
12 replies
FFilament
Created by bwurtz999 on 7/10/2024 in #❓┊help
Testing a HintAction in a Relation Manager
Hello - I am running into an issue trying to write a test for a HintAction inside a relation manager.
// this is in the form element of the relation manager
use Filament\Forms\Components\Actions\Action as ActionsAction;

Select::make('category_id')
->label('Menu Category')
->required()
->searchable()
->reactive()
->hintAction(
ActionsAction::make('createCategory')
->label('Create New Category')
->form([
TextInput::make('name')
->required()
->columnSpanFull(),
Select::make('payment_code_type_id')
->label('Payment Code Type')
->required()
->options(PaymentCodeType::pluck('name', 'id')),

])

// this is the test
livewire(ItemsRelationManager::class, [
'ownerRecord' => $event,
'pageClass' => EditEvent::class,
])
->callTableAction(EditAction::class, $item)
->callFormComponentAction('category_id', 'createCategory', data: [
'name' => $name,
'payment_code_type_id' => $paymentCodeType->id,
])
->assertHasNoFormComponentActionErrors();
// this is in the form element of the relation manager
use Filament\Forms\Components\Actions\Action as ActionsAction;

Select::make('category_id')
->label('Menu Category')
->required()
->searchable()
->reactive()
->hintAction(
ActionsAction::make('createCategory')
->label('Create New Category')
->form([
TextInput::make('name')
->required()
->columnSpanFull(),
Select::make('payment_code_type_id')
->label('Payment Code Type')
->required()
->options(PaymentCodeType::pluck('name', 'id')),

])

// this is the test
livewire(ItemsRelationManager::class, [
'ownerRecord' => $event,
'pageClass' => EditEvent::class,
])
->callTableAction(EditAction::class, $item)
->callFormComponentAction('category_id', 'createCategory', data: [
'name' => $name,
'payment_code_type_id' => $paymentCodeType->id,
])
->assertHasNoFormComponentActionErrors();
I get the following error message when I try to run the test: Argument #1 ($form) must be of type Filament\Forms\Form, Filament\Infolists\Infolist given, called in /Users/robertwurtz/Sites/site/vendor/filament/infolists/src/Concerns/InteractsWithInfolists.php on line 56 I'm confused because nothing in here uses an Infolist - it's all Forms. I tried following the relevant documentation (https://filamentphp.com/docs/3.x/forms/testing#actions) so I'm not sure where to go from here. Thanks in advance!
4 replies
FFilament
Created by bwurtz999 on 6/28/2024 in #❓┊help
Issue With Searchable Select
Hey All - I have a dynamically created schema as shown below:
->schema(function ($record) {
$class = new EditEvent;
$orderSchema = [];
foreach ($record->orders as $order) {
$orderSchema[] = $class->getEditForm($order)[0];
}

return $orderSchema;
})
->schema(function ($record) {
$class = new EditEvent;
$orderSchema = [];
foreach ($record->orders as $order) {
$orderSchema[] = $class->getEditForm($order)[0];
}

return $orderSchema;
})
Each event can have multiple orders, and each order has many selections. So instead of using a relation manager to make selections, I am dynamically generate this schema using the ->getEditForm() function and displaying it directly on the EditEvent form. I'm running into an issue with using searchable(). When I use searchable, all of the menu options are shown based on the first order. But when searchable() is not used, the menu options are displayed correctly based on the order that is passed to the function.
// this works correctly displaying the meals based on the order
Select::make('meal')
->label('Menu Option')
// ->searchable()
->options(function() use ($order) {
Log::debug($order->id);
$meals = Meal::where([
['kitchen_id', $order->provider_id],
['approved', true],
])->get();
$returnArray = [];
foreach($meals as $meal) {
$returnArray[$meal->id] = $meal->name . ' - $' . number_format($meal->price, 2, '.', ',');
}
return $returnArray;
})

// this does not work correctly
// it always uses the first order to pull the meals
Select::make('meal')
->label('Menu Option')
->searchable()
->options(function() use ($order) {
Log::debug($order->id);
$meals = Meal::where([
['kitchen_id', $order->provider_id],
['approved', true],
])->get();
$returnArray = [];
foreach($meals as $meal) {
$returnArray[$meal->id] = $meal->name . ' - $' . number_format($meal->price, 2, '.', ',');
}
return $returnArray;
})
// this works correctly displaying the meals based on the order
Select::make('meal')
->label('Menu Option')
// ->searchable()
->options(function() use ($order) {
Log::debug($order->id);
$meals = Meal::where([
['kitchen_id', $order->provider_id],
['approved', true],
])->get();
$returnArray = [];
foreach($meals as $meal) {
$returnArray[$meal->id] = $meal->name . ' - $' . number_format($meal->price, 2, '.', ',');
}
return $returnArray;
})

// this does not work correctly
// it always uses the first order to pull the meals
Select::make('meal')
->label('Menu Option')
->searchable()
->options(function() use ($order) {
Log::debug($order->id);
$meals = Meal::where([
['kitchen_id', $order->provider_id],
['approved', true],
])->get();
$returnArray = [];
foreach($meals as $meal) {
$returnArray[$meal->id] = $meal->name . ' - $' . number_format($meal->price, 2, '.', ',');
}
return $returnArray;
})
Does anyone have any ideas about what might be going on here? Thank you!
2 replies
FFilament
Created by bwurtz999 on 6/25/2024 in #❓┊help
Updating a Relation Manager Form Without Closing
Hey all - I am upgrading my Livewire version to 3.5 from 3.3 and I've run into a problem. I need to update a relation manager form without closing it and reopening it. In the old version, I use the following:
// form schema for edit order in relation manager
// other form info
Actions::make([
Action::make('submitThisMeal')
->label('Submit')
->action(function () {
// handle submission and create selection
})
->after(function ($livewire) {
$livewire->dispatch('refreshModal');
})

// OrdersRelationManager
#[On('refreshModal')]
public function refresh(): void
{
// unset the form
unset($this->cachedForms['mountedTableActionForm']);
// reload the form
$this->cacheForm('mountedTableActionForm', null);

// application logic to find new selection...
// set form with new data
$this->mountedTableActionsData[0]['existingSelectionInfo'][$selection->meal->menuCategory->name][$selectionIndex]['mealId'] = $selection->meal_id;
}
}
// form schema for edit order in relation manager
// other form info
Actions::make([
Action::make('submitThisMeal')
->label('Submit')
->action(function () {
// handle submission and create selection
})
->after(function ($livewire) {
$livewire->dispatch('refreshModal');
})

// OrdersRelationManager
#[On('refreshModal')]
public function refresh(): void
{
// unset the form
unset($this->cachedForms['mountedTableActionForm']);
// reload the form
$this->cacheForm('mountedTableActionForm', null);

// application logic to find new selection...
// set form with new data
$this->mountedTableActionsData[0]['existingSelectionInfo'][$selection->meal->menuCategory->name][$selectionIndex]['mealId'] = $selection->meal_id;
}
}
Basically, this is all happening on the EditEvent page. Each event can have many Orders. Each Order has many Selections. I want users to be able to make selections and view the menu they have picked in real time in the modal that appears (updating after each selection). The selections appear at the top of the form and the section to make a new selection is at the bottom. This works in 3.3 but not above. Does anyone know why? In general, can anyone suggest a better way to present what I am talking about? I don't like my current solution but it works. Thanks in advance
2 replies
FFilament
Created by bwurtz999 on 4/22/2024 in #❓┊help
Unable to check existence for: item_photos
Hello - I am having an issue with file uploads in forms. I get the error above thrown from League\Flysystem\UnableToCheckDirectoryExistence. This started recently. I have tried updating all dependencies but no luck. What's even more strange is that I only get this locally - not in staging or production. I use an S3 bucket for local testing and I have checked that the bucket is publicly accessible. For context, this is a standard Filament resource using the form from the ItemResource class.
FileUpload::make('image')
->columnSpanFull()
->disk('s3')
->visibility('public')
->directory('item_photos')
FileUpload::make('image')
->columnSpanFull()
->disk('s3')
->visibility('public')
->directory('item_photos')
3 replies
FFilament
Created by bwurtz999 on 4/1/2024 in #❓┊help
Renderhook Cannot Received Dispatched Event
Hello, I am using a renderhook to include some custom JS on a specific page using:
FilamentView::registerRenderHook(
PanelsRenderHook::BODY_START,
fn (): string => Blade::render('@livewire(\'star-j-s\')'),
scopes: [
ListOrders::class,
]
);
FilamentView::registerRenderHook(
PanelsRenderHook::BODY_START,
fn (): string => Blade::render('@livewire(\'star-j-s\')'),
scopes: [
ListOrders::class,
]
);
The JS renders on the page correctly. I have confirmed that it renders properly using:
<div>
</div>

<script>
console.log('rendered');
</script>
<div>
</div>

<script>
console.log('rendered');
</script>
I cannot handle any dispatched events. I have tried:
document.addEventListener('livewire:init', () => {
Livewire.on('paymentSuccessful', event => {
})
// and ...
$wire.on('paymentSuccessful') // this throws an error saying $wire is undefined
// and...
window.addEventListener('paymentSuccessful', event => {

})
document.addEventListener('livewire:init', () => {
Livewire.on('paymentSuccessful', event => {
})
// and ...
$wire.on('paymentSuccessful') // this throws an error saying $wire is undefined
// and...
window.addEventListener('paymentSuccessful', event => {

})
Do I need to modify the StarJS Livewire component? What am I doing wrong? Thanks!
8 replies
FFilament
Created by bwurtz999 on 1/24/2024 in #❓┊help
ExportAction 502 Bad Gateway in Staging/Production
I upgraded to Filament 3.2 to use the new ExportAction. Awesome feature and works locally without issue. When I push to staging/production I get a 502 Bad Gateway error. I know it's not a lot to go on, but I'm not sure what's going on. I use S3 for my file system. The file is created and I can download it if I manually go into S3. Using Vapor if that matters. Thanks!
9 replies
FFilament
Created by bwurtz999 on 1/8/2024 in #❓┊help
Refresh Form With Dynamic Element Names
I have a form that I call from a relation manager. The form has two pieces - the first piece shows the current items in the order and allows customers to modify those selections. The second piece allows customers to make a new selection. When the customer submits the new item, I want the form to refresh and show the updated selections. I can trigger the refresh using:
// action
->after(function ($livewire) {
$livewire->dispatch('refreshModal');
}),

// relation manager
#[On('refreshModal')]
public function refresh(): void
{
// unset the form
unset($this->cachedForms['mountedTableActionForm']);
// reload the form
$this->cacheForm('mountedTableActionForm', null);
}
// action
->after(function ($livewire) {
$livewire->dispatch('refreshModal');
}),

// relation manager
#[On('refreshModal')]
public function refresh(): void
{
// unset the form
unset($this->cachedForms['mountedTableActionForm']);
// reload the form
$this->cacheForm('mountedTableActionForm', null);
}
This process works for modifying a selection. However, when I try to use it for adding a new selection I get the error Livewire Entangle Error: Livewire property cannot be found. So there is a form section for the newly selected item but none of the values are filled in correctly. I define the form component using
Select::make('existingSelectionInfo.' . $existingSelection->id . '.mealId')
Select::make('existingSelectionInfo.' . $existingSelection->id . '.mealId')
So it is named dynamically. This might be more of a Livewire question than an issue with Filament. But basically my question is - how can I manipulate a value (wire:model) that is not present when the form is initially loaded. Thank you!
3 replies
FFilament
Created by bwurtz999 on 1/5/2024 in #❓┊help
DateTimePicker Calendar Display Error
No description
8 replies
FFilament
Created by bwurtz999 on 11/22/2023 in #❓┊help
Fast Pagination
@Dan Harrin I implemented the trick for fast pagination you outlined (https://filamentphp.com/community/danharrin-fast-table-pagination) but there is one issue. When selecting All records, it returns an error for trying to multiply string * int. I changed the function to:
protected function paginateTableQuery(Builder $query): Paginator
{
return $query->fastPaginate(($this->getTableRecordsPerPage() == 'all') ? 9999 : $this->getTableRecordsPerPage());
}
protected function paginateTableQuery(Builder $query): Paginator
{
return $query->fastPaginate(($this->getTableRecordsPerPage() == 'all') ? 9999 : $this->getTableRecordsPerPage());
}
and that avoids the error. I'm not sure if there is a better way around this. I didn't see a way to comment on the community post so I'm doing it here. Just wanted you to know. Filament is amazing - thank you!
7 replies
FFilament
Created by bwurtz999 on 11/20/2023 in #❓┊help
How to speed up the search function on a table with relationships
I have a table with ~300 records and searching the table in production takes close to 10 seconds. Two of the searchable() columns are relationships. I have a different resource with a similar number of rows (but no relationships) and searching takes less than 1 second. The docs say that relationships are already eager loaded by default. Could I have accidentally disabled eager loading somehow? Is there anything I can do to speed up the search process with relationships?
37 replies
FFilament
Created by bwurtz999 on 11/7/2023 in #❓┊help
Custom Infolist Entry CSS
Has anyone else had an issue getting custom CSS classes to render properly? I have the following code:
<x-dynamic-component :component="$getEntryWrapperView()" :entry="$entry" :prefix="null">
<div class="w-full border-b-1 border-black grid grid-cols-6">

<div class="col-span-2">
{{ $getName() }}
</div>

<div class="col-span-4 text-right">
{{ $getState() }}
</div>

</div>
</x-dynamic-component>

@vite('resources/css/app.css')
<x-dynamic-component :component="$getEntryWrapperView()" :entry="$entry" :prefix="null">
<div class="w-full border-b-1 border-black grid grid-cols-6">

<div class="col-span-2">
{{ $getName() }}
</div>

<div class="col-span-4 text-right">
{{ $getState() }}
</div>

</div>
</x-dynamic-component>

@vite('resources/css/app.css')
The custom CSS (grid, grid-cols, etc.) only render properly if I include @vite in the component. But the issue is that I've tried this before and I know it only works locally. It won't work in production. I feel like I'm missing something simple. Any ideas?
24 replies
FFilament
Created by bwurtz999 on 11/1/2023 in #❓┊help
Listen for Event on Custom Page
I'm trying to listen for a dispatched event on a custom page and I must be doing something wrong. Can anyone help me out?
// Livewire
public function addToRepeater()
{
Log::debug('card-added'); // this point is reached
$this->dispatch('card-added');
}

// View
<x-filament::page x-on:card-added.window="handleCardAdded()">
// ... page code
</x-filament::page>
<script>
document.addEventListener('livewire:initialized', () => {
console.log('here');
@this.on('card-added', (event) => {
console.log('added');
});
});
function handleCardAdded()
{
console.log('handleCardAdded');
}
</script>
// Livewire
public function addToRepeater()
{
Log::debug('card-added'); // this point is reached
$this->dispatch('card-added');
}

// View
<x-filament::page x-on:card-added.window="handleCardAdded()">
// ... page code
</x-filament::page>
<script>
document.addEventListener('livewire:initialized', () => {
console.log('here');
@this.on('card-added', (event) => {
console.log('added');
});
});
function handleCardAdded()
{
console.log('handleCardAdded');
}
</script>
I've tried listening in both Alpine and in JS. Neither one is working. I must be missing something.
3 replies
FFilament
Created by bwurtz999 on 11/1/2023 in #❓┊help
Set Key-Value Data from Custom Page
Hello - I have a custom page that implements a form. The page allows users to scan barcodes. I want those scanned barcodes to appear as the values in the cards field.
return $form
->schema([
TextInput::make('amount')
->prefix('$')
->numeric()
->required()
->default(10)
->minValue(1)
->maxValue(100),
KeyValue::make('cards')
->required()
->keyLabel('Card Number')
->valueLabel('Barcode')
->reactive()
])
->statePath('data');

public function addCard($barcode)
{
$barcode = preg_replace('/[^0-9]/', '', $barcode);

foreach ($this->data['cards'] as $card) {
if ($card == $barcode) {
return Notification::make()
->danger()
->title('Card Already Scanned')
->send();
}
}

$this->data['cards'][$this->cardNum] = $barcode;
$this->cardNum++;
}
return $form
->schema([
TextInput::make('amount')
->prefix('$')
->numeric()
->required()
->default(10)
->minValue(1)
->maxValue(100),
KeyValue::make('cards')
->required()
->keyLabel('Card Number')
->valueLabel('Barcode')
->reactive()
])
->statePath('data');

public function addCard($barcode)
{
$barcode = preg_replace('/[^0-9]/', '', $barcode);

foreach ($this->data['cards'] as $card) {
if ($card == $barcode) {
return Notification::make()
->danger()
->title('Card Already Scanned')
->send();
}
}

$this->data['cards'][$this->cardNum] = $barcode;
$this->cardNum++;
}
My page is correctly emitting the scan event to addCard, but I can't figure out how to dynamically set the cards array and get it to update on the page.
2 replies
FFilament
Created by bwurtz999 on 10/18/2023 in #❓┊help
Extending the Base Filament Layout
Hey All - I have a custom page and I am trying to add to the standard base layout for Filament (I need to add to the page <head>). I created a new component docs-layout and then went to the Filament vendor folder and copied the base layout into the new docs-layout file. Without making any changes, when I load the page I get an error. It says Undefined variable $livewire ... in docs-layout. When I don't copy and paste and simply use
<filament-panels::components.layout.base>

</filament-panels::components.layout.base>
<filament-panels::components.layout.base>

</filament-panels::components.layout.base>
it works fine - but I can't make the changes that I need to. What am I missing here? Thanks!
2 replies