Installation:
composer require troopers/ajax-bundle
Add to config/bundles.php (Laravel 5.5+) or AppKernel.php (Symfony):
Troopers\AjaxBundle\TroopersAjaxBundle::class,
Load Assets:
Include in your layout (e.g., resources/views/layouts/app.blade.php):
<!-- CSS -->
<link rel="stylesheet" href="{{ asset('bundles/troopersajax/css/ajax.css') }}">
<!-- JS (after jQuery) -->
<script src="https://code.jquery.com/jquery-3.6.min.js"></script>
<script src="{{ asset('bundles/troopersajax/js/ajax.js') }}"></script>
First Use Case:
Add data-toggle="ajax" to a link/form and specify a target container:
<!-- Link Example -->
<a href="/search" data-toggle="ajax" data-update="results">Search</a>
<div id="results"></div>
<!-- Form Example -->
<form action="/submit" method="POST" data-toggle="ajax" data-update="form-result">
<input type="submit" value="Submit">
</form>
<div id="form-result"></div>
Route::get('/search', [SearchController::class, 'ajaxSearch']);
Route::post('/submit', [FormController::class, 'ajaxSubmit']);
public function ajaxSearch(Request $request)
{
$results = $this->searchService->execute($request->query);
return view('partials.search_results', compact('results'));
}
Update Strategies:
Use data-update-strategy for granular control:
<a href="/load-more" data-toggle="ajax" data-update="content" data-update-strategy="append">
Load More
</a>
Options: replace (default), append, prepend, before, after, or a custom jQuery method.
Form Submission with Data:
<form data-toggle="ajax" data-update="form-result" data-form="#search-form">
<input type="hidden" name="action" value="filter">
</form>
Note: The form’s action attribute is overridden by the link’s href.
<select name="category" data-refreshonchange="true">
<option value="all">All</option>
</select>
public function handleCategoryChange(Request $request)
{
if (!$request->query->get('novalidate')) {
$form = $this->formFactory->create();
$form->handleRequest($request);
if (!$form->isValid()) {
$form = $this->formFactory->create();
$form->setData($request->query->get('user'));
}
return $this->renderForm($form);
}
}
<a href="/modal-content" data-toggle="ajax-modal">Open Modal</a>
<div class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<!-- Your content here -->
</div>
</div>
</div>
window.loader = '<div class="custom-loader">Loading...</div>';
window.loaderOverlay = '<div class="overlay"></div>';
Place in a <script> tag before ajax.js.ajax.js are loaded after jQuery.
<!-- WRONG: Loads jQuery after ajax.js -->
<script src="{{ asset('bundles/troopersajax/js/ajax.js') }}"></script>
<script src="https://code.jquery.com/jquery-3.6.min.js"></script>
data-update IDs match existing DOM elements. Use:
console.log($('#updater-container').length); // Check if element exists
CSRF Tokens: For forms, include a hidden CSRF token:
<form data-toggle="ajax">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>
Form Validation:
The bundle does not handle validation by default. Use Symfony’s isValid() or Laravel’s validate() in your controller.
Dynamic Content: If updating containers dynamically (e.g., with JavaScript), reinitialize the bundle:
$('[data-toggle="ajax"]').ajaxBundle(); // Re-attach events
ajax.js and ajax.css for production.<a href="/lazy-load" data-toggle="ajax" data-defer="true">Lazy Load</a>
data-effect attribute:
// In a separate JS file
$(document).on('ajax:beforeLoad', function(e, settings) {
if (settings.effect === 'custom') {
settings.effect = function() {
$(this).html(settings.content).slideUp(300).slideDown(500);
};
}
});
$(document).on('ajax:complete', function(e, settings) {
console.log('AJAX completed for:', settings.target);
});
mix() for asset paths:
<script src="{{ mix('js/ajax.js') }}"></script>
php artisan route:clear
ajax.js is compatible (tested down to jQuery 1.9+).<a href="/search" data-toggle="ajax">Search (AJAX)</a>
<a href="/search?fallback=1">Search (No JS)</a>
How can I help you explore Laravel packages today?