AJAX is a widely used technique that allows you to send and receive data in your application and refresh a part of your page, without the need for a full page refresh.
In Laravel, sending data via an AJAX POST request involves adding JavaScript code to your blade view, and processing the received data by implementing a function in the controller. Additionally, you’ll need to define a route linking the controller function to a specific URL.
In this tutorial, we’ll create an example application that can add tasks to a list without a full page refresh. I’ll guide you through each step of the process, including installing Laravel, setting up models, migrations, controllers, routes, and views. I will provide two approaches to send the POST request from your view, one will use Axios and one will use jQuery. You can choose which of them best suits your project requirements
Let’s get started!
Step 1: Install Laravel
If you haven’t already, set up a new Laravel project by running:
composer create-project laravel/laravel laravel-ajax-post
Step 2: Add Database Credentials to .env
(Optional)
If you’ve installed Laravel 11 or newer you can use the default Sqlite database connection out of the box without editing any configuration for it. In this case you can skip this step.
Should you wish to use a different database, like MySQL or PostgreSQL, you should edit the file .env
accordingly. For example, to use MySQL, you should edit it to look like this:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laracoding
DB_USERNAME=my-mysql-username
DB_PASSWORD=my-mysql-password
This assumes you’ve installed a MySQL server and created the user named “my-mysql-username
” and the database named “laracoding
“. Make sure you edit these to match your own database and user names.
Step 3: Create Model to save a Task
Generate a new model named Task
using Artisan, along with its migration file:
php artisan make:model Task -m
Step 4: Add Model code
Open the generated Model in app/Models/Task.php and add the following code to make the columns mass assignable:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Task extends Model
{
protected $fillable = [
'name',
'description',
'completed',
'due_date'
];
}
Step 5: Add Migration Code
Open the migration file created in the database/migrations
directory and define the schema for the tasks
table using the code below.
For the sake of example, I suggest adding some columns a task would need, such as name
, description
, status
, and due_date
:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('tasks', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->text('description')->nullable();
$table->boolean('completed')->default(false);
$table->dateTime('due_date')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('tasks');
}
};
Step 6: Create Controller
Create a new controller named TaskController
by runnin the following Artisan command:
php artisan make:controller TaskController
Step 7: Add Controller Code
In the TaskController
, implement the index
method to load a view and the store
method to handle the AJAX POST request:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Task;
class TaskController extends Controller
{
// Shows all tasks
public function index()
{
return view('tasks.index', ['tasks' => Task::all()]);
}
// Handles Ajax POST to create a task
public function store(Request $request)
{
$task = new Task();
$task->name = $request->input('name');
$task->save();
return response()->json($task);
}
}
Step 8: Create Routes
Using the code below you’ll define a get route to show the index page and a post route to receive post requests for adding new tasks:
<?php
use App\Http\Controllers\TaskController;
use Illuminate\Support\Facades\Route;
// Shows all tasks
Route::get('/', [TaskController::class, 'index'])->name('tasks.index');
// Handles Ajax POST to create a task
Route::post('/', [TaskController::class, 'store'])->name('tasks.store');
Step 9: Send POST Request Using Axios
Create a view blade file named index.blade.php
in the resources/views/tasks
directory. This file will contain the HTML for the index page and the form for adding tasks.
You may use the example code below to use Axios for sending the Ajax POST requests:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tasks</title>
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-sm-6 col-sm-offset-6 p-5">
<h1 class="mb-4">Tasks</h1>
<form id="taskForm" class="mb-4">
<div class="input-group">
<input type="text" class="form-control" name="name" placeholder="Enter task name">
<button type="submit" class="btn btn-primary">Add Task</button>
</div>
</form>
<ul id="taskList" class="list-group">
@forelse ($tasks as $task)
<li>{{ $task->name }}</li>
@empty
@endforelse
</ul>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
const form = document.getElementById('taskForm');
form.addEventListener('submit', async (event) => {
// Make sure the submit button doesn't use a regular / non-ajax submit
event.preventDefault();
const formData = new FormData(form);
try {
// Send AJAX POST request using Axios
const response = await axios.post('{{ route('tasks.store') }}', formData);
const task = response.data;
const taskList = document.getElementById('taskList');
const listItem = document.createElement('li');
listItem.textContent = task.name;
taskList.appendChild(listItem);
form.reset();
} catch (error) {
console.error('Error:', error);
}
});
</script>
</body>
</html>
Should you prefer using jQuery, refer to the code used in the next step instead.
Step 10: Send POST Request Using jQuery (Optional)
In case you wish to use jQuery you can use similar code but replace the script portion of the page as follows:
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="csrf-token" content="{{ csrf_token() }}">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tasks</title>
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-sm-6 col-sm-offset-6 p-5">
<h1 class="mb-4">Tasks</h1>
<form id="taskForm" class="mb-4">
<div class="input-group">
<input type="text" class="form-control" name="name" placeholder="Enter task name">
<button type="submit" class="btn btn-primary">Add Task</button>
</div>
</form>
<ul id="taskList" class="list-group">
@forelse ($tasks as $task)
<li>{{ $task->name }}</li>
@empty
@endforelse
</ul>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script>
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$(document).ready(function() {
$('#taskForm').submit(function(event) {
// Makes sure the submit button doesn't use a regular / non-ajax submit
event.preventDefault();
const formData = $(this).serialize();
// Send AJAX POST request using jQuery
$.post('{{ route('tasks.store') }}', formData)
.done(function(response) {
// Update task list in the html page
const taskList = $('#taskList');
const listItem = $('<li>').text(response.name);
taskList.append(listItem);
// Clear the form
$('#taskForm')[0].reset();
})
.fail(function(error) {
console.error('Error:', error);
});
});
});
</script>
</body>
</html>
Step 11: Run the Application
Now let’s start the Laravel development server by running:
php artisan serve
Afterwards you can open your browser and navigate to http://localhost:8000
to view our index page.
On this page you can use the form to input a name and submit it to create a new task. This form will be sent by a POST request to our TaskController’s store method. When the task was successfully stored it is dynamically added to the unordered list on the index page without the need to refresh the page:
Congratulations! You’ve successfully implemented sending and processing AJAX POST requests in a Laravel application
Conclusion
In this tutorial you learned to build a controller to receive an AJAX POST request, and a view to send the request using JavaScript. For actually sending the request I’ve covered using either Axios or jQuery.
The example application uses an index page to show a view with a list of tasks and a form to add new tasks. When the form is submitted, new tasks are dynamically added to the list without the need for page reload.
Should you have any questions let me know in the comments below and I’ll try to answer them. Feel free to apply the techniques shown in this tutorial to enhance the interactivity of your own Laravel applications.
Happy Coding!
References
- Routing (Laravel Documentation)
- Controllers (Laravel Documentation)
- Axios Documentation
- jQuery AJAX Documentation