refactor(products): extract Order Item Select2 to reusable module

Moved order item selection logic from order_form.html to select2-product-search.js
for better code reusability and maintainability.

Changes:
- Extended select2-product-search.js with initOrderItemSelect2() function (~87 lines)
  - Wraps initProductSelect2 for order item context
  - Handles product/kit selection and form field updates
  - Manages custom price indicators
  - Supports data-ajax-url attribute for URL configuration

- Updated order_form.html:
  - Added data-ajax-url to order item select elements
  - Removed inline initOrderItemSelect2 function (~73 lines)
  - Updated dependency check to use initOrderItemSelect2

Benefits:
- No code duplication - reuses existing initProductSelect2
- Cleaner template (79 lines removed)
- Consistent with existing patterns
- Easy to maintain in one place

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-23 15:30:09 +03:00
parent fb4f14f475
commit 98501c1c26
2 changed files with 97 additions and 79 deletions

View File

@@ -145,4 +145,91 @@
});
};
/**
* Инициализирует Select2 для позиции заказа (товар или комплект)
* Обрабатывает выбор товара/комплекта и обновляет скрытые поля формы
*
* @param {Element|jQuery} element - DOM элемент select
* @param {string} apiUrl - URL API для поиска (по умолчанию из data-ajax-url)
*/
window.initOrderItemSelect2 = function(element, apiUrl) {
if (!element) return;
var $element = $(element);
// Получаем URL из параметра или data-атрибута
var searchUrl = apiUrl || $element.data('ajax-url');
if (!searchUrl) {
console.error('[initOrderItemSelect2] API URL not provided');
return;
}
// Инициализируем базовый Select2 с AJAX поиском (товары + комплекты)
window.initProductSelect2(element, 'all', searchUrl);
// Обработка выбора товара/комплекта
$element.on('select2:select', function(e) {
if (!e.params || !e.params.data) return;
var data = e.params.data;
var idParts = data.id.split('_');
var type = idParts[0]; // 'product' или 'kit'
var id = idParts[1];
// Найти форму и скрытые поля
var form = element.closest('.order-item-form');
if (!form) return;
var productField = form.querySelector('[name$="-product"]');
var kitField = form.querySelector('[name$="-product_kit"]');
var priceField = form.querySelector('[name$="-price"]');
var isCustomPriceField = form.querySelector('[name$="-is_custom_price"]');
var originalPrice = data.actual_price || data.price || '';
// Установить значение в правильное поле
if (type === 'product') {
if (productField) productField.value = id;
if (kitField) kitField.value = '';
if (priceField) priceField.value = originalPrice;
} else if (type === 'kit') {
if (kitField) kitField.value = id;
if (productField) productField.value = '';
if (priceField) priceField.value = originalPrice;
}
// Сохраняем оригинальную цену в data-атрибуте
if (priceField) {
priceField.dataset.originalPrice = originalPrice;
}
// Сбрасываем флаг кастомной цены
if (isCustomPriceField) {
isCustomPriceField.value = 'false';
}
// Скрываем индикатор кастомной цены
var badge = form.querySelector('.custom-price-badge');
var priceInfo = form.querySelector('.original-price-info');
if (badge) badge.style.display = 'none';
if (priceInfo) priceInfo.style.display = 'none';
});
// Очистка при удалении выбора
$element.on('select2:clear', function() {
var form = element.closest('.order-item-form');
if (!form) return;
var productField = form.querySelector('[name$="-product"]');
var kitField = form.querySelector('[name$="-product_kit"]');
var priceField = form.querySelector('[name$="-price"]');
var quantityField = form.querySelector('[name$="-quantity"]');
if (productField) productField.value = '';
if (kitField) kitField.value = '';
if (priceField) priceField.value = '';
if (quantityField) quantityField.value = '';
});
};
})(window);