From 045539edf9947a68163e8e111aeb27115c9e1522 Mon Sep 17 00:00:00 2001 From: pxpm Date: Mon, 2 Dec 2024 15:04:55 +0000 Subject: [PATCH] add summernote uploader --- .../views/crud/fields/summernote.blade.php | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/resources/views/crud/fields/summernote.blade.php b/src/resources/views/crud/fields/summernote.blade.php index ad04ba173a..81beec2397 100644 --- a/src/resources/views/crud/fields/summernote.blade.php +++ b/src/resources/views/crud/fields/summernote.blade.php @@ -13,6 +13,9 @@ name="{{ $field['name'] }}" data-init-function="bpFieldInitSummernoteElement" data-options="{{ json_encode($field['options']) }}" + data-upload-enabled="{{ isset($field['withFiles']) || isset($field['withMedia']) || isset($field['imageUploadEndpoint']) ? 'true' : 'false'}}" + data-upload-endpoint="{{ isset($field['imageUploadEndpoint']) ? $field['imageUploadEndpoint'] : 'false'}}" + data-upload-operation="{{ $crud->get('ajax-upload.formOperation') }}" bp-field-main-input @include('crud::fields.inc.attributes', ['default_class' => 'form-control summernote']) >{{ old_empty_or_null($field['name'], '') ?? $field['value'] ?? $field['default'] ?? '' }} @@ -54,7 +57,59 @@ function bpFieldInitSummernoteElement(element) { let summernotCallbacks = { onChange: function(contents, $editable) { element.val(contents).trigger('change'); + }, + } + + if(element.data('upload-enabled') === true){ + let imageUploadEndpoint = element.data('upload-endpoint') !== false ? element.data('upload-endpoint') : '{{ url($crud->route. '/ajax-upload') }}'; + let paramName = typeof element.attr('data-repeatable-input-name') !== 'undefined' ? element.closest('[data-repeatable-identifier]').attr('data-repeatable-identifier')+'#'+element.attr('data-repeatable-input-name') : element.attr('name'); + summernotCallbacks.onImageUpload = function(file) { + var data = new FormData(); + data.append(paramName, file[0]); + data.append('_token', document.querySelector('meta[name="csrf-token"]').getAttribute('content')); + data.append('fieldName', paramName); + data.append('operation', element.data('upload-operation')); + + var xhr = new XMLHttpRequest(); + xhr.open('POST', imageUploadEndpoint, true); + xhr.setRequestHeader('Accept', 'application/json'); + + xhr.onload = function() { + if (xhr.status >= 200 && xhr.status < 300) { + var response = JSON.parse(xhr.responseText); + element.summernote('insertImage', response.data.filePath); + } else { + var response = JSON.parse(xhr.responseText); + let errorBagName = paramName; + // it's in a repeatable field + if(errorBagName.includes('#')) { + errorBagName = errorBagName.replace('#', '.0.'); + } + let errorMessages = typeof response.errors !== 'undefined' ? response.errors[errorBagName].join('
') : response + '
'; + + let summernoteTextarea = element[0]; + + // remove previous error messages + summernoteTextarea.parentNode.querySelector('.invalid-feedback')?.remove(); + + // add the red text classes + summernoteTextarea.parentNode.classList.add('text-danger'); + + // create the error message container + let errorContainer = document.createElement("div"); + errorContainer.classList.add('invalid-feedback', 'd-block'); + errorContainer.innerHTML = errorMessages; + summernoteTextarea.parentNode.appendChild(errorContainer); + } + }; + + xhr.onerror = function() { + console.error('An error occurred during the upload process'); + }; + + xhr.send(data); } + } element.on('CrudField:disable', function(e) {