Adding Image Upload feature in GrapesJS editor

|
| By Webner

In GrapesJS, there is an ‘image’ block which we can drag and drop on the canvas but it only allows us to specify URL of the image to add to Asset Manager. Then we can embed that image in the document from Asset Manager by double-clicking. What if we want to upload an image from the local computer in GrapeJS editor:

To add upload image feature to GrapeJS we have to make some code additions. In short, we will use localhost assets to save uploaded images temporarily and use them to embed into the editor. Then in uploadFile function (in the code below), we use ajax call to send details of the uploaded image and create a proper json in the format required by the Asset Manager of GrapesJS. We get json from the php page and then add that image (json) to the Asset Manager of GrapesJS. Now, you will see your uploaded image in the asset manager from where you can select the image and embed it in the editor.

By default, we have assetManager object as:

assetManager: {
    	storageType  	: '',
    	storeOnChange	: true,
    	storeAfterUpload  : true,
    	assets    	: []
  	},

Change assetManager json to:

assetManager: {
 	storageType  	: '',
    	storeOnChange  : true,
    	storeAfterUpload  : true,
    	upload: 'https://localhost/assets/upload',        //for temporary storage
    	assets    	: [ ],
     	uploadFile: function(e) {
		var files = e.dataTransfer ? e.dataTransfer.files : e.target.files;
var formData = new FormData();
		for(var i in files){
    		    formData.append('file-'+i, files[i]) //containing all the selected images from local
		}
$.ajax({
url: '/location to your php page/upload_image.php',
type: 'POST',
			data: formData,
			contentType:false,
	crossDomain: true,
	dataType: 'json',
	mimeType: "multipart/form-data",
	processData:false,
	success: function(result){
    				var myJSON = [];
    				$.each( result['data'], function( key, value ) {
        					myJSON[key] = value;    
    				});
    				var images = myJSON;    
      		editor.AssetManager.add(images); //adding images to asset 
manager of GrapesJS
    			}
});
},
},

From the php page (upload_image.php), an array is returned, here is sample code:

if($_FILES)
{
$resultArray = array();
	foreach ( $_FILES as $file){
             	$fileName = $file['name'];
             	$tmpName = $file['tmp_name'];
             	$fileSize = $file['size'];
             	$fileType = $file['type'];
             	if ($file['error'] != UPLOAD_ERR_OK)
             	{
                 		error_log($file['error']);
                 		echo JSON_encode(null);
             	}
             	$fp = fopen($tmpName, 'r');
             	$content = fread($fp, filesize($tmpName));
             	fclose($fp);
            	$result=array(
                 		'name'=>$file['name'],
                 		'type'=>'image',
                 		'src'=>"data:".$fileType.";base64,".base64_encode($content),
                 		'height'=>350,
                 		'width'=>250
             	); 
		// we can also add code to save images in database here.
              	array_push($resultArray,$result);
 	}    
$response = array( 'data' => $resultArray );
echo json_encode($response);
}

Now the process of uploading the image from the local system and how to use that image is explained below:

1. Click on the area where ‘Drop files here or click to upload’ is written, to upload an image or drag the image from your local system or from the browser and drop in this area:

2. After selecting the image, you will see the image in Asset Manager (shown in below screenshot):

3. Select the image from asset manager to embed it in the editor (below screenshot shows how it looks like):

4 comments

  1. Hi, why do we need localhost? Can’t we post to the php file directly?Sorry if I have misunderstood. I am looking for a standalone way to use php to add images to the asset manager. The localhost bit is confusing me to be honest.

  2. Hello, I had problem with drag-drop not showing uploaded image (it uploaded and added to asset manager, but not
    in content).
    I solved it by calling callback function that is passed to uploadFile function like this:

    uploadFile: (e, clb) => {
    let files = e.dataTransfer ? e.dataTransfer.files : e.target.files;
    return this.uploadImages(files)
    .then(text => clb && clb(text))
    .catch(err => console.log(err))
    }

    this.uploadImages is almost the same as described in article up.

Leave a Reply

Your email address will not be published. Required fields are marked *