charlie
charlie
FFilament
Created by charlie on 1/19/2025 in #❓┊help
How to use Alpine in Filament?
If I have this very basic example: MyPage.php
namespace App\Filament\Pages;

class MyPage extends Page implements HasForms
{
use InteractsWithForms;

public string $my_text_input = 'Hello, World!';
public string $another_text_input = 'How are you?';

public function form(Form $form): Form
{
return $form
->schema([
TextInput::make('my_text_input'),
TextInput::make('another_text_input'),
]);
}
}
namespace App\Filament\Pages;

class MyPage extends Page implements HasForms
{
use InteractsWithForms;

public string $my_text_input = 'Hello, World!';
public string $another_text_input = 'How are you?';

public function form(Form $form): Form
{
return $form
->schema([
TextInput::make('my_text_input'),
TextInput::make('another_text_input'),
]);
}
}
my-page.blade.php
<x-filament-panels::page>

<script>
document.addEventListener('alpine:init', () => {
console.log('Alpine initialized'); // It works

Alpine.data('my_text_input', ({ state }) => ({
state,

init() {
console.log(this.state) // Doesn't work
},
onclick() {
console.log(this.state) // Doesn't work
},
change() {
console.log(this.state) // Doesn't work
},

})
</script>

{{ $this->form }}

</x-filament-panels::page>
<x-filament-panels::page>

<script>
document.addEventListener('alpine:init', () => {
console.log('Alpine initialized'); // It works

Alpine.data('my_text_input', ({ state }) => ({
state,

init() {
console.log(this.state) // Doesn't work
},
onclick() {
console.log(this.state) // Doesn't work
},
change() {
console.log(this.state) // Doesn't work
},

})
</script>

{{ $this->form }}

</x-filament-panels::page>
I can't understand how I can access the field state from alpine... What if I want to change the state of another_text_input each time my_text_input state changes, for example?
26 replies
FFilament
Created by charlie on 1/17/2025 in #❓┊help
From Livewire to Apine
Hi there! This field doesn't need any request to work. What would be the appropriate way/syntax to translate live() / afterStateUpdated() methods to Alpine.js?
ColorPicker::make('background')
->label('Background Color')
->colors($this->getBackgroundColors())
->live()
->extraAttributes(['id' => 'background'])
->afterStateUpdated(function ($livewire) {
$colors = json_encode($this->getBackgroundColors());
$livewire->js(
<<<JS
const colors = JSON.parse('$colors');
const color = document.querySelector('#background input[type="radio"]:checked').value;
const shades = colors[color];
previewTheme('gray', shades);
window.background = shades;
updateTheme();
JS
);
}),
ColorPicker::make('background')
->label('Background Color')
->colors($this->getBackgroundColors())
->live()
->extraAttributes(['id' => 'background'])
->afterStateUpdated(function ($livewire) {
$colors = json_encode($this->getBackgroundColors());
$livewire->js(
<<<JS
const colors = JSON.parse('$colors');
const color = document.querySelector('#background input[type="radio"]:checked').value;
const shades = colors[color];
previewTheme('gray', shades);
window.background = shades;
updateTheme();
JS
);
}),
Preferably extracting the js code elsewhere. Should I extend the field class or can I go with extraAttributes? Thanks!
1 replies
FFilament
Created by charlie on 11/14/2024 in #❓┊help
$getRecord() in a form changes when I click on an action button or a relation manager tab
Hi, I'm trying to create a custom field as explained here: https://filamentphp.com/docs/3.x/forms/fields/custom#custom-field-classes From the generated view, if I dump record like that:
<x-dynamic-component
:component="$getFieldWrapperView()"
:field="$field"
>
<div x-data="{ state: $wire.$entangle('{{ $getStatePath() }}') }">
<!-- Interact with the `state` property in Alpine.js -->

@dump($getRecord())

</div>
</x-dynamic-component>
<x-dynamic-component
:component="$getFieldWrapperView()"
:field="$field"
>
<div x-data="{ state: $wire.$entangle('{{ $getStatePath() }}') }">
<!-- Interact with the `state` property in Alpine.js -->

@dump($getRecord())

</div>
</x-dynamic-component>
It works fine, until I click on a button launching a modal or a Tab switching to a different RelationManager below the form. The record seems to be emptied, and the code in custom field can't access to the record anymore unless I refresh the page... Is it normal? And what could I do?
5 replies
FFilament
Created by charlie on 10/24/2024 in #❓┊help
Can't use $get inside recordSelectOptionsQuery: any workaround?
Hi, I didn't find the answer on this discord, nor in the docs. What I'm trying to do: Modify the query of the attach action select based on another field The code:
Tables\Actions\AttachAction::make()
->form(function (AttachAction $action): array {
return [

// The field I want to get...
Forms\Components\Toggle::make('mine_only')
->live()
->dehydrated(false),

$action->getRecordSelect(),
];
})
->recordSelectOptionsQuery(
function (Builder $query, $livewire, $get) {

dd($livewire); // Works but I don't know if I can "get" from this

dd($get('mine_only')); // Doesn't work: (An attempt was made to evaluate a closure for [Filament\Tables\Actions\AttachAction], but [$get] was unresolvable.)

// This should be returned if Toggle is on
return $query->whereHas('users',
fn(Builder $query) => $query->where('users.id', auth()->user()->id)
);

// Else if Toggle is off return the base query
return $query;
}
)
Tables\Actions\AttachAction::make()
->form(function (AttachAction $action): array {
return [

// The field I want to get...
Forms\Components\Toggle::make('mine_only')
->live()
->dehydrated(false),

$action->getRecordSelect(),
];
})
->recordSelectOptionsQuery(
function (Builder $query, $livewire, $get) {

dd($livewire); // Works but I don't know if I can "get" from this

dd($get('mine_only')); // Doesn't work: (An attempt was made to evaluate a closure for [Filament\Tables\Actions\AttachAction], but [$get] was unresolvable.)

// This should be returned if Toggle is on
return $query->whereHas('users',
fn(Builder $query) => $query->where('users.id', auth()->user()->id)
);

// Else if Toggle is off return the base query
return $query;
}
)
Thanks for the help!
4 replies