Added the ability to upload pictures in the editor.
This commit is contained in:
@@ -1,23 +1,114 @@
|
||||
@php
|
||||
$tinyId = \Illuminate\Support\Str::random(7);
|
||||
$tinyId = 'form-textarea-wysiwyg-' . $tinyId;
|
||||
|
||||
$images = [];
|
||||
$files = [];
|
||||
/** @var \App\Dto\View\Volt\Form\WysiwygStorageUpload | null $storageUpload */
|
||||
if ($storageUpload !== null) {
|
||||
$storages = old($storageUpload->getRequestInputName(), []);
|
||||
$images = $storages['content_images'] ?? [];
|
||||
}
|
||||
@endphp
|
||||
<div class="mb-3">
|
||||
<label for="form-textarea-wysiwyg-{{ $requestName }}">{{ $title }}</label>
|
||||
<textarea class="form-control {{ $attributes->get('class') }} textarea-tinymce @error($requestName) is-invalid @enderror" name="{{ $name }}" id="form-textarea-wysiwyg-{{ $requestName }}" rows="3">{{ $value }}</textarea>
|
||||
<label for="{{ $tinyId }}">{{ $title }}</label>
|
||||
<textarea class="form-control {{ $attributes->get('class') }} textarea-tinymce @error($requestName) is-invalid @enderror" name="{{ $name }}" id="{{ $tinyId }}" rows="3">{{ $value }}</textarea>
|
||||
@foreach($images as $image)
|
||||
@continue( empty($image['file']) )
|
||||
<input type="hidden" value="{{ $image['file'] }}" name="{{ $storageUpload->getInputName() }}[content_images][][file]';">
|
||||
@endforeach
|
||||
@error($requestName)
|
||||
<span class="invalid-feedback">{{ $message }}</span>
|
||||
<span class="invalid-feedback">{{ $message }}</span>
|
||||
@enderror
|
||||
</div>
|
||||
@pushOnce('scripts')
|
||||
<script src="{{ asset('/build/tinymce/tinymce.min.js') }}" referrerpolicy="origin"></script>
|
||||
@include('admin._scripts._tinymce')
|
||||
@push('scripts')
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
@if($storageUpload !== null)
|
||||
const textarea = document.querySelector('#{{ $tinyId }}');
|
||||
if (!textarea) {
|
||||
return;
|
||||
}
|
||||
|
||||
const storageImageType = '{{ \App\Enums\StorageType::ContentImages->value }}';
|
||||
const morph = '{{ $storageUpload->getMorph()->value }}';
|
||||
const storageInputName = '{{ $storageUpload->getInputName() }}';
|
||||
|
||||
const imageUpload = (blobInfo, progress) => new Promise((resolve, reject) => {
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.withCredentials = false;
|
||||
xhr.open('POST', '{{ route('storage.image_upload_and_resize') }}');
|
||||
|
||||
xhr.upload.onprogress = (e) => {
|
||||
progress(e.loaded / e.total * 100);
|
||||
};
|
||||
|
||||
xhr.onload = () => {
|
||||
if (xhr.status === 422) {
|
||||
const json = JSON.parse(xhr.responseText);
|
||||
let error = 'Error:<br><br>';
|
||||
for (let key of Object.keys(json.errors)) {
|
||||
error += json.errors[key] + '<br><br>';
|
||||
}
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (xhr.status === 403) {
|
||||
reject({ message: 'HTTP Error: ' + xhr.status, remove: true });
|
||||
return;
|
||||
}
|
||||
|
||||
if (xhr.status < 200 || xhr.status >= 300) {
|
||||
reject('HTTP Error: ' + xhr.status);
|
||||
return;
|
||||
}
|
||||
|
||||
const json = JSON.parse(xhr.responseText);
|
||||
|
||||
if (!json || typeof json.url != 'string') {
|
||||
reject('Invalid JSON: ' + xhr.responseText);
|
||||
return;
|
||||
}
|
||||
|
||||
let input = document.createElement('input');
|
||||
input.type = 'hidden';
|
||||
input.name = storageInputName + '[content_images][][file]';
|
||||
input.value = json.id;
|
||||
|
||||
textarea.after(input);
|
||||
|
||||
resolve(json.url);
|
||||
};
|
||||
|
||||
xhr.onerror = () => {
|
||||
reject('Image upload failed due to a XHR Transport error. Code: ' + xhr.status);
|
||||
};
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('file', blobInfo.blob(), blobInfo.filename());
|
||||
formData.append('_token', document.querySelector('meta[name="csrf-token"]').content);
|
||||
formData.append('storage_type', storageImageType);
|
||||
formData.append('morph', morph);
|
||||
|
||||
xhr.send(formData);
|
||||
});
|
||||
@endif
|
||||
tinymce.init({
|
||||
selector: '.textarea-tinymce',
|
||||
selector: '#{{ $tinyId }}',
|
||||
@if(in_array(app()->getLocale(), ['ru'], true))
|
||||
language: '{{ app()->getLocale() }}',
|
||||
@endif
|
||||
license_key: '{{ $tinymceLicenseKey }}',
|
||||
plugins: 'advlist code emoticons link lists table codesample',
|
||||
toolbar: 'bold italic | bullist numlist | link emoticons codesample',
|
||||
plugins: 'advlist code emoticons link lists table codesample media my-image',
|
||||
toolbar: 'bold italic | bullist numlist | link image emoticons media codesample',
|
||||
referrer_policy: 'origin',
|
||||
@if($storageUpload !== null)
|
||||
images_upload_handler: imageUpload,
|
||||
@endif
|
||||
relative_urls: false,
|
||||
convert_urls: false,
|
||||
codesample_global_prismjs: true,
|
||||
codesample_languages: [
|
||||
{text: 'HTML/XML', value: 'markup'},
|
||||
@@ -33,11 +124,11 @@
|
||||
{text: 'Go', value: 'go'},
|
||||
{text: 'Nginx', value: 'nginx'},
|
||||
{text: 'Docker', value: 'docker'},
|
||||
{text: 'Yaml', value: 'yaml'},
|
||||
{text: "Treeview", value: "treeview"},
|
||||
{text: "Diff", value: "diff"},
|
||||
],
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@include('_prism')
|
||||
@endpushonce
|
||||
@endpush
|
||||
|
Reference in New Issue
Block a user