dynamic table
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
<tbody>
|
||||
{% if items is defined and items|length > 0 %}
|
||||
{% for item in items %}
|
||||
<tr>
|
||||
{# Рендерим каждую колонку #}
|
||||
{% for key, column in columns %}
|
||||
<td>
|
||||
{{ render_cell(item, key, column)|raw }}
|
||||
</td>
|
||||
{% endfor %}
|
||||
|
||||
{# Колонка действий #}
|
||||
{% if actionsConfig is defined and actionsConfig|length > 0 %}
|
||||
<td class="actions-cell text-end">
|
||||
{{ render_actions(item, actionsConfig)|raw }}
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{# Пустое состояние #}
|
||||
<tr>
|
||||
<td colspan="{{ columns|length + (actions is defined and actions ? 1 : 0) }}"
|
||||
class="text-center py-5">
|
||||
{% if emptyIcon is defined and emptyIcon %}
|
||||
<div class="mb-3">
|
||||
<i class="{{ emptyIcon }} text-muted" style="font-size: 3rem;"></i>
|
||||
</div>
|
||||
{% endif %}
|
||||
<p class="text-muted mb-3">{{ emptyMessage|default('Нет данных') }}</p>
|
||||
{% if emptyActionUrl is defined and emptyActionUrl %}
|
||||
<a href="{{ emptyActionUrl }}" class="btn btn-primary">
|
||||
{% if emptyActionIcon is defined and emptyActionIcon %}
|
||||
<i class="{{ emptyActionIcon }} me-2"></i>
|
||||
{% endif %}
|
||||
{{ emptyActionLabel|default('Добавить') }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
|
||||
{# Футер с пагинацией #}
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="{{ columns|length + 1 }}">
|
||||
{{ include('@components/table/pagination.twig', {
|
||||
pagination: pagerDetails,
|
||||
id: id
|
||||
}) }}
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
@@ -0,0 +1,19 @@
|
||||
{#
|
||||
macros.twig - Универсальные макросы для таблиц
|
||||
|
||||
Макросы:
|
||||
- render_actions(actions): Рендерит кнопки действий для строки таблицы
|
||||
#}
|
||||
|
||||
{% macro render_actions(actions) %}
|
||||
<div class="btn-group btn-group-sm">
|
||||
{% for action in actions %}
|
||||
<a href="{{ action.url }}"
|
||||
class="btn {{ action.class|default('btn-outline-primary') }}"
|
||||
title="{{ action.title|default('') }}"
|
||||
{% if action.confirm %}onclick="return confirm('{{ action.confirm }}');"{% endif %}>
|
||||
{% if action.icon %}<i class="{{ action.icon }}"></i>{% endif %}
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endmacro %}
|
||||
@@ -5,20 +5,25 @@
|
||||
- id: ID контейнера таблицы (обязательно)
|
||||
- url: URL для AJAX-загрузки данных (обязательно)
|
||||
- perPage: Количество записей на странице (по умолчанию 10)
|
||||
- columns: Ассоциативный массив ['name' => ['label' => 'Name', 'width' => '40%']]
|
||||
- sort: Текущий столбец сортировки
|
||||
- order: Направление сортировки
|
||||
- filters: Текущие значения фильтров
|
||||
- items: Массив объектов модели (автоматический рендеринг)
|
||||
- rows: Предварительно построенные строки (устаревший формат, для совместимости)
|
||||
- columns: Конфигурация колонок
|
||||
Пример:
|
||||
columns: {
|
||||
name: { label: 'Имя', width: '40%' },
|
||||
email: { label: 'Email' }
|
||||
}
|
||||
- items: Массив объектов для отображения
|
||||
- actionsConfig: Конфигурация действий строки
|
||||
Пример:
|
||||
actionsConfig: [
|
||||
{ label: 'Ред.', url: '/clients/edit/{id}', icon: 'bi bi-pencil', class: 'btn-outline-primary' },
|
||||
{ label: 'Удалить', url: '/clients/delete/{id}', icon: 'bi bi-trash', class: 'btn-outline-danger' }
|
||||
]
|
||||
- emptyMessage: Сообщение при отсутствии данных
|
||||
- emptyActionUrl: URL для кнопки действия (опционально)
|
||||
- emptyActionLabel: Текст кнопки действия (опционально)
|
||||
- emptyIcon: FontAwesome иконка (опционально)
|
||||
- emptyActionUrl: URL для кнопки действия
|
||||
- emptyActionLabel: Текст кнопки
|
||||
- emptyIcon: FontAwesome иконка
|
||||
- tableClass: Дополнительные классы для таблицы
|
||||
#}
|
||||
{% set hasRows = (rows is defined and rows|length > 0) or (items is defined and items|length > 0) %}
|
||||
|
||||
<div id="{{ id }}" class="data-table" data-url="{{ url }}" data-per-page="{{ perPage|default(10) }}">
|
||||
<table class="table table-hover mb-0 {{ tableClass|default('') }}">
|
||||
{# Заголовок таблицы #}
|
||||
@@ -32,40 +37,24 @@
|
||||
|
||||
{# Тело таблицы #}
|
||||
<tbody>
|
||||
{% if hasRows %}
|
||||
{% if rows is defined and rows|length > 0 %}
|
||||
{# Старый формат: предварительно построенные строки #}
|
||||
{% for row in rows %}
|
||||
<tr>
|
||||
{% for cell in row.cells %}
|
||||
<td class="{{ cell.class|default('') }}">{{ cell.content|raw }}</td>
|
||||
{% endfor %}
|
||||
{% if row.actions is defined %}
|
||||
<td class="actions-cell text-end">
|
||||
{{ row.actions|raw }}
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% if items is defined and items|length > 0 %}
|
||||
{% for item in items %}
|
||||
<tr>
|
||||
{# Рендерим каждую колонку #}
|
||||
{% for key, column in columns %}
|
||||
<td>
|
||||
{{ render_cell(item, key, column)|raw }}
|
||||
</td>
|
||||
{% endfor %}
|
||||
{% elseif items is defined and items|length > 0 %}
|
||||
{# Новый формат: автоматический рендеринг из объектов модели #}
|
||||
{% set columnKeys = columns|keys %}
|
||||
{% for item in items %}
|
||||
<tr>
|
||||
{# Ячейки данных #}
|
||||
{% for columnKey in columnKeys %}
|
||||
<td>{{ attribute(item, columnKey)|default('—') }}</td>
|
||||
{% endfor %}
|
||||
|
||||
{# Колонка действий #}
|
||||
{% if actions is defined and actions %}
|
||||
<td class="actions-cell text-end">
|
||||
{% if item.actions is defined %}{{ item.actions|raw }}{% endif %}
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{# Колонка действий #}
|
||||
{% if actionsConfig is defined and actionsConfig|length > 0 %}
|
||||
<td class="actions-cell text-end">
|
||||
{{ render_actions(item, actionsConfig)|raw }}
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{# Пустое состояние #}
|
||||
<tr>
|
||||
@@ -76,7 +65,7 @@
|
||||
<i class="{{ emptyIcon }} text-muted" style="font-size: 3rem;"></i>
|
||||
</div>
|
||||
{% endif %}
|
||||
<p class="text-muted mb-3">{{ emptyMessage|default('Нет данных для отображения') }}</p>
|
||||
<p class="text-muted mb-3">{{ emptyMessage|default('Нет данных') }}</p>
|
||||
{% if emptyActionUrl is defined and emptyActionUrl %}
|
||||
<a href="{{ emptyActionUrl }}" class="btn btn-primary">
|
||||
{% if emptyActionIcon is defined and emptyActionIcon %}
|
||||
@@ -90,6 +79,7 @@
|
||||
{% endif %}
|
||||
</tbody>
|
||||
|
||||
{# Футер с пагинацией #}
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="{{ columns|length + 1 }}">
|
||||
|
||||
Reference in New Issue
Block a user