Search code examples
tinymce

Problems displaying image in Tinymce text editor with JS


I have the code, the image is uploaded and returns me the URL of the image that is saved next to my server, the problem that always throws me the following error and I can not understand the error or where is the fall.

  var tin = tinymce.init({
    selector: 'textarea#description',
    height: 350,
    menubar: true,
    language: 'es',
    plugins: ['image', 'advlist', 'autolink', 'lists', 'link', 'charmap', 'preview', 'anchor', 'searchreplace', 'visualblocks', 'code', 'fullscreen', 'insertdatetime', 'media', 'table', 'help', 'wordcount'],
    toolbar: 'undo redo | image | blocks | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table | removeformat',
    content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:14px }',
    branding: false,
    relative_urls: false,
    images_upload_handler: function (blobInfo, success, failure){
        var xhr, formData;
        xhr = new XMLHttpRequest();
        xhr.withCredentials = false;
        xhr.open('POST','{{ route("upload_image_no_attach") }}');
        var token = '{{ csrf_token() }}';
        xhr.setRequestHeader("X-CSRF-TOKEN",token);
        xhr.onload = function() {
            // var json;
            // if (xhr.status != 200) {
            //     console.log('HTTP Error: ' + xhr.status);
            //     return;
            // }
            // json = JSON.parse(xhr.responseText);

            // if (!json || typeof json.location != 'string') {
            //     console.log('Invalid JSON: ' + xhr.responseText);
            //     return;
            // }

            // success(json.location);
            if (xhr.status === 200) {
          // this is callback data: url
                const url = JSON.parse(xhr.responseText);//.data;
                const location = `${window.location.origin}/opportunity/image/${url}`;
                console.log(location);
                success(location)
            }
        };

        formData = new FormData();
        formData.append('image',blobInfo.blob(), blobInfo.filename());
        xhr.send(formData);
    }

  });

The console does not bring me any error, only the error is presented from a Tinymce alert.

enter image description here

Controller

    public function publishImage(Request $request){
        $file_data = File::createFiles($request->all(),null,null);
        return json_encode(['location' => $file_data->pathURL()]);
    }

Solution

  • Given your error message, the issue appears to be in your implementation of the images_upload_handler option. The implementation used is for TinyMCE 4/5, however given the error message it appears that you're using TinyMCE 6. TinyMCE 6 made some modernization changes and this was one of them whereby it now needs to return a Promise instead of using the success and failure callbacks.

    The TinyMCE 6 migration guide and this specific point can be found here: https://www.tiny.cloud/docs/tinymce/6/migration-from-5x/#images_upload_handler. A newer working example can be found here: https://www.tiny.cloud/docs/tinymce/6/file-image-upload/#images_upload_handler

    As such, to fix that error you should just need to update your TinyMCE configuration to something like this:

      var tin = tinymce.init({
        selector: 'textarea#description',
        height: 350,
        menubar: true,
        language: 'es',
        plugins: ['image', 'advlist', 'autolink', 'lists', 'link', 'charmap', 'preview', 'anchor', 'searchreplace', 'visualblocks', 'code', 'fullscreen', 'insertdatetime', 'media', 'table', 'help', 'wordcount'],
        toolbar: 'undo redo | image | blocks | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table | removeformat',
        content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:14px }',
        branding: false,
        relative_urls: false,
        images_upload_handler: (blobInfo) => {
          return new Promise((success, failure) => {
            var xhr, formData;
            xhr = new XMLHttpRequest();
            xhr.withCredentials = false;
            xhr.open('POST','{{ route("upload_image_no_attach") }}');
            var token = '{{ csrf_token() }}';
            xhr.setRequestHeader("X-CSRF-TOKEN",token);
            xhr.onload = function() {
              // var json;
              // if (xhr.status != 200) {
              //     console.log('HTTP Error: ' + xhr.status);
              //     return;
              // }
              // json = JSON.parse(xhr.responseText);
    
              // if (!json || typeof json.location != 'string') {
              //     console.log('Invalid JSON: ' + xhr.responseText);
              //     return;
              // }
    
              // success(json.location);
              if (xhr.status === 200) {
                // this is callback data: url
                const url = JSON.parse(xhr.responseText);//.data;
                const location = `${window.location.origin}/opportunity/image/${url}`;
                console.log(location);
                success(location)
              }
            };
    
            formData = new FormData();
            formData.append('image', blobInfo.blob(), blobInfo.filename());
            xhr.send(formData);
          });
        }
      });