To achieve this dynamic behavior in a Filament resource—where users can right-click a Textarea, see a context menu of database table fields, and insert selected fields as tags—follow these steps:
1. Fetch the Database Table Fields
You can programmatically get the table column names associated with your resource's model like this:
$fields = \Schema::getColumnListing((new YourModel())->getTable());
2. Pass Fields to the Resource
In your Filament Resource form, pass these field names to your view or Blade component used for the textarea.
3. Use a Custom Blade Component for the Textarea
Here's an example of how you might integrate this into a custom Blade form component suitable for Filament:
<!-- resources/views/components/filament/custom-tag-textarea.blade.php -->
<textarea
{{ $attributes }}
id="customFieldTextarea"
style="width: 100%; min-height: 120px;"
></textarea>
<ul id="fieldContextMenu"
style="display:none; position:absolute; z-index:999; background:white; border:1px solid #ccc; padding:10px; list-style:none;">
@foreach($fields as $field)
<li style="padding:5px; cursor:pointer;" onclick="insertTag('{{ $field }}')">
{{ $field }}
</li>
@endforeach
</ul>
<script>
const textarea = document.getElementById('customFieldTextarea');
const menu = document.getElementById('fieldContextMenu');
textarea.addEventListener('contextmenu', (e) => {
e.preventDefault();
menu.style.left = e.pageX + 'px';
menu.style.top = e.pageY + 'px';
menu.style.display = 'block';
});
document.addEventListener('click', () => { menu.style.display = 'none'; });
window.insertTag = function(tag) {
const start = textarea.selectionStart;
const end = textarea.selectionEnd;
const text = textarea.value;
const tagged = '{' + tag + '}';
textarea.value = text.substring(0, start) + tagged + text.substring(end);
textarea.focus();
textarea.selectionStart = textarea.selectionEnd = start + tagged.length;
menu.style.display = 'none';
};
</script>
4. Register the Field in Your Filament Resource
In your resource form, register the custom textarea and provide the $fields:
use App\View\Components\Filament\CustomTagTextarea;
public static function form(Form $form): Form
{
$fields = \Schema::getColumnListing((new YourModel())->getTable());
return $form
->schema([
Forms\Components\View::make('filament.custom-tag-textarea')
->viewData(['fields' => $fields])
->label('Your Textarea')
->required(),
// ... other fields ...
]);
}
5. Styling and Customization
You can further style the context menu and tags to look like chips or styled label spans using CSS and JS as needed.
Summary:
- Use
\Schema::getColumnListing()to fetch fields. - Pass them to a custom textarea Blade component.
- Use JavaScript to display a context menu on right-click and insert selected field names as tags.
This gives you a dynamic, interactive textarea in Filament that meets your requirements!