TextInput with no database column?

I am trying to add a TextInput column to a table that allows users to type in numbers. I don't want anything to be changed in the database when they type something in, but I would like to be able to access the value when clicking an action button. Is there any good way to do this? I considered just trying to make a custom view column, but I wasn't sure how I would access the value from the action button in that case.
10 Replies
Patrick Boivin
Hi @tiber93, I'm doing something similar and I'm using a ViewColumn with a custom input tag. There may be a better way, I'm not sure... Are you trying to access this value from a table action in the same row?
Tiber
TiberOP2y ago
Yep
Patrick Boivin
What does your action do exactly? Is there a modal involved?
Tiber
TiberOP2y ago
Yeah, basically this at the moment: ->modalContent(fn (Trade $record) => $this->confirmationContent($record)) But I am trying to create this custom TextInput that would allow me to also pass in its value through to confirmationContent.
Patrick Boivin
Ok, cool. So this is a bit different from what I needed (no modal) but I'll share my solution in case it can give you a head start Just re-read the code and I didn't use a ViewColumn in the end, I switched to a custom table Action class Action class (simplified) :
class ProductSearchListAddAction extends Action
{
private bool $withQuantity = false;

public function withQuantity(bool $value): self
{
$this->withQuantity = $value;

return $this;
}

public function getWithQuantity(): bool
{
return $this->withQuantity;
}

public static function make(?string $name = null): static
{
return parent::make($name ?: 'add')
->label(__('Add'))
->color('secondary')
->view('Admin::filament.partials.product-search-modal-add-action');
}
}
class ProductSearchListAddAction extends Action
{
private bool $withQuantity = false;

public function withQuantity(bool $value): self
{
$this->withQuantity = $value;

return $this;
}

public function getWithQuantity(): bool
{
return $this->withQuantity;
}

public static function make(?string $name = null): static
{
return parent::make($name ?: 'add')
->label(__('Add'))
->color('secondary')
->view('Admin::filament.partials.product-search-modal-add-action');
}
}
And the view (simplified):
@php
$record = $action->getRecord();
$initial_quantity = $getWithQuantity() ? 1 : null;
@endphp

<div
x-data="{ quantity: {!! json_encode($initial_quantity) !!} }"
>
@if($getWithQuantity())
<x-admin::forms.input
type="number"
x-model="quantity"
/>
@endif

<x-tables::actions.action
:action="$action"
x-on:click="$wire.emitUp('addFromProductSearch', {
'context': {!! json_encode($getProductSearchContext()) !!},
'record_type': {!! json_encode($record::class) !!},
'record_id': {!! json_encode($record->id) !!},
'quantity': quantity,
})"
>
{{ $getLabel() }}
</x-tables::actions.action>
</div>
@php
$record = $action->getRecord();
$initial_quantity = $getWithQuantity() ? 1 : null;
@endphp

<div
x-data="{ quantity: {!! json_encode($initial_quantity) !!} }"
>
@if($getWithQuantity())
<x-admin::forms.input
type="number"
x-model="quantity"
/>
@endif

<x-tables::actions.action
:action="$action"
x-on:click="$wire.emitUp('addFromProductSearch', {
'context': {!! json_encode($getProductSearchContext()) !!},
'record_type': {!! json_encode($record::class) !!},
'record_id': {!! json_encode($record->id) !!},
'quantity': quantity,
})"
>
{{ $getLabel() }}
</x-tables::actions.action>
</div>
The state is stored on the action div, and the action emits up from the table to the page Livewire component.
Tiber
TiberOP2y ago
Hmm, alright. I'll have to see if I can get that to work, assuming no one else has any easier solution. 😄 Thanks
Patrick Boivin
Cool! I'll be watching for other suggestions 👀
Tiber
TiberOP2y ago
I think I found an easy solution: 1. I created a public array within the livewire component.
public $buyAmounts = [];
public $buyAmounts = [];
2. I created a custom view for my input field column, and did a wire:model to the array, using the main record ID as the key:
<div>
<input type="text" wire:model="buyAmounts.{{ $getRecord()->id }}" />
</div>
<div>
<input type="text" wire:model="buyAmounts.{{ $getRecord()->id }}" />
</div>
And that is basically it. Now whenever the user clicks the action button, I can just grab whatever they have typed for that row out of the array. Hopefully it doesn't all fall apart when I have a bunch of records, but it is working at the moment.
Patrick Boivin
Yeah, awesome!
francesco_m
francesco_m2y ago
x-data
Want results from more Discord servers?
Add your server