fixed bug when multiple formulas or windows appeared

This commit is contained in:
Ali 2025-04-05 00:53:03 +04:00
parent 07e26d1395
commit 2042e2365a
1 changed files with 207 additions and 84 deletions

View File

@ -1342,29 +1342,29 @@ return formula;
}
function addTokenHandlers($container) {
// Удаление токенов
$container.find('.token-remove').off('click').on('click', function(e) {
e.stopPropagation();
$(this).parent().remove();
});
// Удаление токенов
$container.find('.token-remove').off('click').on('click', function(e) {
e.stopPropagation();
$(this).parent().remove();
});
// Перетаскивание токенов
$container.find('.formula-token').each(function() {
$(this).attr('draggable', 'true');
$(this).off('dragstart').on('dragstart', function(e) {
e.originalEvent.dataTransfer.setData('text/plain', JSON.stringify({
type: 'token',
value: $(this).data('value'),
html: $(this)[0].outerHTML
}));
window.draggedElement = this;
// Перетаскивание токенов
$container.find('.formula-token').each(function() {
$(this).attr('draggable', 'true');
$(this).off('dragstart').on('dragstart', function(e) {
e.originalEvent.dataTransfer.setData('text/plain', JSON.stringify({
type: 'token',
value: $(this).data('value'),
html: $(this)[0].outerHTML
}));
window.draggedElement = this;
});
$(this).off('dragend').on('dragend', function() {
window.draggedElement = null;
});
});
$(this).off('dragend').on('dragend', function() {
window.draggedElement = null;
});
});
}
// Функции для создания модальных окон
@ -1698,18 +1698,21 @@ function createUniversalFieldsModal() {
// Обработчики событий редактора формул
function attachFormulaBuilderEvents(frm, fields, grouped_fields) {
// Сделаем поля ввода формул редактируемыми
$(frm.wrapper).find('.formula-input').prop('readonly', false);
// Сделаем поля ввода формул редактируемыми
$(frm.wrapper).find('.formula-input').prop('readonly', false);
// Обработчик для кнопок открытия визуального редактора
$(frm.wrapper).on('click', '.open-formula-builder', function() {
const fieldname = $(this).data('fieldname');
const isTableField = $(this).data('is-table') === true;
const currentFormula = $(frm.wrapper).find(`.formula-input[data-fieldname="${fieldname}"]`).val();
openFormulaBuilder(frm, fieldname, isTableField, currentFormula, fields, grouped_fields);
return false;
});
// Сначала удаляем существующие обработчики событий
$(frm.wrapper).off('click', '.open-formula-builder');
// Обработчик для кнопок открытия визуального редактора
$(frm.wrapper).on('click', '.open-formula-builder', function() {
const fieldname = $(this).data('fieldname');
const isTableField = $(this).data('is-table') === true;
const currentFormula = $(frm.wrapper).find(`.formula-input[data-fieldname="${fieldname}"]`).val();
openFormulaBuilder(frm, fieldname, isTableField, currentFormula, fields, grouped_fields);
return false;
});
}
function openFormulaBuilder(frm, targetFieldname, isTableField, currentFormula, fields, grouped_fields) {
@ -1719,6 +1722,8 @@ function openFormulaBuilder(frm, targetFieldname, isTableField, currentFormula,
// Очистка предыдущих обработчиков и данных
$modal.off('click', '.field-btn');
$modal.off('click', '.universal-field-btn');
$modal.off('click', '.operator-btn');
$modal.find('.apply-formula').off('click');
$resultContainer.empty();
$modal.find(".field-groups-container").empty();
@ -1749,13 +1754,13 @@ function openFormulaBuilder(frm, targetFieldname, isTableField, currentFormula,
});
// Обработчики для кнопок полей - используем делегирование событий
$modal.on('click', '.field-btn', function() {
$modal.off('click', '.field-btn').on('click', '.field-btn', function() {
const fieldname = $(this).data('fieldname');
addTokenToFormula(fieldname, 'field', $resultContainer, isTableField, $(this).data('group'));
});
// Обработчики для кнопок универсальных полей
$modal.on('click', '.universal-field-btn', function() {
$modal.off('click', '.universal-field-btn').on('click', '.universal-field-btn', function() {
const fieldId = $(this).data('field-id');
const universalFields = JSON.parse(frm.doc.universal_fields_storage || "{}");
const field = universalFields[fieldId];
@ -1976,7 +1981,7 @@ function initDragAndDrop($modal, $resultContainer, isTableField, frm) {
setupTokenDragging($resultContainer);
// Настраиваем перетаскивание полей из панели
$modal.find('.field-btn').on('dragstart', function(e) {
$modal.find('.field-btn').off('dragstart').on('dragstart', function(e) {
const fieldname = $(this).data('fieldname');
const label = $(this).data('label');
const group = $(this).data('group');
@ -1995,7 +2000,7 @@ function initDragAndDrop($modal, $resultContainer, isTableField, frm) {
});
// Настраиваем перетаскивание универсальных полей
$modal.find('.universal-field-btn').on('dragstart', function(e) {
$modal.find('.universal-field-btn').off('dragstart').on('dragstart', function(e) {
const fieldId = $(this).data('field-id');
const fieldname = $(this).data('fieldname');
const label = $(this).data('label');
@ -2009,7 +2014,7 @@ function initDragAndDrop($modal, $resultContainer, isTableField, frm) {
});
// Настраиваем перетаскивание операторов
$modal.find('.operator-btn').on('dragstart', function(e) {
$modal.find('.operator-btn').off('dragstart').on('dragstart', function(e) {
const operator = $(this).data('operator');
e.originalEvent.dataTransfer.setData('text/plain', JSON.stringify({
@ -2019,7 +2024,7 @@ function initDragAndDrop($modal, $resultContainer, isTableField, frm) {
});
// Обработчики для целевого контейнера
$resultContainer.on('dragover', function(e) {
$resultContainer.off('dragover').on('dragover', function(e) {
e.preventDefault();
e.stopPropagation();
$(this).addClass('drag-hover');
@ -2027,12 +2032,12 @@ function initDragAndDrop($modal, $resultContainer, isTableField, frm) {
updateDropMarker(e, $(this));
});
$resultContainer.on('dragleave', function(e) {
$resultContainer.off('dragleave').on('dragleave', function(e) {
$(this).removeClass('drag-hover');
$(this).find('.drop-marker').remove();
});
$resultContainer.on('drop', function(e) {
$resultContainer.off('drop').on('drop', function(e) {
e.preventDefault();
e.stopPropagation();
$(this).removeClass('drag-hover');
@ -2043,32 +2048,32 @@ function initDragAndDrop($modal, $resultContainer, isTableField, frm) {
}
function setupTokenDragging($container) {
$container.find('.formula-token').each(function() {
$(this).attr('draggable', 'true');
$(this).off('dragstart').on('dragstart', function(e) {
// Сохраняем ссылку на текущий элемент
window.draggedElement = this;
$container.find('.formula-token').each(function() {
$(this).attr('draggable', 'true');
// Добавляем данные для переноса
e.originalEvent.dataTransfer.setData('text/plain', JSON.stringify({
type: 'token',
value: $(this).data('value'),
html: $(this)[0].outerHTML
}));
$(this).off('dragstart').on('dragstart', function(e) {
// Сохраняем ссылку на текущий элемент
window.draggedElement = this;
// Добавляем данные для переноса
e.originalEvent.dataTransfer.setData('text/plain', JSON.stringify({
type: 'token',
value: $(this).data('value'),
html: $(this)[0].outerHTML
}));
// Добавляем класс перетаскивания
$(this).addClass('dragging');
return true;
});
// Добавляем класс перетаскивания
$(this).addClass('dragging');
return true;
// При завершении перетаскивания
$(this).off('dragend').on('dragend', function(e) {
$(this).removeClass('dragging');
window.draggedElement = null;
});
});
// При завершении перетаскивания
$(this).off('dragend').on('dragend', function(e) {
$(this).removeClass('dragging');
window.draggedElement = null;
});
});
}
function updateDropMarker(e, $container) {
@ -2327,6 +2332,9 @@ function setupEditableContainer($container) {
// Функции для работы с полями изменения (триггерами)
function attachTriggerEditorEvents(frm, fields, grouped_fields) {
// Сначала удаляем существующие обработчики событий
$(frm.wrapper).off('click', '.open-trigger-editor');
// Обработчик для кнопок открытия редактора полей изменения
$(frm.wrapper).on('click', '.open-trigger-editor', function() {
const fieldname = $(this).data('fieldname');
@ -2343,6 +2351,8 @@ function openTriggerFieldsEditor(frm, targetFieldname, currentTriggers, fields,
// Очистка предыдущих обработчиков и данных
$modal.off('click', '.trigger-field-btn');
$modal.off('click', '.select-table-row-trigger-field');
$modal.find('.apply-triggers').off('click');
$resultContainer.empty();
$modal.find(".trigger-field-groups-container").empty();
@ -2383,7 +2393,7 @@ function openTriggerFieldsEditor(frm, targetFieldname, currentTriggers, fields,
});
// Обработчики для кнопок полей
$modal.on('click', '.trigger-field-btn', function() {
$modal.off('click', '.trigger-field-btn').on('click', '.trigger-field-btn', function() {
const fieldname = $(this).data('fieldname');
// Определяем тип поля по классу кнопки
@ -2400,7 +2410,7 @@ function openTriggerFieldsEditor(frm, targetFieldname, currentTriggers, fields,
});
// Обработчик для кнопки выбора полей строк табличных частей
$modal.on('click', '.select-table-row-trigger-field', function() {
$modal.off('click', '.select-table-row-trigger-field').on('click', '.select-table-row-trigger-field', function() {
openTableRowFieldSelector(frm, $resultContainer, true);
});
@ -2705,10 +2715,18 @@ function initTriggerDragAndDrop($modal, $triggerContainer) {
});
// Настраиваем перетаскивание полей из панели в триггер-контейнер
$modal.find('.field-btn, .universal-field-btn').off('dragstart').on('dragstart', function(e) {
$modal.find('.field-btn, .universal-field-btn, .trigger-field-btn').off('dragstart').on('dragstart', function(e) {
const fieldname = $(this).data('fieldname');
const label = $(this).data('label');
const fieldType = $(this).hasClass('universal-field-btn') ? 'universal' : 'field';
let fieldType = 'field';
if ($(this).hasClass('universal-field-btn')) {
fieldType = 'universal';
} else if ($(this).hasClass('highlight-event')) {
fieldType = 'event';
} else if ($(this).hasClass('table-field-btn')) {
fieldType = 'table';
}
const fieldData = {
type: 'trigger-field',
@ -2721,7 +2739,7 @@ function initTriggerDragAndDrop($modal, $triggerContainer) {
});
// Обработка dragover для триггер-контейнера
$triggerContainer.on('dragover', function(e) {
$triggerContainer.off('dragover').on('dragover', function(e) {
e.preventDefault();
e.stopPropagation();
$(this).addClass('drag-hover');
@ -2731,14 +2749,14 @@ function initTriggerDragAndDrop($modal, $triggerContainer) {
});
// Обработка dragleave для триггер-контейнера
$triggerContainer.on('dragleave', function(e) {
$triggerContainer.off('dragleave').on('dragleave', function(e) {
e.preventDefault();
$(this).removeClass('drag-hover');
$(this).find('.drop-marker').remove();
});
// Обработка drop для триггер-контейнера
$triggerContainer.on('drop', function(e) {
$triggerContainer.off('drop').on('drop', function(e) {
e.preventDefault();
e.stopPropagation();
$(this).removeClass('drag-hover');
@ -2998,6 +3016,11 @@ function addUniversalFieldsStyles() {
}
function attachUniversalFieldsEvents(frm) {
// Сначала удаляем существующие обработчики событий
$(frm.wrapper).off('click', '.add-universal-field');
$(frm.wrapper).off('click', '.edit-universal-field');
$(frm.wrapper).off('click', '.delete-universal-field');
// Обработчик нажатия на кнопку "Добавить поле"
$(frm.wrapper).on('click', '.add-universal-field', function() {
openUniversalFieldModal(frm);
@ -3019,6 +3042,10 @@ function attachUniversalFieldsEvents(frm) {
}
function openUniversalFieldModal(frm, fieldId = null) {
// Закрываем предыдущее окно, если оно открыто
if ($("#universal_fields_modal").is(":visible")) {
$("#universal_fields_modal").modal('hide');
}
// Получаем значения для редактирования (если указан fieldId)
let fieldValues = {};
@ -3053,6 +3080,13 @@ function openUniversalFieldModal(frm, fieldId = null) {
const selectedDoctype = d.get_value('doctype');
if (selectedDoctype) {
// Очищаем таблицу фильтров перед загрузкой новых полей
if (d.fields_dict.filters && d.fields_dict.filters.grid) {
d.fields_dict.filters.grid.grid_rows.forEach(row => {
row.remove();
});
}
// Загружаем поля выбранного DocType
frappe.model.with_doctype(selectedDoctype, function() {
const meta = frappe.get_meta(selectedDoctype);
@ -3106,14 +3140,50 @@ function openUniversalFieldModal(frm, fieldId = null) {
// Сохраняем информацию о полях для использования в фильтрах
d.docFields = meta.fields;
// ВАЖНО: Сохраняем docFields также в глобальной переменной
window.docFields = meta.fields;
// Обновляем опции для фильтров
if (d.fields_dict.filters && d.fields_dict.filters.grid) {
d.fields_dict.filters.grid.update_docfield_property('field', 'options', filterFieldOptions);
}
// Если редактируем существующее поле и есть фильтры, добавляем их
if (fieldId && fieldValues.filters && fieldValues.filters.length) {
setTimeout(() => {
// Вручную добавляем каждый фильтр
fieldValues.filters.forEach(filter => {
if (!filter || !filter.field) return;
// Добавляем строку в таблицу фильтров
d.fields_dict.filters.grid.add_new_row();
const lastRow = d.fields_dict.filters.grid.grid_rows[d.fields_dict.filters.grid.grid_rows.length - 1];
// Устанавливаем значения фильтра
lastRow.doc.field = filter.field;
lastRow.doc.operator = filter.operator || '=';
lastRow.doc.value = filter.value || '';
// Дополнительные свойства из оригинального фильтра
if (filter.__is_special_ay_field) {
lastRow.doc.__is_special_ay_field = true;
}
// Обновляем отображение строки
lastRow.refresh();
// Находим информацию о поле для настройки типа значения
const fieldInfo = d.docFields.find(f => f.fieldname === filter.field);
if (fieldInfo) {
setTimeout(() => {
handleFilterFieldChange(d, lastRow, fieldInfo);
}, 100);
}
});
// Обновляем всю таблицу
d.fields_dict.filters.grid.refresh();
}, 500);
}
});
}
}
@ -3149,9 +3219,7 @@ function openUniversalFieldModal(frm, fieldId = null) {
if (fieldInfo) {
// Изменяем тип поля значения
handleFilterFieldChange(d, grid_row, fieldInfo);
} else {
}
} else {
}
}
},
@ -3184,7 +3252,7 @@ function openUniversalFieldModal(frm, fieldId = null) {
columns: 4
}
],
default: fieldValues.filters || []
default: []
}
],
primary_action_label: fieldId ? 'Обновить' : 'Создать',
@ -3208,11 +3276,6 @@ function openUniversalFieldModal(frm, fieldId = null) {
}
});
// Если редактируем и есть фильтры, заполняем их
if (fieldId && fieldValues.filters && fieldValues.filters.length) {
d.set_value('filters', fieldValues.filters);
}
// Безопасно инициализируем обработчики для строк фильтров
try {
if (d.fields_dict.filters && d.fields_dict.filters.grid) {
@ -3224,12 +3287,20 @@ function openUniversalFieldModal(frm, fieldId = null) {
// Добавляем обработчик на событие добавления строки
d.fields_dict.filters.grid.on('row-added', function(row) {
if (d.docFields) {
// Копируем docFields в window для доступа из обработчиков
window.docFields = d.docFields;
}
});
}
} catch (error) {
console.error("Ошибка при инициализации обработчиков фильтров:", error);
}
// Если редактируем существующее поле, вызываем событие изменения doctype для загрузки полей
if (fieldId && fieldValues.doctype) {
// Даем время на инициализацию компонентов
setTimeout(() => {
d.fields_dict.doctype.df.onchange.call(d.fields_dict.doctype);
}, 200);
}
// Показываем диалог
@ -4584,7 +4655,15 @@ function openTableRowFormulaModal(frm, formulaId = null) {
const $resultContainer = $modal.find(".table-row-formula");
const $triggerContainer = $modal.find(".table-row-trigger");
// Очистка предыдущих данных
// Очистка предыдущих обработчиков и данных
$modal.off('click', '.field-btn');
$modal.off('click', '.universal-field-btn');
$modal.off('click', '.operator-btn');
$modal.off('click', '.save-table-row-formula');
$modal.off('click', '.add-predefined-event');
$modal.off('click', '.open-trigger-editor-in-row');
$modal.off('click', '.select-table-row-trigger-field');
$resultContainer.empty();
$triggerContainer.empty();
$modal.find(".field-groups-container").empty();
@ -4687,6 +4766,34 @@ function openTableRowFormulaModal(frm, formulaId = null) {
$modal.modal('hide');
});
// Обработчик для кнопки "При открытии документа"
$modal.find('.add-predefined-event').off('click').on('click', function() {
addTokenToTriggers("При открытии документа", $triggerContainer, 'event');
});
// Обработчик для кнопки "Выбрать поле"
$modal.find('.open-trigger-editor-in-row').off('click').on('click', function() {
openTriggerFieldsEditorForTableRow(frm, $triggerContainer);
});
// Обработчик для кнопки выбора поля строки табличной части
$modal.find('.select-table-row-trigger-field').off('click').on('click', function() {
openTableRowFieldSelector(frm, $triggerContainer, true);
});
// Обработчики для кнопок полей (используем делегирование событий)
$modal.off('click', '.field-btn, .universal-field-btn').on('click', '.field-btn, .universal-field-btn', function() {
const fieldText = $(this).text().trim();
const fieldType = $(this).hasClass('universal-field-btn') ? 'universal-field' : 'field';
// Добавляем в формулу
const $token = $(`<span class="formula-token ${fieldType}" data-value="${fieldText}" contenteditable="false" draggable="true">${fieldText}<span class="token-remove">×</span></span>`);
$resultContainer.append($token).append(' ');
// Добавляем обработчики для токенов
addTokenHandlers($resultContainer);
});
// Настраиваем перетаскивание и редактирование
initDragAndDrop($modal, $resultContainer, true, frm);
setupEditableContainer($resultContainer);
@ -4699,6 +4806,7 @@ function openTableRowFormulaModal(frm, formulaId = null) {
$modal.find(".modal-overlay").remove();
})
.catch((error) => {
console.error("Ошибка при открытии модального окна формулы строки таблицы:", error);
$modal.find(".modal-overlay").remove();
frappe.msgprint({
title: __('Ошибка'),
@ -5226,6 +5334,11 @@ function initTableRowFormulas(frm) {
// Создаем модальное окно, если его еще нет
createTableRowFormulaModal();
// Удаляем существующие обработчики
$(frm.wrapper).off('click', '.add-table-row-formula');
$(frm.wrapper).off('click', '.edit-table-row-formula');
$(frm.wrapper).off('click', '.delete-table-row-formula');
// Обработчик для кнопки добавления новой формулы
$(frm.wrapper).on('click', '.add-table-row-formula', function() {
openTableRowFormulaModal(frm);
@ -5588,6 +5701,9 @@ function openTableRowFieldSelector(frm, targetContainer, isForTrigger = false) {
$("#row_field_name").empty().append('<option value="">Выберите поле</option>').prop('disabled', true);
$("#row_field_index").val(1);
// Удаляем старые обработчики
$modal.find('.add-table-row-field').off('click');
// Загружаем список табличных частей
loadTablesListForSelector(frm);
@ -5597,7 +5713,7 @@ function openTableRowFieldSelector(frm, targetContainer, isForTrigger = false) {
$modal.data("frm", frm);
// Обработчик для кнопки добавления
$modal.find('.add-table-row-field').off('click').on('click', function() {
$modal.find('.add-table-row-field').on('click', function() {
const tableName = $("#row_field_table").val();
const fieldName = $("#row_field_name").val();
const rowIndex = $("#row_field_index").val();
@ -6494,6 +6610,8 @@ function openTriggerFieldsEditorForTableRow(frm, $triggerContainer) {
// Очистка предыдущих обработчиков и данных
$modal.off('click', '.trigger-field-btn');
$modal.off('click', '.select-table-row-trigger-field');
$modal.find('.apply-triggers').off('click');
$modal.find(".trigger-result").empty();
$modal.find(".trigger-field-groups-container").empty();
@ -6536,7 +6654,7 @@ function openTriggerFieldsEditorForTableRow(frm, $triggerContainer) {
});
// Обработчики для кнопок полей
$modal.on('click', '.trigger-field-btn', function() {
$modal.off('click', '.trigger-field-btn').on('click', '.trigger-field-btn', function() {
const fieldname = $(this).data('fieldname');
// Определяем тип поля по классу кнопки
@ -6552,6 +6670,11 @@ function openTriggerFieldsEditorForTableRow(frm, $triggerContainer) {
addTokenToTriggers(fieldname, $modal.find(".trigger-result"), fieldType);
});
// Обработчик для кнопки выбора поля строки табличной части
$modal.off('click', '.select-table-row-trigger-field').on('click', '.select-table-row-trigger-field', function() {
openTableRowFieldSelector(frm, $modal.find(".trigger-result"), true);
});
// Увеличиваем z-index модального окна, чтобы оно было поверх других
$modal.css('z-index', 1100);