Добавлен функционал массовых действий с историей: удаление, изменение статусов

This commit is contained in:
2025-09-26 16:35:56 +05:00
parent ad509bc3b1
commit d8b505c5fa
2 changed files with 214 additions and 2 deletions

View File

@@ -71,6 +71,7 @@ edit = "Редактировать"
copy = "Копировать"
delete = "Удалить"
actions = "Действия"
actions_sel = "Действия с выбранными"
saved = "Сохранено"
notsaved = "Во время сохранения произошла ошибка"
created = "Форма успешно создана"
@@ -78,6 +79,7 @@ copied = "Форма успешно скопирована и сохранен
deleting = "Удаление..."
add_refresh = "Добавить и обновить"
save = "Сохранить"
save_changes = "Сохранить изменения"
return_to_forms = "Вернуться к списку форм"
refresh = "Обновить"
mail_set = "Настройки письма"
@@ -182,4 +184,9 @@ cn_copy_to_clipboard = "Скопировать в буфер обмена"
cn_return_list_form = "Вернуться к списку форм"
cn_mod_info = "Важно: модуль использует метод отправки почты установленный в системных настройках, в разделе "
cn_mod_info_a = "Настройки почты."
info_attr_name = "Атрибут <span style='color:#2474B0'>name</span> уже установлен и используется по умолчанию, его значение:"
info_attr_name = "Атрибут <span style='color:#2474B0'>name</span> уже установлен и используется по умолчанию, его значение:"
cn_select_for_action = "Выберите хотя бы один элемент"
cn_confirm_mass_del = "Вы уверены, что хотите удалить выбранные элементы?"
delete_error = "Ошибка удаления"
action_confirm_title = "Удаление истории"
action_error_title = "Действия в истории"

View File

@@ -11,6 +11,12 @@
$smarty = new Array;
$smarty['stat_replied'] = '{#stat_replied#}';
$smarty['stat_viewed'] = '{#stat_viewed#}';
$smarty['delete'] = '{#delete#}';
$smarty['cn_select_for_action'] = '{#cn_select_for_action#}';
$smarty['cn_confirm_mass_del'] = '{#cn_confirm_mass_del#}';
$smarty['delete_error'] = '{#delete_error#}';
$smarty['action_confirm_title'] = '{#action_confirm_title#}';
$smarty['action_error_title'] = '{#action_error_title#}';
</script>
<div class="title">
@@ -40,6 +46,7 @@ $smarty['stat_viewed'] = '{#stat_viewed#}';
</div>
<table cellpadding="0" cellspacing="0" width="100%" class="tableStatic mainForm" id="forms">
<colgroup>
<col width="10">
<col width="100"/>
<col/>
<col width="1"/>
@@ -48,6 +55,7 @@ $smarty['stat_viewed'] = '{#stat_viewed#}';
</colgroup>
<thead>
<tr>
<td><div align="center"><input type="checkbox" id="selectAll" value="1" /></div></td>
<td>{#date#}</td>
<td>{#mfld_subject#}</td>
<td>{#author#}</td>
@@ -58,6 +66,7 @@ $smarty['stat_viewed'] = '{#stat_viewed#}';
<tbody>
{foreach from=$dialogs item=dialog}
<tr class="{if $dialog.status==='new'}green{elseif $dialog.status==='viewed'}yellow{/if}">
<td nowrap="nowrap"><div><input name="form[{$dialog.id}]" type="checkbox" value="1" class="checkbox his-checkbox" /></div></td>
<td align="right" nowrap="nowrap">
<span class="date_text dgrey">{$dialog.date|date_format:$TIME_FORMAT|pretty_date}</span>
</td>
@@ -91,9 +100,36 @@ $smarty['stat_viewed'] = '{#stat_viewed#}';
</tr>
{/foreach}
</tbody>
{if $dialog}
<thead>
<tr>
<td></td>
<td>{#date#}</td>
<td>{#mfld_subject#}</td>
<td>{#author#}</td>
<td>{#status#}</td>
<td>{#cn_actions#}</td>
</tr>
</thead>
{/if}
</table>
{if $dialog}
<div class="rowElem" id="saveBtn">
<div class="saveBtn">
<select name="moderation" class="action-in-moderation">
<option value="none" selected="selected">{#actions_sel#}</option>
<option value="viewed">{#stat_viewed#}</option>
<option value="replied">{#stat_replied#}</option>
<option value="delete">{#delete#}</option>
</select>
&nbsp;&nbsp;<input type="button" class="basicBtn" value="{#save_changes#}" id="massActionButton" />
<script>// разукрашиваем select
$('select').styler({ldelim}selectSearch:false, selectVisibleOptions:5{rdelim});
</script>
</div>
</div>
{/if}
</div>
{if $page_nav}
<div class="pagination">
<ul class="pages">
@@ -134,4 +170,173 @@ function status_change (sel) {
});
};
</script>
{/literal}
{literal}
<script>
// =========================================================
// 1. ФУНКЦИЯ ДЛЯ СБРОСА ВСЕХ ВЫБРАННЫХ ЧЕКБОКСОВ ПОСЛЕ AJAX
// =========================================================
function resetAllCheckedHisCheckboxes() {
// 1. Сначала пытаемся сбросить через главный чекбокс, если он активен
var $selectAll = $('#selectAll');
if ($selectAll.prop('checked')) {
// Используем .click() для корректной работы с плагином стилизации
$selectAll.click();
}
// 2. Агрессивный сброс: Проходим по всем подчиненным элементам, которые могли остаться отмеченными
$('#forms tbody .his-checkbox:checked').each(function() {
var $checkbox = $(this);
// Вызываем click() для снятия отметки, если она еще стоит
$checkbox.click();
});
}
// =========================================================
// 2. ОБРАБОТЧИК КЛИКА ПО ГЛАВНОМУ ЧЕКБОКСУ (#selectAll)
// =========================================================
$(document).on('click', '#selectAll', function() {
var isChecked = $(this).prop('checked');
var $hisCheckboxes = $('#forms tbody .his-checkbox');
$hisCheckboxes.each(function() {
var $checkbox = $(this);
// Используем .click() для принудительного обновления стилизованного элемента
if ($checkbox.prop('checked') !== isChecked) {
$checkbox.click();
}
});
});
// =========================================================
// 3. ОБРАБОТЧИК КНОПКИ МАССОВОГО ДЕЙСТВИЯ (#massActionButton)
// =========================================================
$(document).on('click', '#massActionButton', function() {
var $selectElement = $('.action-in-moderation');
// Получаем значение, читая выбранный <option> (для обхода плагина стилизации)
var selectedAction = $selectElement.find('option:selected').val();
var $checkedRows = $('#forms tbody .his-checkbox:checked');
if ($checkedRows.length === 0) {
if (selectedAction !== 'none') {
jAlert($smarty['cn_select_for_action'], $smarty['action_error_title']); // "Выберите хотя бы один элемент"
}
return false;
}
// --- ЛОГИКА МАССОВОГО УДАЛЕНИЯ ---
if (selectedAction === 'delete') {
// 1. Подтверждение удаления через jConfirm
jConfirm($smarty['cn_confirm_mass_del'], $smarty['action_confirm_title'], function(r) {
if (r) {
var deletions = [];
// Сбор ID и визуальное удаление
$checkedRows.each(function() {
var $checkbox = $(this);
var nameAttr = $checkbox.attr('name');
var match = nameAttr.match(/form\[(\d+)\]/);
if (match && match[1]) {
var dialogId = match[1];
var $row = $checkbox.closest('tr');
deletions.push(dialogId);
$row.fadeOut(300, function() { $(this).remove(); });
}
});
// Выполнение AJAX-запросов
if (deletions.length > 0) {
$.alerts._overlay('show');
var completedRequests = 0;
deletions.forEach(function(hid) {
$.ajax({
url: 'index.php?do=modules&action=modedit&mod=forms&moduleaction=email_del&hid=' + hid + '&ajax=1',
type: 'GET',
success: function() {
completedRequests++;
if (completedRequests === deletions.length) {
$.alerts._overlay('hide');
resetAllCheckedHisCheckboxes(); // Сброс
}
},
error: function() {
completedRequests++;
if (completedRequests === deletions.length) {
$.alerts._overlay('hide');
jAlert($smarty['delete_error'], $smarty['action_error_title']);
}
}
});
});
}
}
});
// --- ЛОГИКА МАССОВОГО ИЗМЕНЕНИЯ СТАТУСА ---
} else if (selectedAction === 'viewed' || selectedAction === 'replied') {
var completedRequests = 0;
var totalRequests = $checkedRows.length;
$.alerts._overlay('show');
// Перебираем выбранные чекбоксы
$checkedRows.each(function() {
var $checkbox = $(this);
var nameAttr = $checkbox.attr('name');
var match = nameAttr.match(/form\[(\d+)\]/);
if (match && match[1]) {
var hid = match[1];
var $row = $checkbox.closest('tr');
var $tdStatus = $row.find('td:eq(4)'); // 5-я ячейка со статусом
// Отправляем AJAX-запрос
$.ajax({
url: 'index.php?do=modules&action=modedit&mod=forms&moduleaction=dialog_status',
type: 'POST',
data: { hid: hid, status: selectedAction, ajax: 1 },
success: function(e) {
// Обновление ячейки статуса в DOM (взято из status_change)
$tdStatus.empty();
if (selectedAction === 'replied') {
$tdStatus.text($smarty['stat_replied']);
$row.removeClass('green yellow');
}
else if (selectedAction === 'viewed') {
$row.removeClass('green').addClass('yellow');
$('<select class="dialog_status" data-hid="'+hid+'" onChange="status_change($(this));"><option value="viewed">'+$smarty['stat_viewed']+'</option><option value="replied">'+$smarty['stat_replied']+'</option></select>').appendTo($tdStatus).jqTransform({imgPath: "../images"}).styler({selectVisibleOptions: 5,selectSearch: false});
}
completedRequests++;
if (completedRequests === totalRequests) {
$.alerts._overlay('hide');
resetAllCheckedHisCheckboxes(); // Сброс
}
},
error: function() {
completedRequests++;
if (completedRequests === totalRequests) {
$.alerts._overlay('hide');
jAlert('{#status_change_error#}', $smarty['action_error_title']);
}
}
});
}
});
} else {
return false;
}
});
</script>
{/literal}