Readytocode
  • Home
  • Laravel
  • PHP
  • React Js
  • Git
  • Server
Facebook X (Twitter) Instagram
Readytocode
  • Home
  • Laravel
  • PHP
  • React Js
  • Git
  • Server
Facebook X (Twitter) Instagram Pinterest LinkedIn Reddit
Readytocode
You are at:Home How to Upload Image in CKEditor 5 Using Laravel 9

Laravel

How to Upload Image in CKEditor 5 Using Laravel 9

JustinBy JustinFebruary 25, 2022Updated:September 11, 2022No Comments6 Mins Read
Facebook Twitter Pinterest LinkedIn Tumblr Email




What is CKEditor 5?

CKEditor (formerly known as FCKeditor) is a WYSIWYG rich text editor which enables writing content directly inside of web pages or online applications. Its core code is written in JavaScript and it is developed by CKSource.

CKEditor is available under open source and commercial licenses.

Modern JavaScript rich text editor with a modular architecture. Its clean UI and features provide the perfect WYSIWYG UX for creating semantic content.

Features of CKEditor

  • Written in ES6 with MVC architecture, custom data model, virtual DOM.
  • Responsive images and media embeds (videos, tweets).
  • Custom output format: HTML and Markdown support.
  • Boost productivity with auto-formatting and collaboration.
  • Extensible and customizable by design.

 

How to Use CKEditor in Laravel 9

First we will create a new Fresh Laravel Project. And then i will guide how to install and add image Adapter to upload image.

CKeditor provides own cloud service to upload image, But in this post we will learn how to create own own custom adapter to upload image. Here i am using CKeditor5.

i will add CDN for CKeditor.

<script src="https://cdn.ckeditor.com/ckeditor5/30.0.0/classic/ckeditor.js"></script>

And now create a form for submit the data to database.

<form class="forms-sample" action="/editor/post-save" method="POST">
                    @csrf
                    <div class="form-group">
                      <label for="exampleInputUsername1">Post Title</label>
                      <input type="text" name="title" class="form-control" id="exampleInputUsername1" placeholder="Post Title">
                    </div>
                    <div class="row">
                        <div class="col-md-6">
                            <div class="form-group">
                                <label for="exampleInputEmail1">Main Category</label>
                                <select class="form-control" name="category" id="category">
                                  <option value="">Choose Main Category</option>
                                  @foreach($category as $v_category)
                                    <option value="{{ $v_category['id'] }}">{{ $v_category['title'] }}</option>
                                  @endforeach
                                </select>
                            </div>
                        </div>
                        <div class="col-md-6">
                            <div class="form-group">
                                <label for="exampleInputEmail1">Sub Category</label>
                                <select class="form-control" name="sub_category" id="subcategory">
                                  <option value="">Choose Sub Category</option>
                                </select>
                            </div>
                        </div>
                    </div>

                    <div class="row">
                        <div class="col-md-12">
                            <div class="form-group">
                                <label for="exampleInputPassword1">Content</label>
                                {{-- <div class="editor"></div> --}}
                                <textarea name="content" id="editor" class="editor" rows="5"></textarea>
                            </div>
                        </div>
                    </div>

                    <div class="row">
                      <div class="col-md-12">
                          <div class="form-group">
                              <label for="exampleInputPassword1">Meta Data</label>
                              {{-- <div class="editor"></div> --}}
                              <textarea name="meta_data" class="form-control"></textarea>
                          </div>
                      </div>
                  </div>
                    
                    <button type="submit" class="btn btn-primary mr-2">Submit</button>
                    <button class="btn btn-light">Cancel</button>
                  </form>

 

I will add the CKeditor in textarea that is

<textarea name="content" id="editor" class="editor"></textarea>

and at the bottom i will add a script for this textarea.

<script>
ClassicEditor
    .create( document.querySelector( '#editor' ), {
            
    } )
    .catch( error => {
            console.error( error );
    } );
</script>

Now our CKeditor is working perfectly. But the problem is Image upload is not working. For this we must have to create a adapter.

<script>
class MyUploadAdapter {
        constructor( loader ) {
            this.loader = loader;
        }
     
        upload() {
            return this.loader.file
                .then( file => new Promise( ( resolve, reject ) => {
                    this._initRequest();
                    this._initListeners( resolve, reject, file );
                    this._sendRequest( file );
                } ) );
        }
     
        abort() {
            if ( this.xhr ) {
                this.xhr.abort();
            }
        }
     
        _initRequest() {
            const xhr = this.xhr = new XMLHttpRequest();
     
            xhr.open( 'POST', "{{route('image-upload', ['_token' => csrf_token() ])}}", true );
            xhr.responseType = 'json';
        }
     
        _initListeners( resolve, reject, file ) {
            const xhr = this.xhr;
            const loader = this.loader;
            const genericErrorText = `Couldn't upload file: ${ file.name }.`;
     
            xhr.addEventListener( 'error', () => reject( genericErrorText ) );
            xhr.addEventListener( 'abort', () => reject() );
            xhr.addEventListener( 'load', () => {
                const response = xhr.response;
     
                if ( !response || response.error ) {
                    return reject( response && response.error ? response.error.message : genericErrorText );
                }
     
                resolve( response );
            } );
     
            if ( xhr.upload ) {
                xhr.upload.addEventListener( 'progress', evt => {
                    if ( evt.lengthComputable ) {
                        loader.uploadTotal = evt.total;
                        loader.uploaded = evt.loaded;
                    }
                } );
            }
        }
     
        _sendRequest( file ) {
            const data = new FormData();
     
            data.append( 'upload', file );
     
            this.xhr.send( data );
        }
    }
</script>

 

Now our final form buttom script will look like below code.

<script>
    class MyUploadAdapter {
        constructor( loader ) {
            this.loader = loader;
        }
     
        upload() {
            return this.loader.file
                .then( file => new Promise( ( resolve, reject ) => {
                    this._initRequest();
                    this._initListeners( resolve, reject, file );
                    this._sendRequest( file );
                } ) );
        }
     
        abort() {
            if ( this.xhr ) {
                this.xhr.abort();
            }
        }
     
        _initRequest() {
            const xhr = this.xhr = new XMLHttpRequest();
     
            xhr.open( 'POST', "{{route('image-upload', ['_token' => csrf_token() ])}}", true );
            xhr.responseType = 'json';
        }
     
        _initListeners( resolve, reject, file ) {
            const xhr = this.xhr;
            const loader = this.loader;
            const genericErrorText = `Couldn't upload file: ${ file.name }.`;
     
            xhr.addEventListener( 'error', () => reject( genericErrorText ) );
            xhr.addEventListener( 'abort', () => reject() );
            xhr.addEventListener( 'load', () => {
                const response = xhr.response;
     
                if ( !response || response.error ) {
                    return reject( response && response.error ? response.error.message : genericErrorText );
                }
     
                resolve( response );
            } );
     
            if ( xhr.upload ) {
                xhr.upload.addEventListener( 'progress', evt => {
                    if ( evt.lengthComputable ) {
                        loader.uploadTotal = evt.total;
                        loader.uploaded = evt.loaded;
                    }
                } );
            }
        }
     
        _sendRequest( file ) {
            const data = new FormData();
     
            data.append( 'upload', file );
     
            this.xhr.send( data );
        }
    }
     
    function MyCustomUploadAdapterPlugin( editor ) {
        editor.plugins.get( 'FileRepository' ).createUploadAdapter = ( loader ) => {
            return new MyUploadAdapter( loader );
        };
    }
     
    ClassicEditor
        .create( document.querySelector( '#editor' ), {
            extraPlugins: [ MyCustomUploadAdapterPlugin ],
        } )
        .catch( error => {
            console.error( error );
        } );
    </script>

Now create a route for image upload.

Route::post('save-image', [CommonController::class, 'image_save'])->name("image-upload");

And controller method, Add the below code in you controller , also please change controller name with your controller name in route file.

public function image_save(Request $request)
    {
         
        if($request->hasFile('upload')) {
            $filenamewithextension= $request->file('upload')->getClientOriginalName();
      
            
            $filename = pathinfo($filenamewithextension, PATHINFO_FILENAME);
      
            
            $extension = $request->file('upload')->getClientOriginalExtension();
      
            
            $filenametostore = $filename.'_'.time().'.'.$extension;
      
            
            $request->file('upload')->storeAs('public/uploads', $filenametostore);
            $request->file('upload')->storeAs('public/uploads/thumbnail', $filenametostore);
     
            
            $thumbnailpath = public_path('storage/uploads/thumbnail/'.$filenametostore);
            $img = Image::make($thumbnailpath)->resize(500, 150, function($constraint) {
                $constraint->aspectRatio();
            });
            $img->save($thumbnailpath);
     
            echo json_encode([
                'default' => asset('storage/uploads/'.$filenametostore),
                '500' => asset('storage/uploads/thumbnail/'.$filenametostore)
            ]);
        }
 
    }

 

I am using here image resize .

composer require intervention/image

and create an alias in config/app.php like below code.

'providers' => [
        ....
        .....
        Intervention\Image\ImageServiceProvider::class,
    ],

    'aliases' => Facade::defaultAliases()->merge([
        .....
        'Image' => Intervention\Image\Facades\Image::class,
    ])->toArray(),

 

and create symbolic link for storage access.

php artisan storage:link

 

Now your form are ready you can check, if its working fine please comment , if any problem then please comment i will help you sure.

Thanks

Happy Coding…

 

Some Popular Post

Summernote Editor With Image Upload in Laravel

Laravel 9 send mail using SMTP

Installing Git on Linux

Laravel 9 – How to Get User Country, City, ZIP from IP

Laravel 9 – How to use Datatable

Total
0
Shares
Share 0
Tweet 0
Pin it 0
Share 0

Like this:

Like Loading...

Related

Share. Facebook Twitter Pinterest LinkedIn Tumblr Email
Justin
  • Website

Related Posts

How to Generate image from text with Laravel 10

May 16, 2023

Laravel 10 Restrict User Access

May 3, 2023

Laravel 10 Pagination Example

May 3, 2023

Leave A Reply Cancel Reply

Featured Posts
  • Why meta tag is important for seo 1
    How to change react Page title, Page Description and some other meta Tag
    • August 4, 2023
  • 2
    How to Generate image from text with Laravel 10
    • May 16, 2023
  • Laravel 10 Restrict User Access 3
    Laravel 10 Restrict User Access
    • May 3, 2023
  • Laravel 10 Pagination Example 4
    Laravel 10 Pagination Example
    • May 3, 2023
  • install Steam on Ubuntu 5
    How to install Steam on Ubuntu 22.04 step by step
    • April 20, 2023



Readytocode
Facebook X (Twitter) Instagram Pinterest
  • About Us
  • Privacy Policy
© 2025 ReadyToCode.

Type above and press Enter to search. Press Esc to cancel.

%d