401 lines
19 KiB
Smarty
401 lines
19 KiB
Smarty
<script type="text/javascript" language="JavaScript">
|
||
var COMMENT_ADM_FILE_MAX_LIM = '{#COMMENT_ADM_FILE_MAX_LIM#}';
|
||
var COMMENT_ADM_FILE_MAX_LIM_A = '{#COMMENT_ADM_FILE_MAX_LIM_A#}';
|
||
var COMMENT_ADM_FILE_MAX_LIM_B = '{#COMMENT_ADM_FILE_MAX_LIM_B#}';
|
||
var COMMENT_ADM_FILE_MAX_LIM_C = '{#COMMENT_ADM_FILE_MAX_LIM_C#}';
|
||
var COMMENT_ADM_FILE_MAX_LIM_D = '{#COMMENT_ADM_FILE_MAX_LIM_D#}';
|
||
|
||
{literal}
|
||
$(document).ready(function(){
|
||
// Инициализация параметров из Smarty
|
||
var maxFiles = {/literal}{$row.comment_max_files|default:5}{literal};
|
||
var maxFileSize = {/literal}{$row.comment_max_file_size|default:2048}{literal} * 1024;
|
||
var allowedExts = {/literal}'{$row.comment_allowed_extensions|default:"jpg,jpeg,png,gif,webp"}'{literal}.split(',');
|
||
var existingFilesCount = {/literal}{$row.file_list|@count|default:0}{literal};
|
||
var dt = new DataTransfer();
|
||
|
||
var left = {/literal}{$comment_max_chars|default:1000}{literal};
|
||
$('#text_counter').text(left);
|
||
|
||
// Счетчик символов в текстовом поле
|
||
$('#in_message').on('keyup change', function () {
|
||
left = {/literal}{$comment_max_chars|default:1000}{literal} - $(this).val().length;
|
||
$('#text_counter').toggleClass("overlimit", left < 0).text(left);
|
||
});
|
||
|
||
// Универсальная функция для вывода предупреждений в админке
|
||
function showFileAlert(message, $container) {
|
||
$container.find('.file-limit-alert').remove(); // Удаляем старые, если есть
|
||
|
||
var alertHtml = `
|
||
<div class="file-limit-alert alert alert-warning py-1 px-2 mb-2 small d-flex align-items-center border-0 shadow-sm"
|
||
style="background: #fff3cd; color: #856404; border-left: 4px solid #ffeeba !important; margin-bottom: 10px; position: relative;">
|
||
<i class="bi bi-exclamation-triangle-fill me-2"></i>
|
||
<span>${message}</span>
|
||
</div>`;
|
||
|
||
$container.prepend(alertHtml);
|
||
|
||
// Плавное удаление через 5 секунд
|
||
setTimeout(function() {
|
||
$container.find('.file-limit-alert').fadeOut(500, function() { $(this).remove(); });
|
||
}, 5000);
|
||
}
|
||
|
||
// Проверки файлов и генерация превью "на лету"
|
||
$('input[name="comment_image[]"]').on('change', function() {
|
||
var $input = $(this);
|
||
var files = this.files;
|
||
var $previewContainer = $('#new_images_preview');
|
||
var $uploadBox = $input.closest('.upload-info-box');
|
||
|
||
//$previewContainer.empty();
|
||
|
||
var deletedCount = $('input[name="delete_files[]"]:checked').length;
|
||
var currentTotal = existingFilesCount - deletedCount;
|
||
|
||
// Проверка общего лимита количества
|
||
if ((currentTotal + files.length) > maxFiles) {
|
||
showFileAlert(COMMENT_ADM_FILE_MAX_LIM + maxFiles + COMMENT_ADM_FILE_MAX_LIM_A, $uploadBox);
|
||
$input.val('');
|
||
return false;
|
||
}
|
||
|
||
// Пофайловая проверка (Формат и Размер)
|
||
var hasError = false;
|
||
$.each(files, function(i, file) {
|
||
var ext = file.name.split('.').pop().toLowerCase();
|
||
|
||
if ($.inArray(ext, allowedExts) == -1) {
|
||
showFileAlert(COMMENT_ADM_FILE_MAX_LIM_B + "<b>." + ext + "</b>" + COMMENT_ADM_FILE_MAX_LIM_C, $uploadBox);
|
||
hasError = true;
|
||
return false;
|
||
}
|
||
|
||
if (file.size > maxFileSize) {
|
||
showFileAlert(COMMENT_ADM_FILE_MAX_LIM_D + (file.size/1024).toFixed(1) + " KB", $uploadBox);
|
||
hasError = true;
|
||
return false;
|
||
}
|
||
|
||
var fileIndex = dt.items.length;
|
||
dt.items.add(file);
|
||
// Если ошибок нет, читаем превью (FileReader)
|
||
var reader = new FileReader();
|
||
reader.onload = function(e) {
|
||
var isImg = ['jpg','jpeg','png','gif','webp'].indexOf(ext) !== -1;
|
||
var content = isImg
|
||
? '<img src="' + e.target.result + '">'
|
||
: '<div class="ext-placeholder">' + ext + '</div>';
|
||
|
||
var html = `
|
||
<div class="new-file-preview" id="nf_${fileIndex}">
|
||
<div class="cancel-new-file" onclick="removeSelectedFile(${fileIndex})">×</div>
|
||
${content}
|
||
<span class="file-name-label">${file.name}</span>
|
||
</div>`;
|
||
$previewContainer.append(html);
|
||
};
|
||
reader.readAsDataURL(file);
|
||
});
|
||
|
||
if (hasError) {
|
||
this.value = "";
|
||
dt = new DataTransfer();
|
||
$previewContainer.empty();
|
||
} else {
|
||
this.files = dt.files;
|
||
}
|
||
});
|
||
|
||
// Логика Авторского рейтинга (звезды)
|
||
$('.rating-star').click(function() {
|
||
var val = $(this).data('value');
|
||
$('#user_rating_input').val(val);
|
||
$('.rating-star').each(function() {
|
||
$(this).toggleClass('active', $(this).data('value') <= val);
|
||
});
|
||
});
|
||
|
||
$('.reset-rating').click(function() {
|
||
$('#user_rating_input').val(0);
|
||
$('.rating-star').removeClass('active');
|
||
});
|
||
|
||
// Удаление существующих файлов (клик по крестику)
|
||
$('.del-file-btn').on('click', function(e) {
|
||
e.preventDefault(); // Предотвращаем стандартное поведение
|
||
var $checkbox = $(this).find('input[type="checkbox"]');
|
||
var isChecked = !$checkbox.prop('checked');
|
||
|
||
$checkbox.prop('checked', isChecked);
|
||
|
||
var $item = $(this).closest('.file-preview-item');
|
||
if (isChecked) {
|
||
$item.find('.file-thumb, .ext-placeholder').css({'opacity': '0.3', 'filter': 'grayscale(1)'});
|
||
$(this).css('background', '#000');
|
||
} else {
|
||
$item.find('.file-thumb, .ext-placeholder').css({'opacity': '1', 'filter': 'none'});
|
||
$(this).css('background', '#dc3545');
|
||
}
|
||
});
|
||
|
||
// Отправка формы через AJAX с прогресс-баром
|
||
$(".SaveCommentAjax").on('click', function(e){
|
||
e.preventDefault();
|
||
var $btn = $(this);
|
||
|
||
$("#comment_edit_form").ajaxSubmit({
|
||
url: 'index.php?ajax=1&onlycontent=1&cp={/literal}{$sess}{literal}',
|
||
type: 'POST',
|
||
dataType: 'json',
|
||
beforeSubmit: function(){
|
||
$btn.attr('disabled', true);
|
||
$('#comment-upload-progress').show();
|
||
},
|
||
uploadProgress: function(event, position, total, percentComplete) {
|
||
$('#upload-bar-fill').css('width', percentComplete + '%').text(percentComplete + '%');
|
||
},
|
||
success: function(data){
|
||
$.jGrowl(data['message'], { header: data['header'], theme: data['theme'] });
|
||
if (data['theme'] !== 'error') {
|
||
// Короткая задержка перед релоадом, чтобы юзер увидел 100% полосы загрузки и jGrowl
|
||
setTimeout(function() {
|
||
if (window.parent) window.parent.location.reload();
|
||
}, 900);
|
||
} else {
|
||
$btn.attr('disabled', false);
|
||
$('#comment-upload-progress').hide();
|
||
}
|
||
},
|
||
error: function() {
|
||
alert("Ошибка при сохранении данных.");
|
||
$btn.attr('disabled', false);
|
||
$('#comment-upload-progress').hide();
|
||
}
|
||
});
|
||
});
|
||
|
||
// Закрытие диалогового окна
|
||
var dialogId = '#ajax-dialog-edit-comment-{/literal}{$smarty.request.Id|escape}{literal}';
|
||
$(".CloseCommentDialog").on('click', function(e){
|
||
e.preventDefault();
|
||
$(dialogId).dialog('destroy').remove();
|
||
});
|
||
|
||
// Функция сброса новых файлов (вызывается крестиком на новом превью)
|
||
window.resetNewFiles = function() {
|
||
$('input[name="comment_image[]"]').val('');
|
||
$('#new_images_preview').empty();
|
||
};
|
||
window.removeSelectedFile = function(idx) {
|
||
var newDt = new DataTransfer();
|
||
for (var i = 0; i < dt.files.length; i++) {
|
||
if (i !== idx) newDt.items.add(dt.files[i]);
|
||
}
|
||
dt = newDt;
|
||
$('input[name="comment_image[]"]')[0].files = dt.files;
|
||
$('#nf_' + idx).remove();
|
||
};
|
||
});
|
||
{/literal}
|
||
</script>
|
||
|
||
<style>
|
||
{literal}
|
||
/* Возврат системных шрифтов и размеров */
|
||
.widget.first, .widget.first table { font-size: 12px !important; font-family: Tahoma, Arial, sans-serif !important; color: #333; }
|
||
|
||
.tableStatic td { padding: 8px 10px !important; vertical-align: middle; }
|
||
|
||
/* ИНПУТЫ: Высота и Шрифт */
|
||
.tableStatic input[type="text"] {
|
||
height: 30px !important;
|
||
line-height: 30px !important;
|
||
font-size: 13px !important;
|
||
padding: 0 8px !important;
|
||
border: 1px solid #ccc;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
/* ТЕКСТОВОЕ ПОЛЕ */
|
||
.tableStatic textarea {
|
||
height: 140px !important;
|
||
font-size: 13px !important;
|
||
padding: 8px !important;
|
||
border: 1px solid #ccc;
|
||
box-sizing: border-box;
|
||
line-height: 1.5;
|
||
}
|
||
|
||
/* Рейтинг */
|
||
.rating-area { display: flex; align-items: center; gap: 5px; height: 30px; }
|
||
.rating-star { color: #ccc; cursor: pointer; font-size: 26px; line-height: 1; }
|
||
.rating-star.active { color: #ffc107; }
|
||
.reset-rating { cursor: pointer; color: #dc3545; margin-left: 10px; font-weight: bold; font-size: 16px; }
|
||
|
||
/* Файлы */
|
||
.file-preview-item { position: relative; display: inline-block; margin: 0 10px 10px 0; width: 60px; text-align: center; }
|
||
.file-thumb { width: 60px; height: 60px; object-fit: cover; border-radius: 4px; border: 1px solid #ccc; }
|
||
.ext-placeholder { width: 60px; height: 60px; background: #0d6efd; color: #fff; display: flex; align-items: center; justify-content: center; font-weight: bold; border-radius: 4px; text-transform: uppercase; font-size: 11px; }
|
||
.del-file-btn { position: absolute; top: -5px; right: -5px; background: #dc3545; color: #fff; border-radius: 50%; width: 18px; height: 18px; cursor: pointer; line-height: 17px; text-align: center; font-size: 12px; border: 1px solid #fff; z-index: 10; }
|
||
.del-file-btn input { display: none; }
|
||
.file-name-label { display: block; font-size: 10px; color: #666; margin-top: 3px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
|
||
|
||
/* Прогресс-бар */
|
||
#comment-upload-progress { display: none; width: 100%; background: #eee; height: 16px; border-radius: 3px; margin: 10px 0; border: 1px solid #ccc; }
|
||
#upload-bar-fill { height: 100%; background: #28a745; color: #fff; font-size: 10px; text-align: center; line-height: 16px; width: 0; }
|
||
|
||
.upload-info-box { margin-top:10px; padding: 10px; border: 1px dashed #ccc; background: #fcfcfc; }
|
||
.overlimit { color: #dc3545; font-weight: bold; }
|
||
|
||
/* Стили для новых превью */
|
||
.new-file-preview { position: relative; width: 60px; text-align: center; }
|
||
.new-file-preview img { width: 60px; height: 60px; object-fit: cover; border-radius: 4px; border: 1px solid #0d6efd; }
|
||
.new-file-preview .ext-placeholder { background: #0d6efd; } /* Синий цвет для новых файлов */
|
||
|
||
/* Кнопка отмены для НОВОГО файла */
|
||
.cancel-new-file {
|
||
position: absolute; top: -5px; right: -5px; background: #000; color: #fff;
|
||
border-radius: 50%; width: 18px; height: 18px; cursor: pointer;
|
||
line-height: 17px; text-align: center; font-size: 12px; border: 1px solid #fff; z-index: 11;
|
||
}
|
||
|
||
.file-limit-alert {
|
||
transition: opacity 0.5s ease-in-out;
|
||
animation: slideDown 0.3s ease-out;
|
||
border-radius: 4px;
|
||
font-family: Tahoma, sans-serif;
|
||
line-height: 1.4;
|
||
z-index: 5;
|
||
}
|
||
.file-limit-alert i {
|
||
font-style: normal;
|
||
font-weight: bold;
|
||
margin-right: 5px;
|
||
}
|
||
@keyframes slideDown {
|
||
from { transform: translateY(-10px); opacity: 0; }
|
||
to { transform: translateY(0); opacity: 1; }
|
||
}
|
||
{/literal}
|
||
</style>
|
||
|
||
<div class="widget first">
|
||
{if $editfalse == 1}
|
||
<div class="body">{#COMMENT_EDIT_FALSE#}</div>
|
||
{else}
|
||
<form method="post" id="comment_edit_form" enctype="multipart/form-data">
|
||
<table cellpadding="0" cellspacing="0" width="100%" class="tableStatic">
|
||
<col width="150">
|
||
|
||
<tr>
|
||
<td>{#COMMENT_YOUR_NAME#}*</td>
|
||
<td><input name="comment_author_name" type="text" style="width:300px" value="{$row.comment_author_name|stripslashes|escape}" /></td>
|
||
</tr>
|
||
<tr>
|
||
<td>{#COMMENT_YOUR_EMAIL#}*</td>
|
||
<td><input name="comment_author_email" type="text" style="width:300px" value="{$row.comment_author_email|stripslashes|escape}" /></td>
|
||
</tr>
|
||
|
||
{* Поле F1 - Город *}
|
||
{if $row.comment_show_f1 == 1}
|
||
<tr>
|
||
<td>
|
||
{if $row.comment_name_f1}{$row.comment_name_f1|stripslashes|escape}{else}{#COMMENT_YOUR_FROM#}{/if}
|
||
</td>
|
||
<td><input name="comment_author_city" type="text" style="width:300px" value="{$row.comment_author_city|stripslashes|escape}" /></td>
|
||
</tr>
|
||
{/if}
|
||
|
||
{* Поле F2 - Веб-сайт *}
|
||
{if $row.comment_show_f2 == 1}
|
||
<tr>
|
||
<td>
|
||
{if $row.comment_name_f2}{$row.comment_name_f2|stripslashes|escape}{else}{#COMMENT_YOUR_SITE#}{/if}
|
||
</td>
|
||
<td><input name="comment_author_website" type="text" style="width:300px" value="{$row.comment_author_website|stripslashes|escape}" /></td>
|
||
</tr>
|
||
{/if}
|
||
|
||
{if $row.comment_show_user_rating == 1}
|
||
<tr>
|
||
<td>{#COMMENT_RATING_TITEL#}</td>
|
||
<td>
|
||
<div class="rating-area">
|
||
<input type="hidden" name="user_rating" id="user_rating_input" value="{$row.user_rating|default:0}">
|
||
{section name=r start=1 loop=6}
|
||
<span class="rating-star {if $row.user_rating >= $smarty.section.r.index}active{/if}" data-value="{$smarty.section.r.index}">★</span>
|
||
{/section}
|
||
<span class="reset-rating" title="{#COMMENT_RATING_RESET#}">×</span><span>{#COMMENT_RATING_RESET#}</span>
|
||
{* Проверка разрешения на редактирование *}
|
||
{if $edit_rating_enabled == 0}
|
||
<span style="color: #dc3545; font-size: 11px; margin-left: 15px; font-weight: bold;">
|
||
(Редактирование Авторской оценки отключено)
|
||
</span>
|
||
{/if}
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
{/if}
|
||
|
||
<tr>
|
||
<td>{#COMMENT_FILES#}</td>
|
||
<td>
|
||
<div id="image_preview_wrapper">
|
||
{foreach from=$row.file_list item=file}
|
||
{assign var="fileExt" value=$file|substr:-3|lower}
|
||
<div class="file-preview-item">
|
||
<label class="del-file-btn" title="Удалить">×<input type="checkbox" name="delete_files[]" value="{$file}"></label>
|
||
{if $fileExt == 'jpg' || $fileExt == 'png' || $fileExt == 'gif' || $fileExt == 'ebp' || $fileExt == 'peg'}
|
||
<img src="{$ABS_PATH}uploads/comments/{$file}" class="file-thumb">
|
||
{else}
|
||
<div class="ext-placeholder">{$fileExt}</div>
|
||
{/if}
|
||
<span class="file-name-label">{$file|regex_replace:"/_[0-9]+(?=\.[a-z0-9]+$)/i":""}</span>
|
||
</div>
|
||
{/foreach}
|
||
</div>
|
||
{* превью новых только что загруженных файлов *}
|
||
<div id="new_images_preview" style="display: flex; flex-wrap: wrap; gap: 10px; margin-top: 10px;"></div>
|
||
{if $row.comment_allow_files == 1}
|
||
<div class="upload-info-box">
|
||
<input type="file" name="comment_image[]" multiple />
|
||
<div style="font-size:10px; color:#888; margin-top:5px;">
|
||
{#COMMENT_ADD_FILES_ALLOW#} {$row.comment_allowed_extensions} ({#COMMENT_ADD_FILES_MAX_COUNT#} {$row.comment_max_files} {#COMMENT_ADD_FILES_COUNT_PIC#} | {#COMMENT_ADD_FILES_MAX_SIZE#} {$row.comment_max_file_size} {#COMMENT_ADD_FILES_SIZE#})
|
||
</div>
|
||
</div>
|
||
{/if}
|
||
</td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td>{#COMMENT_YOUR_TEXT#}*</td>
|
||
<td>
|
||
<textarea style="width:100%" name="comment_text" id="in_message">{$row.comment_text|stripslashes}</textarea>
|
||
<div style="text-align:right; font-size:11px; color:#999; margin-top:5px;">
|
||
{#COMMENT_CHARS_LEFT#} <span id="text_counter"></span>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
|
||
<input type="hidden" name="do" value="modules" />
|
||
<input type="hidden" name="action" value="modedit" />
|
||
<input type="hidden" name="mod" value="comment" />
|
||
<input type="hidden" name="moduleaction" value="admin_edit" />
|
||
<input type="hidden" name="sub" value="send" />
|
||
<input type="hidden" name="Id" value="{$smarty.request.Id|escape}" />
|
||
|
||
<tr>
|
||
<td colspan="2">
|
||
<div id="comment-upload-progress"><div id="upload-bar-fill"></div></div>
|
||
<div style="padding:15px 0;">
|
||
<input type="submit" class="basicBtn SaveCommentAjax" value="{#COMMENT_BUTTON_EDIT#}" />
|
||
<a href="javascript:void(0);" class="button redBtn CloseCommentDialog">{#COMMENT_BUTTON_CANCEL#}</a>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</form>
|
||
{/if}
|
||
</div> |