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.
Contents
- Database Configuration
- Table structure
- Model
- Controller
- Route
- Download CKEditor 5
- View
- Output
- 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
, andMessages
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.
- / – Load
<?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
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.