antqa/ajax-autocomplete-bundle
Installation:
composer require antqa/ajax-autocomplete-bundle
Add to config/bundles.php (Laravel 5.4+):
return [
// ...
AntQa\AjaxAutoCompleteBundle\AntQaAjaxAutoCompleteBundle::class => ['all' => true],
];
Define Routes (in routes/web.php):
Route::get('/find', [YourController::class, 'find'])->name('autocomplete.find');
Route::get('/get/{ids}', [YourController::class, 'get'])->name('autocomplete.get');
Basic Controller (Laravel-style):
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
public function find(Request $request) {
$query = $request->input('q');
$results = DB::table('your_table')
->where('column', 'LIKE', "%{$query}%")
->select('id', 'name')
->get();
return response()->json($results);
}
public function get($ids) {
$ids = explode(',', $ids);
$results = DB::table('your_table')
->whereIn('id', $ids)
->select('id', 'name')
->get();
return response()->json($results);
}
Frontend Integration (jQuery + Select2):
$('select').select2({
ajax: {
url: '/find',
dataType: 'json',
data: function(params) {
return { q: params.term };
},
processResults: function(data) {
return { results: data };
}
}
});
Form Integration:
Form facade:
{!! Form::select('search', null, [], [
'class' => 'autocomplete-select',
'data-placeholder' => 'Search...'
]) !!}
$(document).ready(function() {
$('.autocomplete-select').select2({
ajax: { url: '{{ route("autocomplete.find") }}' }
});
});
Dynamic Data Sources:
find() to query Elasticsearch instead of SQL.find() and cache responses.Validation & Sanitization:
find():
$query = trim($request->input('q', ''));
if (strlen($query) < 2) return response()->json([]);
Pagination:
limit and offset to queries:
$results = DB::table('your_table')
->where('column', 'LIKE', "%{$query}%")
->select('id', 'name')
->limit(10)
->offset($request->input('offset', 0))
->get();
Caching:
$cacheKey = "autocomplete:{$query}";
$results = Cache::remember($cacheKey, 3600, function() use ($query) {
return DB::table('your_table')->where('column', 'LIKE', "%{$query}%")->get();
});
Laravel Mix/Webpack:
// resources/js/app.js
import 'select2/dist/css/select2.min.css';
import 'select2/dist/js/select2.min.js';
API Resources:
ApiResource for consistent JSON responses:
class AutocompleteResource extends JsonResource {
public function toArray($request) {
return [
'id' => $this->id,
'text' => $this->name,
];
}
}
Then return:
return response()->json(AutocompleteResource::collection($results));
Middleware:
auth or throttle middleware:
Route::get('/find', [YourController::class, 'find'])
->middleware('auth')
->name('autocomplete.find');
Testing:
Http::fake():
$response = $this->get('/find?q=test');
$response->assertJsonCount(2);
CSRF Protection:
Route::get('/find', [YourController::class, 'find'])
->middleware('web')
->middleware('csrf-exempt'); // Only if needed!
VerifyCsrfToken exception:
public function find(Request $request) {
if (!$request->expectsJson()) {
abort(403);
}
// ...
}
SQL Injection:
// ❌ Bad
DB::table('users')->where("name LIKE '%{$query}%'");
// ✅ Good
DB::table('users')->where('name', 'LIKE', "%{$query}%");
Case Sensitivity:
LOWER() or ILIKE for case-insensitive searches:
DB::table('users')->whereRaw('LOWER(name) LIKE ?', ["%{$query}%"]);
Performance:
SELECT *; explicitly define columns.CREATE INDEX idx_name ON users(name);
Select2 Version Mismatch:
formatResult/formatSelection to use text:
formatResult: object => object.text,
formatSelection: object => object.text,
Check Network Requests:
{ results: [...] }).Log Queries:
DB::enableQueryLog();
// Run query...
dd(DB::getQueryLog());
Validate JSON:
return response()->json($data)->setEncodingOptions(JSON_UNESCAPED_SLASHES);
Test with Postman:
/find?q=test to isolate backend issues.Custom Data Transformers:
class AutocompleteTransformer {
public static function transform($entity) {
return [
'id' => $entity->id,
'text' => $entity->name,
'children' => $entity->children->pluck('name'),
];
}
}
Event Listeners:
event(new AutocompleteSearched($query, $results));
Dynamic Route Binding:
/get/{ids}:
Route::get('/get/{ids}', [YourController::class, 'get'])
->where('ids', '.*');
Twig Integration (if using Symfony):
Symfony vs. Laravel:
QueryBuilder with Eloquent or Query Builder.Route::get) instead of Symfony's YAML routes.Deprecated Methods:
setParameter('name', $value) in Laravel; use ->where('name', $value).Bundle Auto-Loading:
config/app.php under providers.JavaScript Conflicts:
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
How can I help you explore Laravel packages today?