Installation
composer require baks-dev/reference-field
Publish the package assets (if needed) via:
php artisan vendor:publish --provider="BaksDev\ReferenceField\ReferenceFieldServiceProvider" --tag="public"
First Use Case: Basic Reference Field Register a reference field in a Laravel Form Request or Form class:
use BaksDev\ReferenceField\ReferenceField;
public function rules()
{
return [
'user_id' => [
new ReferenceField('users', 'id', 'name', 'User ID'),
'required',
],
];
}
model (string): Eloquent model name (e.g., 'users').id_column (string): Primary key column (default: 'id').display_column (string): Column for display (e.g., 'name').label (string): Human-readable label (optional).Blade Integration
Use the @referenceField directive in your Blade template:
@referenceField('user_id', 'users', 'id', 'name', 'Select User')
name: Input field name.model: Eloquent model.id_column: Primary key (optional).display_column: Display column (optional).label: Label text (optional).Configuration
Check config/reference-field.php for default settings (e.g., query scopes, placeholder text).
public function buildForm(array $data, Form $form)
{
if (auth()->user()->isAdmin()) {
$form->add('department_id', ReferenceField::make('departments', 'id', 'name'));
}
}
// In config/reference-field.php
'scopes' => [
'users' => ['active' => true],
],
Or dynamically:
$field = new ReferenceField('users', 'id', 'name');
$field->setScope('active', true);
use BaksDev\ReferenceField\Nova\ReferenceField;
public function fields(Request $request)
{
return [
new ReferenceField($request, 'user_id', 'users', 'id', 'name', 'User'),
];
}
$validator = Validator::make($data, [
'user_id' => [
new ReferenceField('users', 'id', 'name'),
'exists:users,id',
],
]);
use BaksDev\ReferenceField\ReferenceField;
$field = new ReferenceField('roles', 'id', 'name');
return response()->json(['roles' => $field->getOptions()]);
Laravel Livewire
@referenceField directive in Livewire components:
<livewire:user-form>
@referenceField('user_id', 'users', 'id', 'name', 'User')
</livewire:user-form>
Inertia.js
return Inertia::render('Users/Edit', [
'user' => $user,
'referenceFields' => [
'user_id' => (new ReferenceField('users', 'id', 'name'))->getOptions(),
],
]);
Custom Display Logic
ReferenceField class to modify display behavior:
class CustomReferenceField extends ReferenceField
{
public function getDisplayValue($value)
{
return "Custom: " . parent::getDisplayValue($value);
}
}
Localization
// resources/lang/en/reference-field.php
return [
'placeholders' => [
'users' => 'Select a user...',
],
];
Model Not Found
Class 'App\Models\Users' not found (Laravel's auto-naming).new ReferenceField('App\Models\User', 'id', 'name')
Query Performance
$field = new ReferenceField('posts', 'id', 'title');
$field->setLimit(100);
Caching Stale Data
->fresh():
$field->setModel(Model::query()->fresh());
Blade Directive Conflicts
@referenceField not working due to namespace collisions.AppServiceProvider:
Blade::directive('referenceField', function ($expression) {
return "<?php echo BaksDev\ReferenceField\Blade::referenceField($expression); ?>";
});
Log Query Enable SQL logging to debug queries:
$field = new ReferenceField('orders', 'id', 'customer_name');
\DB::enableQueryLog();
$options = $field->getOptions();
\Log::info(collect(\DB::getQueryLog())->pluck('query'));
Validate Model Binding Ensure the model is properly bound:
$field = new ReferenceField('App\Models\User', 'id', 'email');
if (!$field->isValid($request->user_id)) {
// Handle invalid reference
}
Default Placeholder
config/reference-field.php:
'placeholders' => [
'default' => 'Select an option...',
],
Empty State Handling
$field = new ReferenceField('products', 'id', 'name');
$field->setEmptyOption('All Products', null);
Dynamic Model Binding
$model = auth()->user()->canAccess('admin') ? 'AdminUser' : 'User';
$field = new ReferenceField($model, 'id', 'name');
Custom Option Formatter
ReferenceField class to modify option formatting:
class FormattedReferenceField extends ReferenceField
{
public function getOptions()
{
$options = parent::getOptions();
return collect($options)->mapWithKeys(function ($value, $key) {
return [$key => "<strong>{$value}</strong>"];
});
}
}
Add Search Functionality
document.querySelectorAll('[data-reference-field]').forEach(el => {
el.addEventListener('input', (e) => {
fetch(`/api/search?field=${el.dataset.field}&query=${e.target.value}`)
.then(response => response.json())
.then(data => {
// Update dropdown options
});
});
});
Hooks for Pre/Post Processing
// In AppServiceProvider@boot()
event(new \BaksDev\ReferenceField\Events\BuildingReferenceField(
$field, $model, $idColumn, $displayColumn
));
Custom Storage Logic
$field = new ReferenceField('tags', 'id', 'name');
$field->setStoreFormat(fn ($value) => strtolower($value));
$field->setRetrieveFormat(fn ($value) => ucfirst($value));
How can I help you explore Laravel packages today?