Add CKEditor 5 and save it to MySQL database in Laravel

CKEditor is a widely use WYSIWYG (What You See Is What You Get) editor. It provides all the basic features that are required for formatting.

The editor works perfectly but you need to write extra code for file upload through the editor.

In this tutorial, I show how you can add CKeditor 5 to an HTML element and save it to the MySQL database in Laravel 9.

Add CKEditor 5 and save it to MySQL database in Laravel


Contents

  1. Database Configuration
  2. Table structure
  3. Model
  4. Controller
  5. Route
  6. Download CKEditor 5
  7. View
  8. Output
  9. Conclusion

1. Database Configuration

Open .env file.

Specify the host, database name, username, and password.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=tutorial
DB_USERNAME=root
DB_PASSWORD=

2. Table structure

  • Create a new table messages using migration.
php artisan make:migration create_messages_table
  • Now, navigate to database/migrations/ folder from the project root.
  • Find a PHP file that ends with create_messages_table and open it.
  • Define the table structure in the up() method.
public function up()
{
    Schema::create('messages', function (Blueprint $table) {
       $table->id();
       $table->string('subject');
       $table->text('message');
       $table->timestamps();
    });
}
  • Run the migration –
php artisan migrate

3. Model

  • Create Messages Model –
php artisan make:model Messages
  • Open app/Models/Messages.php file.
  • Specify mass assignable Model attributes – subject, and message using the $fillable property.

Completed Code

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Messages extends Model
{
   use HasFactory;

   protected $fillable = [
      'subject','message'
   ];
}

4. Controller

  • Create PagesController controller –
php artisan make:controller PagesController
  • Import Validator, Session, and Messages model.

Create 3 methods –

  • index() – Load index view.
  • uploadFile() – Using this method upload the selected file from the CKEditor. Access file using upload name.

Validate the file. If not validated then assign 0 to $data['uploaded'] and error message to $data['error']['message'].

If validated successfully then upload the file to uploads folder.

After upload assign $filename to $data['fileName'], 1 to $data['uploaded'], and $filepath to $data['url'].

  • submitform() – Using this method handle form submit.

Validate the submitted values. If not validated then return to the page with error messages otherwise insert a new record in the messages table, and specify the success message in SESSION flash.

Redirect page to /.

Completed Code

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Session;
use App\Models\Messages;

class PagesController extends Controller
{
     public function index(){
         return view('index');
     }

     // Upload CkEditor file
     public function uploadFile(Request $request){

         $data = array();

         $validator = Validator::make($request->all(), [
              'upload' => 'required|mimes:png,jpg,jpeg|max:2048'
         ]);

         if ($validator->fails()) {

              $data['uploaded'] = 0;
              $data['error']['message'] = $validator->errors()->first('upload');// Error response

         }else{
              if($request->file('upload')) {

                    $file = $request->file('upload');
                    $filename = time().'_'.$file->getClientOriginalName();

                    // File upload location
                    $location = 'uploads';

                    // Upload file
                    $file->move($location,$filename);

                    // File path
                    $filepath = url('uploads/'.$filename);

                    // Response
                    $data['fileName'] = $filename;
                    $data['uploaded'] = 1;
                    $data['url'] = $filepath;

              }else{
                    // Response
                    $data['uploaded'] = 0;
                    $data['error']['message'] = 'File not uploaded.'; 
              }
         }

         return response()->json($data);
     }

     // Submit form
     public function submitform(Request $request){

         $validator = Validator::make($request->all(), [
              'subject' => 'required',
              'message' => 'required',
         ]);

         if ($validator->fails()) {
              return redirect()->Back()->withInput()->withErrors($validator);
         }else{
              // Insert record
              Messages::create([
                  'subject' => $request->subject,
                  'message' => $request->message
              ]);

              Session::flash('message','Form submit Successfully.');
         }

         return redirect('/');

     }

}

5. Route

  • Open routes/web.php file.
  • Define 3 routes –
    • / – Load index view.
    • /uploadFile – This is use to upload CKEditor selected file.
    • /submitform – Handle form submit.
<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PagesController;

Route::get('/', [PagesController::class, 'index']);
Route::post('/submitform',[PagesController::class,'submitform'])->name('submitform');
Route::post('/uploadFile',[PagesController::class,'uploadFile'])->name('uploadFile');

6. Download CKEditor 5

  • Download CKEditor 5 library from here or you can use CDN –
<!-- ckeditor5 JS -->
<script src="https://cdn.ckeditor.com/ckeditor5/35.4.0/classic/ckeditor.js"></script>

7. View

Create index.blade.php file in resources/views/ folder.

HTML

Create a <form >. Set its action to {{ route('submitform') }}.

Here, create a textbox, textarea element, and a submit button. Define CKEditor on textarea.


Script

Initialize CKEditor on .editor class. Using ckfinder to set upload file URL.

Set uploadUrl to "{{route('uploadFile').'?_token='.csrf_token()}}". Here, pass the CSRF token with the URL.

Completed Code

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>Add CKEditor 5 and save it to MySQL database in Laravel</title>

    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" >

    <style type="text/css">
    .ck-editor__editable {
         min-height: 250px;
    }
    </style>
</head>
<body>

    <div class="container">
         <div class="row">
               <div class="col-md-8 mt-5" style="margin: 0 auto;">

                    <!-- Alert message (start) -->
                    @if(Session::has('message'))
                         <div class="alert alert-success">
                             {{ Session::get('message') }}
                         </div>
                    @endif
                    <!-- Alert message (end) -->

                    <form method="post" action="{{ route('submitform') }}">

                        @csrf

                        <div class="form-group mb-4">

                            <label class="control-label col-sm-2" for="subject">Subject:</label>

                            <div class="col-sm-10">
                                  <input type="text" class="form-control" id="name" placeholder="Enter Subject" name="subject" value="{{ old('subject') }}">
                            </div>

                            <!-- Error -->
                            @if($errors->has('subject'))

                                <div class='text-danger mt-2'>
                                     * {{ $errors->first('subject') }}
                                </div>

                            @endif
                        </div>

                        <div class="form-group mb-4">

                            <label class="control-label col-sm-2" for="message">Message:</label>
                            <div class="col-sm-10">
                                <textarea class="form-control editor" name="message"></textarea>
                            </div>

                            <!-- Error -->
                            @if($errors->has('message'))

                                <div class='text-danger mt-2'>
                                     * {{ $errors->first('message') }}
                                </div>

                            @endif

                        </div>

                        <div class="form-group "> 
                            <div class="col-sm-offset-2 col-sm-10">
                                <button type="submit" class="btn btn-info">Submit</button>
                            </div>
                        </div>

                    </form>

               </div>

          </div>

    </div>

    <!-- Script -->
    <script src="https://cdn.ckeditor.com/ckeditor5/35.4.0/classic/ckeditor.js"></script>
    <script type="text/javascript">

    ClassicEditor
          .create( document.querySelector( '.editor' ),{ 
                ckfinder: {
                      uploadUrl: "{{route('uploadFile').'?_token='.csrf_token()}}",
                }
          } )
          .then( editor => {

                console.log( editor );

          } )
          .catch( error => {
                console.error( error );
          } );
    </script>
</body>
</html>

8. Output

View Output


9. Conclusion

CKEditor element data is directly accessible after submission on the server side.

If you want to show stored CKEditor data in MySQL database then read and store it in CKEditor textarea element.

If you found this tutorial helpful then don't forget to share.

Leave a Comment