Упрощён компонент поиска товаров: убран мультивыбор, только single-select
- Удалён весь функционал множественного выбора - Удалены кнопки 'Выбрать все' и 'Сбросить' - Удалён счётчик выбранных товаров - state.selected теперь содержит один объект вместо словаря - Убраны параметры multi_select, max_selection, show_select_all - onAddSelected теперь возвращает объект вместо массива - Удалены методы getSelectedIds() и setSelection() - Упрощена логика _toggleProduct для single-select - Обновлены все callback'и для работы с одним товаром - Компонент стал значительно проще и понятнее
This commit is contained in:
@@ -107,7 +107,7 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<!-- Компонент поиска товаров -->
|
<!-- Компонент поиска товаров -->
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
{% include 'products/components/product_search_picker.html' with container_id='writeoff-document-picker' title='Найти товар для списания' warehouse_id=document.warehouse.id filter_in_stock_only=True categories=categories tags=tags add_button_text='Выбрать товар' multi_select=False show_select_all=False content_height='250px' %}
|
{% include 'products/components/product_search_picker.html' with container_id='writeoff-document-picker' title='Найти товар для списания' warehouse_id=document.warehouse.id filter_in_stock_only=True categories=categories tags=tags add_button_text='Выбрать товар' content_height='250px' %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Информация о выбранном товаре -->
|
<!-- Информация о выбранном товаре -->
|
||||||
@@ -291,9 +291,9 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
|
|
||||||
// Инициализация компонента поиска товаров
|
// Инициализация компонента поиска товаров
|
||||||
const picker = ProductSearchPicker.init('#writeoff-document-picker', {
|
const picker = ProductSearchPicker.init('#writeoff-document-picker', {
|
||||||
onAddSelected: function(products, instance) {
|
onAddSelected: function(product, instance) {
|
||||||
if (products.length > 0) {
|
if (product) {
|
||||||
selectProduct(products[0]);
|
selectProduct(product);
|
||||||
instance.clearSelection();
|
instance.clearSelection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,18 @@
|
|||||||
/**
|
/**
|
||||||
* ProductSearchPicker - переиспользуемый модуль для поиска и выбора товаров
|
* ProductSearchPicker - переиспользуемый модуль для поиска и выбора товара
|
||||||
|
* Только single-select режим.
|
||||||
*
|
*
|
||||||
* API:
|
* API:
|
||||||
* - ProductSearchPicker.init(containerSelector, options) - инициализация
|
* - ProductSearchPicker.init(containerSelector, options) - инициализация
|
||||||
* - instance.getSelected() - получить выбранные товары (массив объектов)
|
* - instance.getSelected() - получить выбранный товар (объект или null)
|
||||||
* - instance.getSelectedIds() - получить ID выбранных товаров (массив строк)
|
|
||||||
* - instance.clearSelection() - сбросить выбор
|
* - instance.clearSelection() - сбросить выбор
|
||||||
* - instance.setSelection(productIds) - установить выбор программно
|
|
||||||
* - instance.refresh() - обновить список товаров
|
* - instance.refresh() - обновить список товаров
|
||||||
* - instance.destroy() - уничтожить экземпляр
|
* - instance.destroy() - уничтожить экземпляр
|
||||||
*
|
*
|
||||||
* Пример использования:
|
* Пример использования:
|
||||||
* const picker = ProductSearchPicker.init('#my-picker', {
|
* const picker = ProductSearchPicker.init('#my-picker', {
|
||||||
* onAddSelected: function(products, instance) {
|
* onAddSelected: function(product, instance) {
|
||||||
* console.log('Добавлены товары:', products);
|
* console.log('Выбран товар:', product);
|
||||||
* }
|
* }
|
||||||
* });
|
* });
|
||||||
*/
|
*/
|
||||||
@@ -39,23 +38,20 @@
|
|||||||
// Настройки по умолчанию
|
// Настройки по умолчанию
|
||||||
this.options = Object.assign({
|
this.options = Object.assign({
|
||||||
apiUrl: this.container.dataset.apiUrl || '/products/api/search-products-variants/',
|
apiUrl: this.container.dataset.apiUrl || '/products/api/search-products-variants/',
|
||||||
multiSelect: this.container.dataset.multiSelect !== 'false',
|
|
||||||
maxSelection: parseInt(this.container.dataset.maxSelection) || null,
|
|
||||||
excludeKits: this.container.dataset.excludeKits !== 'false',
|
excludeKits: this.container.dataset.excludeKits !== 'false',
|
||||||
debounceDelay: 300,
|
debounceDelay: 300,
|
||||||
pageSize: 30,
|
pageSize: 30,
|
||||||
|
|
||||||
// Callbacks
|
// Callbacks
|
||||||
onSelect: null, // (products, instance) => {}
|
onSelect: null, // (product, instance) => {}
|
||||||
onDeselect: null, // (products, instance) => {}
|
onDeselect: null, // (instance) => {}
|
||||||
onSelectionChange: null, // (selectedProducts, instance) => {}
|
onAddSelected: null // (product, instance) => {}
|
||||||
onAddSelected: null // (selectedProducts, instance) => {}
|
|
||||||
}, options || {});
|
}, options || {});
|
||||||
|
|
||||||
// Состояние
|
// Состояние
|
||||||
this.state = {
|
this.state = {
|
||||||
products: [],
|
products: [],
|
||||||
selected: {}, // {productId: productData}
|
selected: null, // Единичный выбранный товар (объект или null)
|
||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
hasMore: false,
|
hasMore: false,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
@@ -94,9 +90,6 @@
|
|||||||
loading: c.querySelector('.product-picker-loading'),
|
loading: c.querySelector('.product-picker-loading'),
|
||||||
empty: c.querySelector('.product-picker-empty'),
|
empty: c.querySelector('.product-picker-empty'),
|
||||||
content: c.querySelector('.product-picker-content'),
|
content: c.querySelector('.product-picker-content'),
|
||||||
selectedCount: c.querySelector('.product-picker-selected-count'),
|
|
||||||
selectAllBtn: c.querySelector('.product-picker-select-all'),
|
|
||||||
clearSelectionBtn: c.querySelector('.product-picker-clear-selection'),
|
|
||||||
addSelectedBtn: c.querySelector('.product-picker-add-selected'),
|
addSelectedBtn: c.querySelector('.product-picker-add-selected'),
|
||||||
viewButtons: c.querySelectorAll('.product-picker-view')
|
viewButtons: c.querySelectorAll('.product-picker-view')
|
||||||
};
|
};
|
||||||
@@ -210,25 +203,11 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Выбрать все
|
// Добавить выбранный
|
||||||
if (this.elements.selectAllBtn) {
|
|
||||||
this.elements.selectAllBtn.addEventListener('click', function() {
|
|
||||||
self._selectAll();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Сбросить выбор
|
|
||||||
if (this.elements.clearSelectionBtn) {
|
|
||||||
this.elements.clearSelectionBtn.addEventListener('click', function() {
|
|
||||||
self.clearSelection();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Добавить выбранные
|
|
||||||
if (this.elements.addSelectedBtn) {
|
if (this.elements.addSelectedBtn) {
|
||||||
this.elements.addSelectedBtn.addEventListener('click', function() {
|
this.elements.addSelectedBtn.addEventListener('click', function() {
|
||||||
if (self.options.onAddSelected) {
|
if (self.state.selected && self.options.onAddSelected) {
|
||||||
self.options.onAddSelected(self.getSelected(), self);
|
self.options.onAddSelected(self.state.selected, self);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -348,7 +327,7 @@
|
|||||||
products.forEach(function(product) {
|
products.forEach(function(product) {
|
||||||
// Извлекаем ID (убираем префикс "product_")
|
// Извлекаем ID (убираем префикс "product_")
|
||||||
var productId = String(product.id).replace('product_', '');
|
var productId = String(product.id).replace('product_', '');
|
||||||
var isSelected = self.state.selected.hasOwnProperty(productId);
|
var isSelected = self.state.selected && self.state.selected.id === productId;
|
||||||
|
|
||||||
var html = self.state.currentView === 'grid'
|
var html = self.state.currentView === 'grid'
|
||||||
? self._renderGridCard(product, productId, isSelected)
|
? self._renderGridCard(product, productId, isSelected)
|
||||||
@@ -446,7 +425,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Переключение выбора товара
|
* Переключение выбора товара (single-select)
|
||||||
*/
|
*/
|
||||||
ProductSearchPicker.prototype._toggleProduct = function(productId) {
|
ProductSearchPicker.prototype._toggleProduct = function(productId) {
|
||||||
var self = this;
|
var self = this;
|
||||||
@@ -457,47 +436,40 @@
|
|||||||
var p = this.state.products[i];
|
var p = this.state.products[i];
|
||||||
if (String(p.id).replace('product_', '') === productId) {
|
if (String(p.id).replace('product_', '') === productId) {
|
||||||
product = p;
|
product = p;
|
||||||
|
product.id = productId; // Сохраняем очищенный ID
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!product) return;
|
if (!product) return;
|
||||||
|
|
||||||
var isSelected = this.state.selected.hasOwnProperty(productId);
|
var isSelected = this.state.selected && this.state.selected.id === productId;
|
||||||
|
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
// Снять выбор
|
// Снять выбор
|
||||||
delete this.state.selected[productId];
|
var oldProductId = this.state.selected.id;
|
||||||
|
this.state.selected = null;
|
||||||
|
this._updateProductUI(oldProductId);
|
||||||
if (this.options.onDeselect) {
|
if (this.options.onDeselect) {
|
||||||
this.options.onDeselect([product], this);
|
this.options.onDeselect(this);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Проверка множественного выбора
|
// Сначала снимаем выбор со старого товара
|
||||||
if (!this.options.multiSelect) {
|
if (this.state.selected) {
|
||||||
this.state.selected = {};
|
var oldProductId = this.state.selected.id;
|
||||||
|
this._updateProductUI(oldProductId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Проверка лимита
|
// Выбираем новый товар
|
||||||
if (this.options.maxSelection &&
|
this.state.selected = product;
|
||||||
Object.keys(this.state.selected).length >= this.options.maxSelection) {
|
this._updateProductUI(productId);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Добавить в выбор
|
|
||||||
this.state.selected[productId] = product;
|
|
||||||
if (this.options.onSelect) {
|
if (this.options.onSelect) {
|
||||||
this.options.onSelect([product], this);
|
this.options.onSelect(product, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Обновить UI
|
// Обновить UI
|
||||||
this._updateProductUI(productId);
|
|
||||||
this._updateSelectionUI();
|
this._updateSelectionUI();
|
||||||
|
|
||||||
// Общий callback
|
|
||||||
if (this.options.onSelectionChange) {
|
|
||||||
this.options.onSelectionChange(this.getSelected(), this);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -507,7 +479,7 @@
|
|||||||
var card = this.elements.grid.querySelector('[data-product-id="' + productId + '"]');
|
var card = this.elements.grid.querySelector('[data-product-id="' + productId + '"]');
|
||||||
if (!card) return;
|
if (!card) return;
|
||||||
|
|
||||||
var isSelected = this.state.selected.hasOwnProperty(productId);
|
var isSelected = this.state.selected && this.state.selected.id === productId;
|
||||||
|
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
card.classList.add('selected');
|
card.classList.add('selected');
|
||||||
@@ -545,52 +517,16 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Обновление UI выбора (счетчик, кнопки)
|
* Обновление UI выбора (кнопка)
|
||||||
*/
|
*/
|
||||||
ProductSearchPicker.prototype._updateSelectionUI = function() {
|
ProductSearchPicker.prototype._updateSelectionUI = function() {
|
||||||
var count = Object.keys(this.state.selected).length;
|
|
||||||
|
|
||||||
// Счетчик
|
|
||||||
if (this.elements.selectedCount) {
|
|
||||||
this.elements.selectedCount.textContent = count;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Кнопка "Добавить"
|
// Кнопка "Добавить"
|
||||||
if (this.elements.addSelectedBtn) {
|
if (this.elements.addSelectedBtn) {
|
||||||
this.elements.addSelectedBtn.disabled = count === 0;
|
this.elements.addSelectedBtn.disabled = !this.state.selected;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Выбрать все видимые товары
|
|
||||||
*/
|
|
||||||
ProductSearchPicker.prototype._selectAll = function() {
|
|
||||||
var self = this;
|
|
||||||
var currentCount = Object.keys(this.state.selected).length;
|
|
||||||
var maxToSelect = this.options.maxSelection
|
|
||||||
? this.options.maxSelection - currentCount
|
|
||||||
: Infinity;
|
|
||||||
|
|
||||||
var added = 0;
|
|
||||||
this.state.products.forEach(function(product) {
|
|
||||||
if (added >= maxToSelect) return;
|
|
||||||
|
|
||||||
var productId = String(product.id).replace('product_', '');
|
|
||||||
if (!self.state.selected.hasOwnProperty(productId)) {
|
|
||||||
self.state.selected[productId] = product;
|
|
||||||
self._updateProductUI(productId);
|
|
||||||
added++;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this._updateSelectionUI();
|
|
||||||
|
|
||||||
if (this.options.onSelectionChange) {
|
|
||||||
this.options.onSelectionChange(this.getSelected(), this);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Обновление кнопок переключателя вида
|
* Обновление кнопок переключателя вида
|
||||||
*/
|
*/
|
||||||
ProductSearchPicker.prototype._updateViewButtons = function() {
|
ProductSearchPicker.prototype._updateViewButtons = function() {
|
||||||
@@ -625,68 +561,25 @@
|
|||||||
// ========== ПУБЛИЧНОЕ API ==========
|
// ========== ПУБЛИЧНОЕ API ==========
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Получить массив выбранных товаров
|
* Получить выбранный товар (объект или null)
|
||||||
*/
|
*/
|
||||||
ProductSearchPicker.prototype.getSelected = function() {
|
ProductSearchPicker.prototype.getSelected = function() {
|
||||||
var result = [];
|
return this.state.selected;
|
||||||
for (var key in this.state.selected) {
|
|
||||||
if (this.state.selected.hasOwnProperty(key)) {
|
|
||||||
result.push(this.state.selected[key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Получить массив ID выбранных товаров
|
|
||||||
*/
|
|
||||||
ProductSearchPicker.prototype.getSelectedIds = function() {
|
|
||||||
return Object.keys(this.state.selected);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Сбросить выбор
|
* Сбросить выбор
|
||||||
*/
|
*/
|
||||||
ProductSearchPicker.prototype.clearSelection = function() {
|
ProductSearchPicker.prototype.clearSelection = function() {
|
||||||
var self = this;
|
if (this.state.selected) {
|
||||||
var ids = Object.keys(this.state.selected);
|
var productId = this.state.selected.id;
|
||||||
this.state.selected = {};
|
this.state.selected = null;
|
||||||
|
this._updateProductUI(productId);
|
||||||
ids.forEach(function(productId) {
|
|
||||||
self._updateProductUI(productId);
|
|
||||||
});
|
|
||||||
|
|
||||||
this._updateSelectionUI();
|
|
||||||
|
|
||||||
if (this.options.onSelectionChange) {
|
|
||||||
this.options.onSelectionChange([], this);
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Установить выбор программно
|
|
||||||
*/
|
|
||||||
ProductSearchPicker.prototype.setSelection = function(productIds) {
|
|
||||||
var self = this;
|
|
||||||
this.clearSelection();
|
|
||||||
|
|
||||||
productIds.forEach(function(id) {
|
|
||||||
var productId = String(id).replace('product_', '');
|
|
||||||
// Ищем товар в загруженном списке
|
|
||||||
for (var i = 0; i < self.state.products.length; i++) {
|
|
||||||
var p = self.state.products[i];
|
|
||||||
if (String(p.id).replace('product_', '') === productId) {
|
|
||||||
self.state.selected[productId] = p;
|
|
||||||
self._updateProductUI(productId);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this._updateSelectionUI();
|
this._updateSelectionUI();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Обновить список товаров
|
* Обновить список товаров
|
||||||
*/
|
*/
|
||||||
ProductSearchPicker.prototype.refresh = function() {
|
ProductSearchPicker.prototype.refresh = function() {
|
||||||
|
|||||||
@@ -1,18 +1,15 @@
|
|||||||
{% comment %}
|
{% comment %}
|
||||||
Переиспользуемый компонент поиска и выбора штучных товаров (Product).
|
Переиспользуемый компонент поиска и выбора товара (Product).
|
||||||
|
Только единичный выбор (single-select).
|
||||||
|
|
||||||
Параметры (Django template variables):
|
Параметры (Django template variables):
|
||||||
- container_id: уникальный ID контейнера (default: 'product-search-picker')
|
- container_id: уникальный ID контейнера (default: 'product-search-picker')
|
||||||
- title: заголовок компонента (default: 'Выбор товаров')
|
- title: заголовок компонента (default: 'Выбор товара')
|
||||||
- api_url: URL для AJAX поиска (default: '/products/api/search-products-variants/')
|
- api_url: URL для AJAX поиска (default: '/products/api/search-products-variants/')
|
||||||
- show_filters: показывать фильтры (default: True)
|
- show_filters: показывать фильтры (default: True)
|
||||||
- show_view_toggle: показывать переключатель вида (default: True)
|
- show_view_toggle: показывать переключатель вида (default: True)
|
||||||
- show_select_all: показывать кнопку "Выбрать все" (default: True)
|
- add_button_text: текст кнопки добавления (default: 'Выбрать товар')
|
||||||
- show_add_button: показывать кнопку "Добавить выбранные" (default: True)
|
|
||||||
- add_button_text: текст кнопки добавления (default: 'Добавить выбранные')
|
|
||||||
- initial_view: начальный вид 'grid' или 'list' (default: 'list')
|
- initial_view: начальный вид 'grid' или 'list' (default: 'list')
|
||||||
- multi_select: множественный выбор (default: True)
|
|
||||||
- max_selection: максимальное количество выбранных товаров (default: null)
|
|
||||||
- filter_in_stock_only: показывать только товары в наличии (default: False)
|
- filter_in_stock_only: показывать только товары в наличии (default: False)
|
||||||
- warehouse_id: ID склада для фильтрации товаров (default: None)
|
- warehouse_id: ID склада для фильтрации товаров (default: None)
|
||||||
- categories: список категорий для фильтра (queryset или list)
|
- categories: список категорий для фильтра (queryset или list)
|
||||||
@@ -22,7 +19,7 @@
|
|||||||
Пример использования:
|
Пример использования:
|
||||||
{% include 'products/components/product_search_picker.html' with
|
{% include 'products/components/product_search_picker.html' with
|
||||||
container_id='writeoff-products'
|
container_id='writeoff-products'
|
||||||
title='Выберите товары для списания'
|
title='Выберите товар для списания'
|
||||||
show_filters=True
|
show_filters=True
|
||||||
filter_in_stock_only=True
|
filter_in_stock_only=True
|
||||||
categories=categories
|
categories=categories
|
||||||
@@ -31,9 +28,9 @@
|
|||||||
После включения инициализируйте JS:
|
После включения инициализируйте JS:
|
||||||
<script>
|
<script>
|
||||||
ProductSearchPicker.init('#writeoff-products', {
|
ProductSearchPicker.init('#writeoff-products', {
|
||||||
onAddSelected: function(products, instance) {
|
onAddSelected: function(product, instance) {
|
||||||
// products = [{id, text, sku, price, in_stock, photo_url}, ...]
|
// product = {id, text, sku, price, in_stock, photo_url}
|
||||||
products.forEach(addToForm);
|
addToForm(product);
|
||||||
instance.clearSelection();
|
instance.clearSelection();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -45,8 +42,6 @@ ProductSearchPicker.init('#writeoff-products', {
|
|||||||
<div class="product-search-picker"
|
<div class="product-search-picker"
|
||||||
id="{{ container_id|default:'product-search-picker' }}"
|
id="{{ container_id|default:'product-search-picker' }}"
|
||||||
data-api-url="{{ api_url|default:'/products/api/search-products-variants/' }}"
|
data-api-url="{{ api_url|default:'/products/api/search-products-variants/' }}"
|
||||||
data-multi-select="{{ multi_select|default:'true' }}"
|
|
||||||
data-max-selection="{{ max_selection|default:'' }}"
|
|
||||||
data-exclude-kits="true"
|
data-exclude-kits="true"
|
||||||
{% if warehouse_id %}data-warehouse-id="{{ warehouse_id }}"{% endif %}>
|
{% if warehouse_id %}data-warehouse-id="{{ warehouse_id }}"{% endif %}>
|
||||||
|
|
||||||
@@ -55,7 +50,7 @@ ProductSearchPicker.init('#writeoff-products', {
|
|||||||
<div class="card-header bg-white py-2 d-flex justify-content-between align-items-center flex-wrap gap-2">
|
<div class="card-header bg-white py-2 d-flex justify-content-between align-items-center flex-wrap gap-2">
|
||||||
<strong>
|
<strong>
|
||||||
<i class="bi bi-box-seam text-primary"></i>
|
<i class="bi bi-box-seam text-primary"></i>
|
||||||
{{ title|default:'Выбор товаров' }}
|
{{ title|default:'Выбор товара' }}
|
||||||
</strong>
|
</strong>
|
||||||
|
|
||||||
<div class="d-flex gap-2 align-items-center flex-wrap">
|
<div class="d-flex gap-2 align-items-center flex-wrap">
|
||||||
@@ -128,11 +123,7 @@ ProductSearchPicker.init('#writeoff-products', {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Счетчик выбранных -->
|
<!-- Счетчик выбранных - УБРАН в single-select режиме -->
|
||||||
<div class="col-auto ms-auto">
|
|
||||||
<span class="badge bg-primary product-picker-selected-count">0</span>
|
|
||||||
<span class="text-muted small">выбрано</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -158,27 +149,14 @@ ProductSearchPicker.init('#writeoff-products', {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Футер с кнопками действий -->
|
<!-- Футер с кнопкой действия -->
|
||||||
<div class="card-footer bg-white py-2 d-flex justify-content-between align-items-center flex-wrap gap-2">
|
<div class="card-footer bg-white py-2 d-flex justify-content-between align-items-center flex-wrap gap-2">
|
||||||
{% if show_select_all|default:True %}
|
|
||||||
<div class="d-flex gap-2">
|
|
||||||
<button class="btn btn-outline-secondary btn-sm product-picker-select-all">
|
|
||||||
<i class="bi bi-check2-all"></i> Выбрать все
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-outline-secondary btn-sm product-picker-clear-selection">
|
|
||||||
<i class="bi bi-x-lg"></i> Сбросить
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div></div>
|
<div></div>
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if show_add_button|default:True %}
|
|
||||||
<button class="btn btn-primary btn-sm product-picker-add-selected" disabled>
|
<button class="btn btn-primary btn-sm product-picker-add-selected" disabled>
|
||||||
<i class="bi bi-plus-circle"></i>
|
<i class="bi bi-plus-circle"></i>
|
||||||
{{ add_button_text|default:'Добавить выбранные' }}
|
{{ add_button_text|default:'Выбрать товар' }}
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user