Learning Management Platform for Written Tutorial Series.

Laravel 6 Ajax Tutorial

Laravel 6 Ajax Tutorial

Web applications are increasingly become more popular and users expect a similar experience offered by desktop applications. Traditionally, web applications have to send requests to the server and wait for the response. The response has to refresh the entire web page even if its just a small aspect of the page that needs to be updated. This leads to performance issues and affects the user experience. AJAX solves this problem by only updating the potion that needs to be updated without affecting the entire page.

The tutorial will first cover the theoretical aspect of AJAX, discuss the advantages and disadvantages then show you how to do the implementation. If you are already familiar with the theory then you can skip it and go to the implementation.

Laravel Ajax CRUD Example

Video Demo of Application

Topics to be covered

  • Tutorial Pre-requisites
  • What is Ajax
  • Why use Ajax?
  • When to Use Ajax
  • jQuery Ajax API
  • Laravel Ajax CRUD Example

Tutorial Pre-requisites

This tutorial assumes;

  • You understand the basics of Laravel
  • You have PHP and MySQL up and running
  • You have the basics of HTML and JavaScript especially jQuery
  • You have composer installed
  • You have a text editor or IDE that supports PHP.
  • You have a modern web browser that supports HTML5
  • You have been following the tutorial series and you understand the basics of Laravel 5.

What is AJAX?

AJAX is the acronym for Asynchronous JavaScript and XML. AJAX refers to a group of technologies that enable web application clients to send and receive data from the server asynchronously. In this case, asynchronous refers to sending and retrieving data in the background without affecting the display of the current page. Ajax is implemented using the following technologies

  • JavaScript – client-side scripting language that ties all of the technologies together
  • HTML/XHTML/CSS – used for the presentation of data
  • Document Object Model (DOM) – used to access and manipulate structured documents
  • XML / JSON – used to exchange data. JSON is now commonly used in place of XML format.
  • XMLHttpRequest – JavaScript object that is responsible for asynchronous communication with the server.

Advantages and disadvantages of Ajax?

The following are some of the advantages of Ajax when developing web applications.

  • Improved User Experience – Ajax makes it possible to create interactive applications that are fast and do not require reloading the whole page. The user can continue using the application whilst Ajax operations are going on in the background
  • Reduced bandwidth usage – Bandwidth costs money and Ajax enables you to save. Traditional applications require reloading all of the assets even if you are only interested in a small section of the application. This results in using up a lot of bandwidth. Ajax only lets you pull the required data from the server.
  • Improved system performance – Ajax only retrieves the required data from the server. This greatly improves the system performance and response time.
  • Promotes separation of data, business logic and presentation – Ajax calls usually retrieve data from the server and if necessary, business logic is applied. Data is displayed after these actives have successfully been completed.

The following are the disadvantages if using Ajax

  • Requires JavaScript – JavaScript is a client-side technology and you have no control over it. If the user disables JavaScript on their web browser then Ajax will not work.
  • Web browser compatibility – not all web browsers especially very old ones have support for all of the technologies that Ajax uses. These days most browsers support these technologies so you should worry much about this.
  • Hard/impossible to bookmark content – users usually bookmark content so that they can easily go back to it later. With Ajax content, this is impossible or at a minimum requires extra effort to implement.
  • JavaScript Content generally isn’t SEO friendly – it is easier for Search Engines to crawl classic content compared to content that is generated via JavaScript. Developing SEO content with JavaScript requires extra efforts.

In conclusion, in most cases, the advantages outweigh the disadvantages and you will have to work with Ajax in one way or another. The next section looks at when you should use Ajax

When to Use AJAX

The following are some of the idea situations when you should use Ajax

  • Auto complete – if you have worked with any search engine, chances are suggestions were made to you before you could complete typing. Ajax can be used to provide such functionality
  • Auto save – when you are composing an email and something to your internet and you lose the connection to the server, chances are you will find your work in drafts directory. This is just one example. If you develop a content management system, you can also provide similar functionality where you save the users work periodic to provide auto restore functionality.
  • Pagination – you can only see so much at a time. Pagination allows you to display a limited number of items at a time and provide links that allow users to view the next segment. Google Search lists 10 items per page and provides you with links to other result pages. Ajax can greatly improve the user experience when displaying content that has been paginated.
  • Blog comments – what’s a blog without a comments section? The experience is improved when it is implemented using Ajax. Users can submit comments without reloading the entire page which can be very frustrating.
  • Real time validation – you can use Ajax to provide feedback to users in real time. let’s say a user is filling in a registration form on website. You can use Ajax to validate the submitted email address and let the user know if it is available before the user even submits the form.
  • …and many more – Ajax can also be used to implement functionality such as surveys, online voting, filtering and sorting data etc.

jQuery AJAX API

Using Ajax requires you to know JavaScript and a set of other technologies. This increases the development time and cost. Fortunately, JavaScript libraries such as jQuery can make your life easier. jQuery has an Ajax API that provides Ajax implementation.

Laravel AJAX CRUD Example Components

Before we create our application, we will first look at the major components that make up an AJAX Laravel application.

  • AJAX Application Programming Interface (API) – our AJAX forms will be submitting data to the server and receiving feedback. The data from the form is sent the normal way while the server responds with JSON content. You can use any format that is applicable but JSON is the commonly used one and its what we will use in this tutorial.
  • JavaScript – JavaScript is a core component of AJAX. We will work with jQuery library in this tutorial to make things easy. You don’t need to know JavaScript to follow along in this tutorial
  • Web Application – by this, we the regular HTML, CSS and basic JavaScript for building the user interface.

Laravel Ajax CRUD Example

In this section, we are going to use composer to create a new Laravel application using the latest version of 5.8*. I will create my application on the desktop. Feel free to use whatever location that you prefer. Open the command prompt / terminal.

cd ~/Desktop

Run the following command to create a new project.

composer create-project laravel/laravel ajax-crud 6.0.*

HERE,

  • The above command creates a directory ajax-crud and installs the latest version of Laravel 6.0

After the above command has run successfully, run the following command to browse to the new project directory

cd ajax-crud

Let’s now test the installation. We will work with the built-in server.

Run the following command

php artisan serve --port=777

HERE,

  • The above command starts the built-in web serve on port 777

Open the following URL in your web browser

http://localhost:777

You will see the welcome page for Laravel

Laravel Homepage

We will create a simple to do list application

Open the command prompt / terminal and browse to the project root.

Run the following command to create a model and migration file at the same time.

php artisan make:model Task –m

HERE,

  • The above command creates a model task and its migration file

Open the model Task in /app/Task.php

Update the code to the following

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Task extends Model
{
    protected $fillable = ['task', 'description','done'];
}

HERE,

  • protected $fillable = ['task', 'description','done']; specifies the fields that can be mass assigned.

Let’s now update the database migration file

Open the migration file in /database/migrations/xxxx_xx_xx_xxxxxx_create_tasks_table.php

Update the code to the following

<?php

use App\Task;
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateTasksTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tasks', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('task');
            $table->string('description');
            $table->boolean('done')->default(0);
            $table->timestamps();
        });

        Task::create([
            'task' => 'Weekend hookup',
            'description' => 'Call Helga in the afternoon',
            'done' => false,
        ]);

        Task::create([
            'task' => 'Late night coding',
            'description' => 'Finishing coding POS API',
            'done' => false,
        ]);
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('tasks');
    }
}

If you are not familiar with the concepts of migrations then I recommend you read this tutorial Laravel Migrations Tutorial

Before we run our migration files, we will need to create a database in MySQL and configure our project to connect to the database.

Run the following SQL statement in MySQL

Create schema ajax_crud;

HERE,

  • The above command creates a database in MySQL called ajax_crud.

Let’s now setup the database configuration parameters to connect to out MySQL Server.

Open .env file in the project root.

Set the configurations as shown below

DB_HOST=localhost
DB_DATABASE=ajax_crud
DB_USERNAME=root
DB_PASSWORD=xxx

Note: the above settings should match the ones on your development machine.

Execute the following command to run the migrations

php artisan migrate

Note: if you are using a lower version of MySQL which usually comes with XAMPP then you may get the following error message

Illuminate\Database\QueryException  : SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table `users` add unique `users_email_unique`(`email`))

To resolve the above, open /app/Providers/AppServiceProvider.php

Update it to the following code

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Schema;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Schema::defaultStringLength(191);
    }
}

HERE,

  • use Illuminate\Support\Facades\Schema; imports the schema façade class
  • Schema::defaultStringLength(191); sets the default string length that is Laravel migrations compatible with lower versions of MySQL.

Note: you will have to manually delete the partially created tables in the database before you proceed to the following command.

Run the following command again (if you had the above error else you can skip this section)

php artisan migrate

Check the database after running the migration files. You should be able to see the tasks table with two records that we seeded in the migration file.

Laravel Blade Bootstrap Modal Forms

We will use Twitter bootstrap to do some fancy styling for the user interface. Even though we only need one html page for all the functionality, we will take advantage of Laravel blade partials to breakdown the code into small manageable parts

Our structure will be as follows

Laravel AJAX CRUD Blade Views

HERE,

  • tasks_add.blade.php – contains the HTML for the modal form that we will use to add a new task
  • tasks_delete.blade.php – contains the HTML for the modal form that we will use to ask the user for confirmation before deleting the task
  • tasks_edit.blade.php – contains the HTML for the modal form that we will use to edit and update tasks
  • tasks.blade.php – is the parent view that will load the partial views.

We will work with the following JavaScript and CSS resources

  • css/style.css – this file will contain the styling for the beautiful interface you saw in the above image.
  • js/tasks.js – this file will contain the jQuery Javascript code that will be performing the AJAX CRUD operations.
  • Other files such as Bootstrap and jQuery library will be loaded directly from the respective CDN networks.

Create a new file in /resources/views/tasks.blade.php

Add the following code to tasks.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>Laravel 5.8 Ajax Example</title>
<link rel="shortcut icon" href="{{asset('images/favicon.png')}}" type="image/x-icon"/>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto|Varela+Round">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="{{asset('css/style.css')}}">
</head>
<body>
    <div class="container">
        <div class="table-wrapper">
            <div class="table-title">
                <div class="row">
                    <div class="col-sm-6">
                        <h2>Manage <b>Tasks</b></h2>
                    </div>
                    <div class="col-sm-6">
                        <a onclick="event.preventDefault();addTaskForm();" href="#" class="btn btn-success" data-toggle="modal"><i class="material-icons">&#xE147;</i> <span>Add New Task</span></a>                       
                    </div>
                </div>
            </div>
            <table class="table table-striped table-hover">
                <thead>
                    <tr>
                        <th>ID</th>
                        <th>Task</th>
                        <th>Created At</th>
                        <th>Description</th>
                        <th>Done</th>
                        <th>Actions</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach($tasks as $task)
                    <tr>
                        <td>{{$task->id}}</td>
                        <td>{{$task->task}}</td>
                        <td>{{$task->created_at}}</td>
                        <td>{{$task->description}}</td>
                        <td>{{($task->done) ? 'Yes' : 'No'}}</td>
                        <td>
                            <a onclick="event.preventDefault();editTaskForm({{$task->id}});" href="#" class="edit open-modal" data-toggle="modal" value="{{$task->id}}"><i class="material-icons" data-toggle="tooltip" title="Edit">&#xE254;</i></a>
                            <a onclick="event.preventDefault();deleteTaskForm({{$task->id}});" href="#" class="delete" data-toggle="modal"><i class="material-icons" data-toggle="tooltip" title="Delete">&#xE872;</i></a>
                        </td>
                    </tr>
                    @endforeach
                </tbody>
            </table>
            <div class="clearfix">
                <div class="hint-text">Showing <b>{{$tasks->count()}}</b> out of <b>{{$tasks->total()}}</b> entries</div>
                {{ $tasks->links() }}
            </div>

        </div>
    </div>
    @include('partials.tasks_add')
    @include('partials.tasks_edit')
    @include('partials.tasks_delete')
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <script type="text/javascript" src="{{asset('js/tasks.js')}}"></script>
</body>
</html>                                                                 

HERE,

  • We load the required styling files in the header section of the blade view
  • <meta name="csrf-token" content="{{ csrf_token() }}"> sets the Laravel CSRF token as a header meta value. We will need this value when performing AJAX operations.
  • On line 25, <a onclick="event.preventDefault();addTaskForm();" href="#" class="btn btn-success" data-toggle="modal"><i class="material-icons">&#xE147;</i> <span>Add New Task</span></a> defines the click event for the anchor that we will use to display the modal form that we will use to create the tasks. The line event.preventDefault(); prevents the normal anchor behavior which is opening a link and addTaskForm(); calls a JavaScript function that displays our form.
  • @foreach($tasks as $task) loops through the $tasks variable which is passed from the controller and displays the data in the table
  • onclick="event.preventDefault();editTaskForm({{$task->id}});" defines the click event for the edit record function that accepts the task id for the task that we wish to edit.
  • onclick="event.preventDefault();deleteTaskForm({{$task->id}});" defines the click event for the delete record function that accepts the task id for the task that we wish to delete.
  • {{ $tasks->links() }} prints pagination links at the button of the page
  • @include('partials.tasks_add') @include('partials.tasks_edit') @include('partials.tasks_delete') uses the blade include directive to load the partial views into the parent template. We do this for organizational purposes and avoid having one large file.
  • Finally we load some JavaScript resources at the button of the page.

CSS Styling

You can download the CSS from our Github page https://github.com/KodeBlog/Laravel-Ajax-CRUD-Example/blob/master/public/css/style.css

Let’s now create the partial views.

Create a new directory called partials in /resources/views

Create the following files in /resources/views/partials

The code for the partial views is as follows

The code for tasks_add.blade.php

<!-- Add Task Modal Form HTML -->
<div class="modal fade" id="addTaskModal">
    <div class="modal-dialog">
        <div class="modal-content">
            <form id="frmAddTask">
                <div class="modal-header">
                    <h4 class="modal-title">
                        Add New Task
                    </h4>
                    <button aria-hidden="true" class="close" data-dismiss="modal" type="button">
                        ×
                    </button>
                </div>
                <div class="modal-body">
                    <div class="alert alert-danger" id="add-error-bag">
                        <ul id="add-task-errors">
                        </ul>
                    </div>
                    <div class="form-group">
                        <label>
                            Task
                        </label>
                        <input class="form-control" id="task" name="task" required="" type="text">
                        </input>
                    </div>
                    <div class="form-group">
                        <label>
                            Description
                        </label>
                        <input class="form-control" id="description" name="description" required="" type="text">
                        </input>
                    </div>
                </div>
                <div class="modal-footer">
                    <input class="btn btn-default" data-dismiss="modal" type="button" value="Cancel">
                        <button class="btn btn-info" id="btn-add" type="button" value="add">
                            Add New Task
                        </button>
                    </input>
                </div>
            </form>
        </div>
    </div>
</div>

The code for tasks_delete.blade.php is as follows

<!-- Delete Task Modal Form HTML -->
<div class="modal fade" id="deleteTaskModal">
    <div class="modal-dialog">
        <div class="modal-content">
            <form id="frmDeleteTask">
                <div class="modal-header">
                    <h4 class="modal-title" id="delete-title" name="title">
                        Delete Task
                    </h4>
                    <button aria-hidden="true" class="close" data-dismiss="modal" type="button">
                        ×
                    </button>
                </div>
                <div class="modal-body">
                    <p>
                        Are you sure you want to delete this task?
                    </p>
                    <p class="text-warning">
                        <small>
                            This action cannot be undone.
                        </small>
                    </p>
                </div>
                <div class="modal-footer">
                    <input id="task_id" name="task_id" type="hidden" value="0">
                        <input class="btn btn-default" data-dismiss="modal" type="button" value="Cancel">
                            <button class="btn btn-danger" id="btn-delete" type="button">
                                Delete Task
                            </button>
                        </input>
                    </input>
                </div>
            </form>
        </div>
    </div>
</div>

The code for tasks_edit.blade.php is as follows

<!-- Edit Modal HTML -->
<div class="modal fade" id="editTaskModal">
    <div class="modal-dialog">
        <div class="modal-content">
            <form id="frmEditTask">
                <div class="modal-header">
                    <h4 class="modal-title">
                        Edit Task
                    </h4>
                    <button aria-hidden="true" class="close" data-dismiss="modal" type="button">
                        ×
                    </button>
                </div>
                <div class="modal-body">
                    <div class="alert alert-danger" id="edit-error-bag">
                        <ul id="edit-task-errors">
                        </ul>
                    </div>
                    <div class="form-group">
                        <label>
                            Task
                        </label>
                        <input class="form-control" id="task" name="task" required="" type="text">
                        </input>
                    </div>
                    <div class="form-group">
                        <label>
                            Description
                        </label>
                        <input class="form-control" id="description" name="description" required="" type="text">
                        </input>
                    </div>
                </div>
                <div class="modal-footer">
                    <input id="task_id" name="task_id" type="hidden" value="0">
                        <input class="btn btn-default" data-dismiss="modal" type="button" value="Cancel">
                            <button class="btn btn-info" id="btn-edit" type="button" value="add">
                                Update Task
                            </button>
                        </input>
                    </input>
                </div>
            </form>
        </div>
    </div>
</div>

That is, it for the views. Let’s now work on the JavaScript

Laravel AJAX jQuery CRUD Example JavaScript Code

Next create the file tasks.js in the directory /public/js

Add the following code

$(document).ready(function() {
    $("#btn-add").click(function() {
        $.ajaxSetup({
            headers: {
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
            }
        });
        $.ajax({
            type: 'POST',
            url: '/tasks',
            data: {
                task: $("#frmAddTask input[name=task]").val(),
                description: $("#frmAddTask input[name=description]").val(),
            },
            dataType: 'json',
            success: function(data) {
                $('#frmAddTask').trigger("reset");
                $("#frmAddTask .close").click();
                window.location.reload();
            },
            error: function(data) {
                var errors = $.parseJSON(data.responseText);
                $('#add-task-errors').html('');
                $.each(errors.messages, function(key, value) {
                    $('#add-task-errors').append('<li>' + value + '</li>');
                });
                $("#add-error-bag").show();
            }
        });
    });
    $("#btn-edit").click(function() {
        $.ajaxSetup({
            headers: {
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
            }
        });
        $.ajax({
            type: 'PUT',
            url: '/tasks/' + $("#frmEditTask input[name=task_id]").val(),
            data: {
                task: $("#frmEditTask input[name=task]").val(),
                description: $("#frmEditTask input[name=description]").val(),
            },
            dataType: 'json',
            success: function(data) {
                $('#frmEditTask').trigger("reset");
                $("#frmEditTask .close").click();
                window.location.reload();
            },
            error: function(data) {
                var errors = $.parseJSON(data.responseText);
                $('#edit-task-errors').html('');
                $.each(errors.messages, function(key, value) {
                    $('#edit-task-errors').append('<li>' + value + '</li>');
                });
                $("#edit-error-bag").show();
            }
        });
    });
    $("#btn-delete").click(function() {
        $.ajaxSetup({
            headers: {
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
            }
        });
        $.ajax({
            type: 'DELETE',
            url: '/tasks/' + $("#frmDeleteTask input[name=task_id]").val(),
            dataType: 'json',
            success: function(data) {
                $("#frmDeleteTask .close").click();
                window.location.reload();
            },
            error: function(data) {
                console.log(data);
            }
        });
    });
});

function addTaskForm() {
    $(document).ready(function() {
        $("#add-error-bag").hide();
        $('#addTaskModal').modal('show');
    });
}

function editTaskForm(task_id) {
    $.ajax({
        type: 'GET',
        url: '/tasks/' + task_id,
        success: function(data) {
            $("#edit-error-bag").hide();
            $("#frmEditTask input[name=task]").val(data.task.task);
            $("#frmEditTask input[name=description]").val(data.task.description);
            $("#frmEditTask input[name=task_id]").val(data.task.id);
            $('#editTaskModal').modal('show');
        },
        error: function(data) {
            console.log(data);
        }
    });
}

function deleteTaskForm(task_id) {
    $.ajax({
        type: 'GET',
        url: '/tasks/' + task_id,
        success: function(data) {
            $("#frmDeleteTask #delete-title").html("Delete Task (" + data.task.task + ")?");
            $("#frmDeleteTask input[name=task_id]").val(data.task.id);
            $('#deleteTaskModal').modal('show');
        },
        error: function(data) {
            console.log(data);
        }
    });
}

HERE,

  • $("#btn-add").click(function() {…} defines the click event for the Add Task button that is on the modal form.
  • $.ajaxSetup({…}); sets up the AJAX X-CSRF-TOKEN header and passes the token value that we set up in the header section of the parent template. 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') reads the header meta named csrf-token and reads the value of the content attribute and assigns it to X-CSRF-TOKEN.
  • $.ajax({…}); performs the AJAX operation.
    • o type: 'POST', specifies the HTTP verb to be used.
    • o url: '/tasks', defines the URL that our AJAX operation should interact with.
    • o data: {…} defines the values that should be submitted to the back-end server that processes the AJAX operations. task: $("#frmAddTask input[name=task]").val(), uses jQuery to get the value of the input named task in the form with the id of #frmAddTask.
    • o dataType: 'json', sets the data type for the operation
    • o success: function(data) {…} defines the function that should be called if everything works ok. The function accepts a parameter data which contains the data returned from the server.
    • o error: function(data) {…} is the function that is called when the back-end returns an error. In our case, we expect to receive validation errors and display them to the user.
  • $("#btn-edit").click(function() {…} defines the click event for the edit task submit button
  • $("#btn-delete").click(function() {…} defines the click event for the delete task submit button
  • function addTaskForm() {…} defines the show add task modal form.
  • function editTaskForm(task_id) {…} defines the function that displays the edit form. This function accepts a parameter of task_id, performs an AJAX operation to retrieve the record from the server then displays the returned values in the edit task form.
  • function deleteTaskForm(task_id) {...} defines the function that displays the delete record confirmation modal form. It accepts a task_id parameter that is used to retrieve the record from the database and displays the task name in the confirm delete dialogue form.

That is it for the client side JavaScript. If you need further explanations on the above code then use the comments section to ask.

Laravel AJAX API

We will now need to create a basic API that will be responding to our AJAX calls. Laravel has a custom file for defining API routes but for simplicity’ sake, we will define our “API” route in the web routes form.

The table below shows the routes that we will work with

Laravel AJAX Routes

Open /routes/web.php

Add the following routes

Route::get('/', [
    'uses' => 'TasksController@index',
    'as' => 'tasks.index',
]);


Route::group(['prefix' => 'tasks'], function () {
    Route::get('/{id}', [
        'uses' => 'TasksController@show',
        'as'   => 'tasks.show',
    ]);

    Route::post('/', [
        'uses' => 'TasksController@store',
        'as'   => 'tasks.store',
    ]);

    Route::put('/{id}', [
        'uses' => 'TasksController@update',
        'as'   => 'tasks.update',
    ]);

    Route::delete('/{id}', [
        'uses' => 'TasksController@destroy',
        'as'   => 'tasks.destroy',
    ]);
});

HERE,

  • Our routes will be interacting with a model named TasksController and we have named all of our routes.

Laravel AJAX Controller

Let’s now create the controller class for the above code

Run the following command

php artisan make:controller TasksController

Open /app/Http/Controllers/TasksController.php

Add the following code

<?php

namespace App\Http\Controllers;

use App\Task;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class TasksController extends Controller
{
    public function index(Request $request)
    {
        $tasks = Task::orderBy('id', 'desc')->paginate(5);

        return view('tasks')->with('tasks',$tasks);
    }

    public function store(Request $request)
    {
        $validator = Validator::make($request->input(), array(
            'task' => 'required',
            'description' => 'required',
        ));

        if ($validator->fails()) {
            return response()->json([
                'error'    => true,
                'messages' => $validator->errors(),
            ], 422);
        }

        $task = Task::create($request->all());

        return response()->json([
            'error' => false,
            'task'  => $task,
        ], 200);
    }

    public function show($id)
    {
        $task = Task::find($id);

        return response()->json([
            'error' => false,
            'task'  => $task,
        ], 200);
    }

    public function update(Request $request, $id)
    {
        $validator = Validator::make($request->input(), array(
            'task' => 'required',
            'description' => 'required',
        ));

        if ($validator->fails()) {
            return response()->json([
                'error'    => true,
                'messages' => $validator->errors(),
            ], 422);
        }

        $task = Task::find($id);

        $task->task        =  $request->input('task');
        $task->description = $request->input('description');

        $task->save();

        return response()->json([
            'error' => false,
            'task'  => $task,
        ], 200);
    }

    public function destroy($id)
    {
        $task = Task::destroy($id);

        return response()->json([
            'error' => false,
            'task'  => $task,
        ], 200);
    }
}

HERE,

  • public function index(Request $request){…} defines the index method that displays the blade view and passes in the $tasks variable as a parameter. $tasks = Task::orderBy('id', 'desc')->paginate(5); orders the tasks by id in descending order and paginates the results.
  • public function store(Request $request){…} is the function that receives the AJAX POST request and creates a new task. The function validates the input. If the input passes then a new task is created and a success result is returned. If then validation fails then an error response is returned with the relevant message.
  • public function show($id){…} is the function that responds to the AJAX GET request for a single task.
  • public function update(Request $request, $id){…} this is the function that responds to the AJAX PUT method. It also performs validation.
  • public function destroy($id){…} defines the function that responds to the AJAX DELETE request and deletes the record from the database.

Loading the application in the web browser

Run the following command to start the server.

php artisan serve –port=777

Load the following URL into your web browser

http://localhost:777

You will get the following results

Laravel Ajax CRUD Example

Click on the add button

You will get the following modal form

Ajax Add

Click on Add New Task without entering anything

You will get the following error messages

Ajax Add

Click on edit button

You will get a modal form with the details of the task that you clicked

Ajax Edit

Click on delete button

You will get the following form

Ajax Delete

Summary

In this tutorial, we learnt how to create a Laravel AJAX application that Creates, Reads, Updates and Deletes data from the database. We will be looked at how to perform Laravel AJAX validation and display error messages on the modal form when they occur.

What’s next?

If you found this tutorial useful, support us by using the social media buttons to like and share the tutorial. If you didn’t find it useful, please use the comments section below to let us know how we can do better next time. You can also signup for a free account on the site and use the forums section to ask any programming questions that you have and we promise to do our best to answer them. You can also answer questions from other members and build your reputation.

Complete Source Code Download

You can download the complete source code by clicking this link https://github.com/KodeBlog/Laravel-Ajax-CRUD-Example/archive/master.zip

Alternative you can clone the repository using the following Git command

git clone https://github.com/KodeBlog/Laravel-Ajax-CRUD-Example.git
composer install

...