Laravel integration

MDB backend integration with Laravel for Standard

This article shows you how to integrate Laravel backend application with MDB Standard UI Kit.


Prerequisites

Before starting the project make sure to install the following utilities:

  • Node LTS (14.x.x or higher recommended)
  • PHP (7.4.32 or higher recommended)
  • Composer (2.4.2 or higher recommended)
  • Code editor. We recommend VSCode

Creating a new Laravel application

Let's create a fresh Laravel application so that we can go through all the steps together. For this tutorial we'll be using MySQL database.

Step 1

Creating Laravel project.

You can initialize a MDB GO starter. Simply run the following command:

Note: If you don't have MDB CLI installed yet, you can do it with NPM: npm install -g mdb-cli. Now log in with your MDB account, type: mdb login. If you don't have account yet you can create one using mdb register command.

        
            
        mdb backend init php-free-laravel
      
        
    

Step 2

Creating a MySQL database.

In order to create a new database you need to run the following command.

        
            
          mdb database init -db mysql8
        
        
    
  • Create a new user
  • Provide username, password, database name and description.

CLI will display your username, password, database name and connections string. You will need this data in the next step. Now you can go to phpMyAdmin where you will be able to handle the administration of the MySQL database.

Note: the password must contain at least one uppercase letter, one lowercase letter, one number, one special symbol and have minimum length of 8.

Step 3

After initialization just go to the newly created project directory and open the .env file. After that edit the config values that start with DB_. You should make use of credentials that's been shown to you in the previous step. In my case the updated values look like this:

        
            
        DB_CONNECTION=mysql
        DB_HOST=mysql.db.mdbgo.com
        DB_PORT=3306
        DB_DATABASE=your_database_name
        DB_USERNAME=your_username
        DB_PASSWORD=your_password
      
        
    

Step 4

Create a table.

Go to phpMyAdmin, log in, and add a table, which name will be a plural form of created model. For example on purpose of this tutorial: tasks. Then create a three columns: id (type: int + auto increment), name (type: text) and description (type: text).

Step 5

Navigate to you project direction and install Laravel dependencies using Composer. php-free-laravel is the name from MDB GO starter (you can change whatever you like).

        
            
        composer install
      
        
    

Note: If after this process you got an error bound installation - try composer install --ignore-platform-req=ext-fileinfo or composer update --ignore-platform-reqs.


To Do App with MDB

Step 1

Create a model. You can use built in Laravel pre-made function: php artisan make:model Task, where Task is your custom name (you can change it whatever you like). Nevertheless this model should being inserted in app/Models directory and looks like this:

        
            
        <?php

        namespace App\Models;
        
        use Illuminate\Database\Eloquent\Factories\HasFactory;
        use Illuminate\Database\Eloquent\Model;
        
        class Task extends Model
        {
            use HasFactory;
            public $timestamps=false;
        }      
      
        
    

Step 2

Now create a controller for handling an endpoints. You can use built in Laravel pre-made function: php artisan make:controller TaskController, where TaskController is your custom name (you can change it whatever you like). Nevertheless this controller should being inserted in app/Http/Controllers directory and looks like this:

        
            
        <?php

        namespace App\Http\Controllers;

        use Illuminate\Http\Request;
        use App\Models\Task;

        class TaskController extends Controller
        {

            function addTask(Request $req) {
                $task=new Task;
                $task->id=$req->id;
                $task->name=$req->name;
                $task->description=$req->description;
                $result=$task->save();

                return redirect()->back();
            }

            function editTask(Request $req) {
                $task= Task::find($req->id);
                $task->name=$req->name;
                $task->description=$req->description;
                $result=$task->save();

                return redirect()->back();
            }
            
            function deleteTask($id) {
                $task=Task::find($id);
                $result=$task->delete();
                
                return redirect()->back();
            }
        }    
      
        
    

Step 3

Add routes for newly created controller in api.php file (found in routes folder in root directory).

        
            
        use App\Http\Controllers\TaskController;

        ...

        Route::get('task/{id}', [TaskController::class, 'getTask']);
        Route::post('task', [TaskController::class, 'addTask']);
        Route::put('task', [TaskController::class, 'editTask']);
        Route::delete('task/{id}', [TaskController::class, 'deleteTask']);
      
        
    

Step 4

One more route must be set inside web.php.

        
            
        use App\Http\Controllers\TaskController;

        ...

        Route::get('/', function () {
            $tasks = \App\Models\Task::all();
            return view('welcome' , ['tasks' => $tasks]);
        });
      
        
    

Step 5

Now all we need is to write some code in resources/views/welcome.blade.php. This is the layout of the page and the place where all the requests will be sent from.

        
            
        <!DOCTYPE html>
        <html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
          <head>
            <meta charset="utf-8">
            <meta name="viewport" content="width=device-width, initial-scale=1">

            <title>Material Design for Bootstrap - Laravel</title>

            <!-- Font Awesome -->
            <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.2/css/all.css" />
            <!-- Google Fonts Roboto -->
            <link
              rel="stylesheet"
              href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap"
            />
            <!-- MDB -->
            <link rel="stylesheet" href="css/mdb.min.css" />

            <!-- Styles -->
            <style>
              /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}a{background-color:transparent}[hidden]{display:none}html{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}*,:after,:before{box-sizing:border-box;border:0 solid #e2e8f0}a{color:inherit;text-decoration:inherit}svg,video{display:block;vertical-align:middle}video{max-width:100%;height:auto}.bg-white{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.bg-gray-100{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.border-gray-200{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.border-t{border-top-width:1px}.flex{display:flex}.grid{display:grid}.hidden{display:none}.items-center{align-items:center}.justify-center{justify-content:center}.font-semibold{font-weight:600}.h-5{height:1.25rem}.h-8{height:2rem}.h-16{height:4rem}.text-sm{font-size:.875rem}.text-lg{font-size:1.125rem}.leading-7{line-height:1.75rem}.mx-auto{margin-left:auto;margin-right:auto}.ml-1{margin-left:.25rem}.mt-2{margin-top:.5rem}.mr-2{margin-right:.5rem}.ml-2{margin-left:.5rem}.mt-4{margin-top:1rem}.ml-4{margin-left:1rem}.mt-8{margin-top:2rem}.ml-12{margin-left:3rem}.-mt-px{margin-top:-1px}.max-w-6xl{max-width:72rem}.min-h-screen{min-height:100vh}.overflow-hidden{overflow:hidden}.p-6{padding:1.5rem}.py-4{padding-top:1rem;padding-bottom:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.pt-8{padding-top:2rem}.fixed{position:fixed}.relative{position:relative}.top-0{top:0}.right-0{right:0}.shadow{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.text-center{text-align:center}.text-gray-200{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.text-gray-300{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.text-gray-500{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.text-gray-600{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.text-gray-700{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.text-gray-900{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.underline{text-decoration:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.w-5{width:1.25rem}.w-8{width:2rem}.w-auto{width:auto}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}@media (min-width:640px){.sm\:rounded-lg{border-radius:.5rem}.sm\:block{display:block}.sm\:items-center{align-items:center}.sm\:justify-start{justify-content:flex-start}.sm\:justify-between{justify-content:space-between}.sm\:h-20{height:5rem}.sm\:ml-0{margin-left:0}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:pt-0{padding-top:0}.sm\:text-left{text-align:left}.sm\:text-right{text-align:right}}@media (min-width:768px){.md\:border-t-0{border-top-width:0}.md\:border-l{border-left-width:1px}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:1024px){.lg\:px-8{padding-left:2rem;padding-right:2rem}}@media (prefers-color-scheme:dark){.dark\:bg-gray-800{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.dark\:bg-gray-900{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.dark\:border-gray-700{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.dark\:text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.dark\:text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}}
            </style>
          </head>
          <body class="antialiased">
              <?php 
              $APP_URL = "$_ENV[APP_URL]";
              ?>
              <div class="container mt-5">
                <div class="row pt-5">
                  <div class="col text-center">
                    <button class="btn btn-primary" data-mdb-modal-init data-mdb-target="#addTaskModal" data-mdb-ripple-init >ADD TASK</button>
                  </div>
                </div>
                <div class="row mt-3 p-5" style="min-height: 40vh;">
                  <div class="col d-flex justify-content-center align-items-center">
                    <ul class="list-group list-group-light taskList" style="min-width: 22rem;">
                    <?php foreach ($tasks as $task) { ?>
                      <li class='list-group-item d-flex justify-content-between align-items-center gap-5'>
                        <div>
                          <div class="fw-bold taskName"> <?=$task->name?> </div>
                          <div class="fw-bold taskDescription"> <?=$task->description?> </div>
                        </div>
                        <form method="post" action="{{$APP_URL}}:8000/api/task/{{$task->id}}">
                          <button type="button" class="editBtn btn btn-light btn-floating me-2" id="{{$task->id}}" data-mdb-ripple-init >
                            <span class="fas fa-pen text-primary" title="edit" data-mdb-modal-init data-mdb-target="#editTaskModal"></span>
                          </button>
                          <input type="hidden" name="_method" value="DELETE">
                          <button type="submit" class="deleteBtn btn btn-light btn-floating" id="${taskData[i].id}" data-mdb-ripple-init >
                            <i class="fas fa-trash text-danger" title="delete"></i>
                          </button>
                        </form>
                      </li> 
                      <?php } ?> 
                    </ul>
                  </div>
                </div>
                <div class="modal fade" id="addTaskModal" tabindex="-1" aria-labelledby="addTaskModalLabel" aria-hidden="true">
                  <div class="modal-dialog">
                    <div class="modal-content">
                      <div class="modal-header">
                        <h5 class="modal-title" id="addTaskModalLabel">Add task</h5>
                        <button type="button" class="btn-close" data-mdb-dismiss="modal" aria-label="Close"></button>
                      </div>
                      <form id="addTaskForm" action="{{$APP_URL}}:8000/api/task" method="post">
                        <div class="modal-body">
                          <div class="form-outline mb-4" data-mdb-input-init>
                            <input name='name' type="text" id="nameInput" class="form-control" />
                            <label class="form-label" for="form7Example1">Name</label>
                          </div>
                          <div class="form-outline mb-4" data-mdb-input-init>
                            <input name="description" type="text" id="descInput" class="form-control" />
                            <label class="form-label" for="form7Example2">Email address</label>
                          </div>
                        </div>
                        <div class="modal-footer">
                          <button type="button" class="btn btn-secondary" data-mdb-dismiss="modal" data-mdb-ripple-init > Close </button>
                          <button type="submit" class="btn btn-primary modalConfirmBtn" data-mdb-ripple-init >Confirm</button>
                        </div>
                      </form>
                    </div>
                  </div>
                </div>
                <div class="modal fade" id="editTaskModal" tabindex="-1" aria-labelledby="editTaskModalLabel" aria-hidden="true">
                  <div class="modal-dialog">
                    <div class="modal-content">
                      <div class="modal-header">
                        <h5 class="modal-title" id="editTaskModalLabel">Edit Task</h5>
                        <button type="button" class="btn-close" data-mdb-dismiss="modal" aria-label="Close"></button>
                      </div>
                      <form id="editTaskForm" action="{{$APP_URL}}:8000/api/task" method="post">
                        <input type="hidden" name="_method" value="PUT">
                        <div class="modal-body">
                          <input id="editIdInput" name="id" type="number" value='0' class='d-none'>
                          <div class="form-outline mb-4" data-mdb-input-init>
                            <input name='name' type="text" id="editNameInput" class="form-control" />
                            <label class="form-label" for="editNameInput">Name</label>
                          </div>
                          <div class="form-outline mb-4" data-mdb-input-init>
                            <input name="description" type="text" id="editDescInput" class="form-control" />
                            <label class="form-label" for="editDescInput">Description</label>
                          </div>
                        </div>
                        <div class="modal-footer">
                          <button type="button" class="btn btn-secondary" data-mdb-dismiss="modal" data-mdb-ripple-init > Close </button>
                          <button type="submit" class="btn btn-primary modalConfirmBtn" data-mdb-ripple-init >Confirm</button>
                        </div>
                      </form>
                    </div>
                  </div>
                </div>
              </div>

              <script type="text/javascript" src="js/mdb.umd.min.js"></script>
              <script type="module">
              const editTaskModal = document.querySelector('#editTaskModal');
              const editTaskForm = document.querySelector('#editTaskForm');
              const editBtns = document.querySelectorAll('.editBtn');
              const editIdInput = editTaskForm.querySelector('#editIdInput')

              editBtns.forEach((button) => {
                  button.addEventListener('click', () => {
                      editIdInput.value = button.id;

                      const taskName = button.closest("li").querySelector('.taskName').innerText;
                      const taskDesc = button.closest("li").querySelector('.taskDescription').innerText;

                      editTaskForm.querySelector('#editDescInput').value = taskDesc
                      editTaskForm.querySelector('#editNameInput').value = taskName
                  })
              })
              </script>
          </body>
        </html>

      
        
    

Finally, we can run app using php artisan serve.


Publish your app

Now you can publish your project on MDB GO using the following command:

Note: If you don't have MDB CLI installed yet, you can do it with NPM: npm install -g mdb-cli. Now log in with your MDB account, type: mdb login. If you don't have account yet you can create one using mdb register command.

        
            
      mdb publish -p php-laravel
    
        
    

Note Since we need to install dependencies and run your app, it may take a few moments until it will be available under the provided URL.


Optimization

If you want to further optimize your application please visit:


Backend features

Laravel:

This example was created with Laravel-starter. By creating new endpoints, we could pass or receive data from this application.


Frontend features

MDB UI KIT:

To create the project we used our ui kit, with which we can build basic views very quickly.

Views and Layouts:

In this project we used the welcome.blade.php file created by Laravel where we placed our MDB components. We have successfully integrated the backend with the MDB Standard package and can send basic requests to the Laravel application.