DEV Community

loading...

How to create modal in Laravel 8 and Laravel 6/7 with AJax

Kingsconsult
I am Kingsley Okpara, a Python and PHP Fullstack Web developer and tech writer, I also have extensive knowledge and experience with JavaScript while working on applications developed with VueJs.
Updated on ・6 min read

Hello, today we are going to add a little feature to our CRUD app
laravel 8 CRUD, which is using bootstrap Modal to create, edit and view our projects, this can be extended to anything you want to do in Laravel 6/7/8 that requires displaying in a modal.
Modal helps us to work on another page without moving out of the current page, which helps not to lose sight of where we are. We are going to be using Bootstrap, Jquery, and Ajax to achieve this. Jquery and Ajax will send the URL with the id of the item we want to edit or view into the modal dynamically.
As it is always my culture, I will simplify this article to the level of any developer with screenshots and the code snippets, you can visit the GIthub repo if you just need the code or you made a mistake in following the article.

Click on my profile to follow me to get more updates.

Like I said earlier, anything that requires performing an action on another page and coming back can be achieved with a modal without navigating to different pages. All you need is to copy the code in the script tag and change the id of the button to be click and also the id of the modal to be display.
I will be displaying two sizes of the modal, one for small modal and the other for a medium modal, bootstrap has different sizes, small (modal-sm), medium (default), large (modal-lg).
small modal view
medium modal view
large modal view

Step 1: Setup the app

  1. git clone https://github.com/Kingsconsult/laravel_8_crud.git
  2. cd laravel_8_crud/
  3. composer install
  4. npm install
  5. cp .env.example .env
  6. php artisan key:generate
  7. Add your database config in the .env file (you can check my articles on how to achieve that)
  8. php artisan migrate
  9. php artisan serve (if the server opens up, http://127.0.0.1:8000, then we are good to go) localhost
  10. Navigate to http://127.0.0.1:8000/projects project index
  11. Click on the Green button at the top-right to create some projects create project create project

Step 2: Add the bootstrap, jquery, ajax script tag

In the head section of the app.blade.php in resources/views/layouts/ directory, add the following scripts below

<title>App Name - @yield('title')</title>

<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/css/bootstrap.css" rel="stylesheet">

<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<!-- Script -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js' type='text/javascript'></script>

<!-- Font Awesome JS -->
<script defer src="https://use.fontawesome.com/releases/v5.0.13/js/solid.js" integrity="sha384-tzzSw1/Vo+0N5UhStP3bvwWPq+uvzCMfrN1fEFe+xBmv1C/AtVX5K0uZtmcHitFZ" crossorigin="anonymous"> </script>
<script defer src="https://use.fontawesome.com/releases/v5.0.13/js/fontawesome.js" integrity="sha384-6OIrr52G08NpOFSZdxxz1xdNSndlD4vdcf/q2myIUVO0VsqaGHJsB0RaBE01VTOY" crossorigin="anonymous"> </script>

<link href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css' rel='stylesheet' type='text/css'>

<style>
    .footer {
        position: fixed;
        left: 0;
        bottom: 0;
        width: 100%;
        background-color: #9C27B0;
        color: white;
        text-align: center;
    }
    body {
        background-color: #EDF7EF
    }

</style>
Enter fullscreen mode Exit fullscreen mode

Step 3: edit the index.blade.php

Go to the index.blade.php in resources/views/projects/ directory, copy, and paste the code below.

index.blade.php

@extends('layouts.app')

@section('content')

    <div class="row">
        <div class="col-lg-12 margin-tb">
            <div class="pull-left">
                <h2>Laravel 8 CRUD </h2>
            </div>
            <div class="pull-right">
                <a class="btn btn-success text-light" data-toggle="modal" id="mediumButton" data-target="#mediumModal"
                    data-attr="{{ route('projects.create') }}" title="Create a project"> <i class="fas fa-plus-circle"></i>
                </a>
            </div>
        </div>
    </div>

    @if ($message = Session::get('success'))
        <div class="alert alert-success">
            <p>{{ $message }}</p>
        </div>
    @endif

    <table class="table table-bordered table-responsive-lg table-hover">
        <thead class="thead-dark">
            <tr>
                <th scope="col">No</th>
                <th scope="col">Name</th>
                <th scope="col" width="30%">Introduction</th>
                <th scope="col">Location</th>
                <th scope="col">Cost</th>
                <th scope="col">Date Created</th>
                <th scope="col">Action</th>
            </tr>
        </thead>
        <tbody>
            @foreach ($projects as $project)
                <tr>
                    <td scope="row">{{ ++$i }}</td>
                    <td>{{ $project->name }}</td>
                    <td>{{ $project->introduction }}</td>
                    <td>{{ $project->location }}</td>
                    <td>{{ $project->cost }}</td>
                    <td>{{ date_format($project->created_at, 'jS M Y') }}</td>
                    <td>
                        <form action="{{ route('projects.destroy', $project->id) }}" method="POST">

                            <a data-toggle="modal" id="smallButton" data-target="#smallModal"
                                data-attr="{{ route('projects.show', $project->id) }}" title="show">
                                <i class="fas fa-eye text-success  fa-lg"></i>
                            </a>

                            <a class="text-secondary" data-toggle="modal" id="mediumButton" data-target="#mediumModal"
                                data-attr="{{ route('projects.edit', $project->id) }}">
                                <i class="fas fa-edit text-gray-300"></i>
                            </a>
                            @csrf
                            @method('DELETE')

                            <button type="submit" title="delete" style="border: none; background-color:transparent;">
                                <i class="fas fa-trash fa-lg text-danger"></i>
                            </button>
                        </form>
                    </td>
                </tr>
            @endforeach
        </tbody>
    </table>

    {!! $projects->links() !!}


    <!-- small modal -->
    <div class="modal fade" id="smallModal" tabindex="-1" role="dialog" aria-labelledby="smallModalLabel"
        aria-hidden="true">
        <div class="modal-dialog modal-sm" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body" id="smallBody">
                    <div>
                        <!-- the result to be displayed apply here -->
                    </div>
                </div>
            </div>
        </div>
    </div>


    <!-- medium modal -->
    <div class="modal fade" id="mediumModal" tabindex="-1" role="dialog" aria-labelledby="mediumModalLabel"
        aria-hidden="true">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body" id="mediumBody">
                    <div>
                        <!-- the result to be displayed apply here -->
                    </div>
                </div>
            </div>
        </div>
    </div>


    <script>
        // display a modal (small modal)
        $(document).on('click', '#smallButton', function(event) {
            event.preventDefault();
            let href = $(this).attr('data-attr');
            $.ajax({
                url: href,
                beforeSend: function() {
                    $('#loader').show();
                },
                // return the result
                success: function(result) {
                    $('#smallModal').modal("show");
                    $('#smallBody').html(result).show();
                },
                complete: function() {
                    $('#loader').hide();
                },
                error: function(jqXHR, testStatus, error) {
                    console.log(error);
                    alert("Page " + href + " cannot open. Error:" + error);
                    $('#loader').hide();
                },
                timeout: 8000
            })
        });

        // display a modal (medium modal)
        $(document).on('click', '#mediumButton', function(event) {
            event.preventDefault();
            let href = $(this).attr('data-attr');
            $.ajax({
                url: href,
                beforeSend: function() {
                    $('#loader').show();
                },
                // return the result
                success: function(result) {
                    $('#mediumModal').modal("show");
                    $('#mediumBody').html(result).show();
                },
                complete: function() {
                    $('#loader').hide();
                },
                error: function(jqXHR, testStatus, error) {
                    console.log(error);
                    alert("Page " + href + " cannot open. Error:" + error);
                    $('#loader').hide();
                },
                timeout: 8000
            })
        });

    </script>
@endsection
Enter fullscreen mode Exit fullscreen mode

From our code above, in the anchor tag to create a project, we remove the href=” ” and replace it with data-attr=” “, we also added data-toggle=” “, id=” “ and data-target=” “.
We created two div below our table with a class of “modal fade”, these div displays different sizes of modal with the heading specified and contents of the modal. Inside the modal div, there is a div with class modal-dialog, this is where we can change the size of the modal.
Lastly, we added a script tag that contains jquery, ajax logic in displaying the modal.
What we did in the script tag

  1. On click of the button in the anchor tag, it should grab the URL found in the anchor tag
  2. If the URL is valid and on success, it will grab the id of the target modal and pass the contents of the URL to the body of the modal
  3. If there is an error with the URL, it will alert the user with the error message that the URL cannot be open

Step 4: edit the create, edit, show pages

Go to the create.blade.php, edit.blade.php and show.blade.php in resources/views/projects/ directory, and remove the extension of the base layouts,

@extends(‘layouts.app’)
@section(‘content’)
@endsection
Enter fullscreen mode Exit fullscreen mode

That is all, we are good to go

  1. clicking Create button Create page
  2. clicking the show button show page
  3. clicking the edit button Create page You can follow me, leave a comment below, suggestion, reaction, or email, WhatsApp or call me, my contacts are on the screenshot. Visit my other posts

Discussion (6)

Collapse
faeza97 profile image
Faeza Mohammed

How to make the validation work inside your modal?

Collapse
kingsconsult profile image
Kingsconsult Author

which kind of validation are you talking about?

Collapse
faeza97 profile image
Faeza Mohammed • Edited

Laravel validator is not working inside the modal.
how to make it work? while inputting blank values it will just refresh the page after submit button.
blade



@if ($errors->any())
<div class="alert alert-danger">
    <strong>Whoops!</strong> There were some problems with your input.<br><br>
    <ul>
        @foreach ($errors->all() as $error)
        <li>{{ $error }}</li>
        @endforeach
    </ul>
</div>
@endif
Enter fullscreen mode Exit fullscreen mode

controller

 $request->validate([
            'name' => 'required',
            'introduction' => 'required',
            'location' => 'required',
            'cost' => 'required'
        ]);
        $project->update($request->all());

        return redirect()->route('projects.index')
            ->with('success', 'Project updated successfully');
    }
Enter fullscreen mode Exit fullscreen mode
Thread Thread
faeza97 profile image
Faeza Mohammed • Edited

Look when I erase the input values and submit the form again it won't show the error messages for laravel validator

dev-to-uploads.s3.amazonaws.com/i/...

Thread Thread
christophebossens profile image
Christophe Bossens

Probably a bit late, but if it doesn't help you it might still be useful for other people. I think you are mixing two approaches:

First, you can submit a form by sending a POST request to the server, and the server will then redirect you to a new page. In that case you can use the $errors directive to catch anything that went wrong during validation.

When using a modal, you submit your data using AJAX. This means you basically never leave the page you are on. The server will still return a response, but you have to process this in your JavaScript (specifically, in the AJAX error callback function).

You can find more info here: stackoverflow.com/questions/493337...

Collapse
joseantoniobsi profile image
joseantoniobsi

Very good! Thanks for the contribution!