204 lines
8.6 KiB
PHP
204 lines
8.6 KiB
PHP
@props([
|
|
'name' => 'thumbnail',
|
|
'label' => 'Thumbnail',
|
|
'value' => null,
|
|
'placeholder' => 'Chọn File',
|
|
'required' => false,
|
|
'horizontal' => true,
|
|
'labelClass' => 'col-md-3 text-right',
|
|
'inputClass' => 'col-md-9',
|
|
])
|
|
|
|
@php
|
|
$uniqueId = 'image-picker-' . uniqid();
|
|
$currentValue = old($name) ?? $value;
|
|
@endphp
|
|
|
|
@if ($horizontal)
|
|
<div class="row form-group align-items-center mb-0">
|
|
<label for="{{ $name }}" class="{{ $labelClass }}">
|
|
{{ $label }}
|
|
@if ($required)
|
|
<span class="text-danger">*</span>
|
|
@endif
|
|
</label>
|
|
<div class="{{ $inputClass }} p-1">
|
|
@else
|
|
<div class="form-group mb-3">
|
|
<label for="{{ $name }}" class="mb-2">
|
|
{{ $label }}
|
|
@if ($required)
|
|
<span class="text-danger">*</span>
|
|
@endif
|
|
</label>
|
|
<div>
|
|
@endif
|
|
<div class="row">
|
|
<div class="col-md-8 bg-customer">
|
|
<input type="text" id="{{ $uniqueId }}-input" name="{{ $name }}" value="{{ $currentValue }}"
|
|
class="form-control image-picker-input" placeholder="{{ $placeholder }}"
|
|
data-picker-id="{{ $uniqueId }}" @if ($required) required @endif>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<button type="button" class="btn btn-outline-secondary btn-open-image-picker"
|
|
data-picker-id="{{ $uniqueId }}">
|
|
<i data-lucide="folder-open" class="w-14px h-14px me-1"></i> Chọn hình ảnh
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Image Preview --}}
|
|
<div class="mt-2" id="{{ $uniqueId }}-preview-wrapper" style="display: {{ $currentValue ? 'block' : 'none' }};">
|
|
<div class="position-relative d-inline-block">
|
|
<div id="{{ $uniqueId }}-preview-container"
|
|
class="img-thumbnail bg-light d-flex align-items-center justify-content-center"
|
|
style="max-width: 200px; max-height: 150px; min-width: 100px; min-height: 80px; cursor: pointer; overflow: hidden;"
|
|
data-bs-toggle="modal" data-bs-target="#{{ $uniqueId }}-modal">
|
|
@if ($currentValue)
|
|
@if (str_ends_with(strtolower($currentValue), '.svg'))
|
|
<object data="{{ $currentValue }}" type="image/svg+xml"
|
|
style="max-width: 100%; max-height: 150px; width: auto; height: auto;">
|
|
<img src="{{ $currentValue }}" alt="Preview" style="max-width: 100%; max-height: 150px;">
|
|
</object>
|
|
@else
|
|
<img src="{{ $currentValue }}" alt="Preview"
|
|
style="max-width: 100%; max-height: 150px; object-fit: contain;">
|
|
@endif
|
|
@endif
|
|
</div>
|
|
<button type="button" class="btn btn-sm btn-danger position-absolute btn-remove-image end-0 top-0"
|
|
data-picker-id="{{ $uniqueId }}" style="transform: translate(50%, -50%);">
|
|
<i data-lucide="x" class="w-12px h-12px"></i>
|
|
</button>
|
|
</div>
|
|
<small class="text-muted d-block mt-1">Click vào ảnh để xem phóng to</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Image Preview Modal --}}
|
|
<div class="modal fade" id="{{ $uniqueId }}-modal" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog modal-lg modal-dialog-centered">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">
|
|
<i data-lucide="image" class="w-18px h-18px me-2"></i>
|
|
Preview Image
|
|
</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body bg-light p-3 text-center">
|
|
<div id="{{ $uniqueId }}-modal-container" class="d-flex align-items-center justify-content-center"
|
|
style="min-height: 300px;">
|
|
@if ($currentValue)
|
|
@if (str_ends_with(strtolower($currentValue), '.svg'))
|
|
<object data="{{ $currentValue }}" type="image/svg+xml"
|
|
style="max-width: 100%; max-height: 70vh; width: auto; height: auto;">
|
|
<img src="{{ $currentValue }}" alt="Full Preview"
|
|
style="max-width: 100%; max-height: 70vh;">
|
|
</object>
|
|
@else
|
|
<img src="{{ $currentValue }}" alt="Full Preview" class="img-fluid"
|
|
style="max-height: 70vh;">
|
|
@endif
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
@pushOnce('custom-scripts')
|
|
<script>
|
|
$(document).ready(function() {
|
|
// Prevent multiple initializations
|
|
if (window.imagePickerInitialized) return;
|
|
window.imagePickerInitialized = true;
|
|
|
|
// Function to check if file is SVG
|
|
function isSvg(url) {
|
|
return url && url.toLowerCase().endsWith('.svg');
|
|
}
|
|
|
|
// Function to update preview
|
|
function updateImagePreview(pickerId, url) {
|
|
const $wrapper = $(`#${pickerId}-preview-wrapper`);
|
|
const $container = $(`#${pickerId}-preview-container`);
|
|
const $modalContainer = $(`#${pickerId}-modal-container`);
|
|
|
|
if (url && url.trim() !== '') {
|
|
if (isSvg(url)) {
|
|
$container.html(`
|
|
<object data="${url}" type="image/svg+xml"
|
|
style="max-width: 100%; max-height: 150px; width: auto; height: auto;">
|
|
<img src="${url}" alt="Preview" style="max-width: 100%; max-height: 150px;">
|
|
</object>
|
|
`);
|
|
$modalContainer.html(`
|
|
<object data="${url}" type="image/svg+xml"
|
|
style="max-width: 100%; max-height: 70vh; width: auto; height: auto;">
|
|
<img src="${url}" alt="Full Preview" style="max-width: 100%; max-height: 70vh;">
|
|
</object>
|
|
`);
|
|
} else {
|
|
$container.html(`
|
|
<img src="${url}" alt="Preview" style="max-width: 100%; max-height: 150px; object-fit: contain;">
|
|
`);
|
|
$modalContainer.html(`
|
|
<img src="${url}" alt="Full Preview" class="img-fluid" style="max-height: 70vh;">
|
|
`);
|
|
}
|
|
$wrapper.slideDown(200);
|
|
|
|
// Reinitialize Lucide icons
|
|
if (typeof lucide !== 'undefined') {
|
|
lucide.createIcons();
|
|
}
|
|
} else {
|
|
$wrapper.slideUp(200);
|
|
}
|
|
}
|
|
|
|
// Listen for input changes
|
|
$(document).on('input change', '.image-picker-input', function() {
|
|
const pickerId = $(this).data('picker-id');
|
|
updateImagePreview(pickerId, $(this).val());
|
|
});
|
|
|
|
// Remove image button
|
|
$(document).on('click', '.btn-remove-image', function(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
const pickerId = $(this).data('picker-id');
|
|
const $input = $(`#${pickerId}-input`);
|
|
$input.val('');
|
|
$(`#${pickerId}-preview-wrapper`).slideUp(200);
|
|
});
|
|
|
|
// Open CKFinder popup
|
|
$(document).on('click', '.btn-open-image-picker', function() {
|
|
const pickerId = $(this).data('picker-id');
|
|
const $input = $(`#${pickerId}-input`);
|
|
|
|
if (typeof CKFinder !== 'undefined') {
|
|
CKFinder.popup({
|
|
connectorPath: '{{ route('ckfinder_connector') }}',
|
|
chooseFiles: true,
|
|
width: 800,
|
|
height: 600,
|
|
onInit: function(finder) {
|
|
finder.on('files:choose', function(evt) {
|
|
const fileUrl = evt.data.files.first().getUrl();
|
|
$input.val(fileUrl).trigger('input');
|
|
});
|
|
}
|
|
});
|
|
} else {
|
|
console.error('CKFinder is not loaded');
|
|
alert('CKFinder chưa được tải. Vui lòng thử lại.');
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
@endPushOnce
|