Files
shopPRO/admin/templates/components/table-list.php

345 lines
14 KiB
PHP

<?php
$list = $this->list;
$buildUrl = function(array $params = []) use ($list): string {
$query = array_merge($list->query, $params);
foreach ($query as $key => $value) {
if ($value === '' || $value === null) {
unset($query[$key]);
}
}
$qs = http_build_query($query);
return $list->basePath . ($qs ? ('?' . $qs) : '');
};
$currentSort = $list->sort['column'] ?? '';
$currentDir = strtoupper($list->sort['dir'] ?? 'DESC');
$page = max(1, (int)($list->pagination['page'] ?? 1));
$totalPages = max(1, (int)($list->pagination['total_pages'] ?? 1));
$total = (int)($list->pagination['total'] ?? 0);
$perPage = (int)($list->pagination['per_page'] ?? 15);
?>
<div class="panel">
<div class="panel-heading">
<div class="row">
<div class="col-sm-8">
<?php if (!empty($list->createUrl) && !empty($list->createLabel)): ?>
<a href="<?= htmlspecialchars($list->createUrl, ENT_QUOTES, 'UTF-8'); ?>" class="btn btn-success btn-sm">
<i class="fa fa-plus-circle mr5"></i><?= htmlspecialchars($list->createLabel, ENT_QUOTES, 'UTF-8'); ?>
</a>
<?php endif; ?>
</div>
<div class="col-sm-4 text-right">
<span class="text-muted">Wyników: <?= $total; ?></span>
</div>
</div>
</div>
<div class="panel-body">
<form method="get" action="<?= htmlspecialchars($list->basePath, ENT_QUOTES, 'UTF-8'); ?>" class="row mb15 js-table-filters-form">
<?php foreach ($list->filters as $filter): ?>
<?php
$filterKey = (string)($filter['key'] ?? '');
$inputId = 'filter_' . preg_replace('/[^a-zA-Z0-9_]+/', '_', $filterKey);
?>
<div class="col-sm-2 mb10">
<label for="<?= htmlspecialchars($inputId, ENT_QUOTES, 'UTF-8'); ?>" class="control-label">
<?= htmlspecialchars((string)($filter['label'] ?? ''), ENT_QUOTES, 'UTF-8'); ?>
</label>
<?php if (($filter['type'] ?? '') === 'select'): ?>
<select
id="<?= htmlspecialchars($inputId, ENT_QUOTES, 'UTF-8'); ?>"
name="<?= htmlspecialchars($filter['key'], ENT_QUOTES, 'UTF-8'); ?>"
class="form-control input-sm"
title="<?= htmlspecialchars($filter['label'], ENT_QUOTES, 'UTF-8'); ?>"
>
<?php foreach (($filter['options'] ?? []) as $value => $label): ?>
<option value="<?= htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8'); ?>"<?= ((string)($filter['value'] ?? '') === (string)$value) ? ' selected="selected"' : ''; ?>>
<?= htmlspecialchars((string)$label, ENT_QUOTES, 'UTF-8'); ?>
</option>
<?php endforeach; ?>
</select>
<?php elseif (($filter['type'] ?? '') === 'date'): ?>
<input
type="date"
id="<?= htmlspecialchars($inputId, ENT_QUOTES, 'UTF-8'); ?>"
name="<?= htmlspecialchars($filter['key'], ENT_QUOTES, 'UTF-8'); ?>"
value="<?= htmlspecialchars((string)($filter['value'] ?? ''), ENT_QUOTES, 'UTF-8'); ?>"
class="form-control input-sm"
title="<?= htmlspecialchars($filter['label'], ENT_QUOTES, 'UTF-8'); ?>"
/>
<?php else: ?>
<input
type="text"
id="<?= htmlspecialchars($inputId, ENT_QUOTES, 'UTF-8'); ?>"
name="<?= htmlspecialchars($filter['key'], ENT_QUOTES, 'UTF-8'); ?>"
value="<?= htmlspecialchars((string)($filter['value'] ?? ''), ENT_QUOTES, 'UTF-8'); ?>"
class="form-control input-sm"
placeholder="<?= htmlspecialchars($filter['label'], ENT_QUOTES, 'UTF-8'); ?>"
title="<?= htmlspecialchars($filter['label'], ENT_QUOTES, 'UTF-8'); ?>"
/>
<?php endif; ?>
</div>
<?php endforeach; ?>
<input type="hidden" name="sort" value="<?= htmlspecialchars((string)$currentSort, ENT_QUOTES, 'UTF-8'); ?>" />
<input type="hidden" name="dir" value="<?= htmlspecialchars((string)$currentDir, ENT_QUOTES, 'UTF-8'); ?>" />
<input type="hidden" name="per_page" value="<?= $perPage; ?>" />
<div class="col-sm-12">
<button type="submit" class="btn btn-primary btn-sm">Szukaj</button>
<a href="<?= htmlspecialchars($list->basePath, ENT_QUOTES, 'UTF-8'); ?>" class="btn btn-default btn-sm">Wyczyść</a>
</div>
</form>
<div class="table-responsive">
<table class="table table-hover table-striped table-bordered mbn table-list-table">
<thead>
<tr>
<?php foreach ($list->columns as $column): ?>
<?php
$sortKey = (string)($column['sort_key'] ?? ($column['key'] ?? ''));
$isAllowedSortKey = empty($list->sortableColumns) || in_array($sortKey, $list->sortableColumns, true);
$isSortable = !empty($column['sortable']) && $sortKey !== '' && $isAllowedSortKey;
$isCurrent = $isSortable && $currentSort === $sortKey;
$nextDir = ($isCurrent && $currentDir === 'ASC') ? 'DESC' : 'ASC';
$sortUrl = $buildUrl([
'sort' => $sortKey,
'dir' => $nextDir,
'page' => 1,
]);
?>
<th class="<?= htmlspecialchars((string)($column['class'] ?? ''), ENT_QUOTES, 'UTF-8'); ?>">
<?php if ($isSortable): ?>
<a href="<?= htmlspecialchars($sortUrl, ENT_QUOTES, 'UTF-8'); ?>">
<?= htmlspecialchars((string)($column['label'] ?? ''), ENT_QUOTES, 'UTF-8'); ?>
<?php if ($isCurrent): ?>
<span aria-hidden="true"><?= $currentDir === 'ASC' ? '↑' : '↓'; ?></span>
<?php else: ?>
<span class="text-muted" aria-hidden="true">↕</span>
<?php endif; ?>
</a>
<?php else: ?>
<?= htmlspecialchars((string)($column['label'] ?? ''), ENT_QUOTES, 'UTF-8'); ?>
<?php endif; ?>
</th>
<?php endforeach; ?>
<th class="text-center" style="width: 160px;">Akcje</th>
</tr>
</thead>
<tbody>
<?php if (is_array($list->rows) && !empty($list->rows)): ?>
<?php foreach ($list->rows as $row): ?>
<tr>
<?php foreach ($list->columns as $column): ?>
<?php
$key = $column['key'] ?? '';
$raw = !empty($column['raw']);
$value = $row[$key] ?? '';
?>
<td class="<?= htmlspecialchars((string)($column['class'] ?? ''), ENT_QUOTES, 'UTF-8'); ?>">
<?php if ($raw): ?>
<?= (string)$value; ?>
<?php else: ?>
<?= htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8'); ?>
<?php endif; ?>
</td>
<?php endforeach; ?>
<td class="text-center">
<?php foreach (($row['_actions'] ?? []) as $action): ?>
<?php
$confirmMessage = (string)($action['confirm'] ?? '');
$needsConfirm = $confirmMessage !== '';
$actionClass = (string)($action['class'] ?? 'btn btn-default btn-xs');
if ($needsConfirm) {
$actionClass .= ' js-table-action-confirm';
}
?>
<a
href="<?= htmlspecialchars((string)($action['url'] ?? '#'), ENT_QUOTES, 'UTF-8'); ?>"
class="<?= htmlspecialchars($actionClass, ENT_QUOTES, 'UTF-8'); ?>"
<?php if ($needsConfirm): ?>
data-confirm-title="Potwierdzenie"
data-confirm-message="<?= htmlspecialchars($confirmMessage, ENT_QUOTES, 'UTF-8'); ?>"
data-confirm-ok="<?= htmlspecialchars((string)($action['confirm_ok'] ?? 'Usun'), ENT_QUOTES, 'UTF-8'); ?>"
data-confirm-cancel="<?= htmlspecialchars((string)($action['confirm_cancel'] ?? 'Anuluj'), ENT_QUOTES, 'UTF-8'); ?>"
<?php endif; ?>
>
<?= htmlspecialchars((string)($action['label'] ?? ''), ENT_QUOTES, 'UTF-8'); ?>
</a>
<?php endforeach; ?>
</td>
</tr>
<?php endforeach; ?>
<?php else: ?>
<tr>
<td colspan="<?= count($list->columns) + 1; ?>">
<div class="alert alert-danger mbn"><?= htmlspecialchars((string)$list->emptyMessage, ENT_QUOTES, 'UTF-8'); ?></div>
</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
<div class="row mt15">
<div class="col-sm-6">
<ul class="pagination">
<?php $prevPage = max(1, $page - 1); ?>
<?php $nextPage = min($totalPages, $page + 1); ?>
<li class="<?= $page <= 1 ? 'disabled' : ''; ?>">
<a href="<?= htmlspecialchars($buildUrl(['page' => 1]), ENT_QUOTES, 'UTF-8'); ?>"><i class="fa fa-fast-backward"></i></a>
</li>
<li class="<?= $page <= 1 ? 'disabled' : ''; ?>">
<a href="<?= htmlspecialchars($buildUrl(['page' => $prevPage]), ENT_QUOTES, 'UTF-8'); ?>"><i class="fa fa-backward"></i></a>
</li>
<?php for ($i = max(1, $page - 3); $i <= min($totalPages, $page + 3); $i++): ?>
<li class="<?= $i === $page ? 'active' : ''; ?>">
<a href="<?= htmlspecialchars($buildUrl(['page' => $i]), ENT_QUOTES, 'UTF-8'); ?>"><?= $i; ?></a>
</li>
<?php endfor; ?>
<li class="<?= $page >= $totalPages ? 'disabled' : ''; ?>">
<a href="<?= htmlspecialchars($buildUrl(['page' => $nextPage]), ENT_QUOTES, 'UTF-8'); ?>"><i class="fa fa-forward"></i></a>
</li>
<li class="<?= $page >= $totalPages ? 'disabled' : ''; ?>">
<a href="<?= htmlspecialchars($buildUrl(['page' => $totalPages]), ENT_QUOTES, 'UTF-8'); ?>"><i class="fa fa-fast-forward"></i></a>
</li>
</ul>
</div>
<div class="col-sm-6 text-right">
<form method="get" action="<?= htmlspecialchars($list->basePath, ENT_QUOTES, 'UTF-8'); ?>" class="form-inline">
<?php foreach ($list->query as $key => $value): ?>
<?php if ($key !== 'per_page' && $key !== 'page'): ?>
<input type="hidden" name="<?= htmlspecialchars((string)$key, ENT_QUOTES, 'UTF-8'); ?>" value="<?= htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8'); ?>" />
<?php endif; ?>
<?php endforeach; ?>
<input type="hidden" name="page" value="1" />
Wyświetlaj
<select name="per_page" class="form-control input-sm" onchange="this.form.submit()">
<?php foreach ($list->perPageOptions as $opt): ?>
<option value="<?= (int)$opt; ?>"<?= ((int)$opt === $perPage) ? ' selected="selected"' : ''; ?>><?= (int)$opt; ?></option>
<?php endforeach; ?>
</select>
rekordów
</form>
</div>
</div>
</div>
</div>
<style type="text/css">
.table-list-table th:first-child,
.table-list-table td:first-child {
width: 70px;
white-space: nowrap;
}
.jconfirm.table-list-confirm-dialog .jconfirm-row {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.jconfirm.table-list-confirm-dialog .jconfirm-box-container {
width: 100%;
max-width: 560px;
padding-left: 12px;
padding-right: 12px;
margin: 0 auto;
}
.jconfirm.table-list-confirm-dialog .jconfirm-box {
width: 100% !important;
}
</style>
<script type="text/javascript">
(function($) {
if (!$) {
return;
}
$(document).off('click.tableListConfirm', '.js-table-action-confirm');
$(document).on('click.tableListConfirm', '.js-table-action-confirm', function(e) {
e.preventDefault();
var $link = $(this);
var href = $link.attr('href');
var title = $link.data('confirmTitle') || 'Potwierdzenie';
var message = $link.data('confirmMessage') || 'Czy na pewno chcesz kontynuowac?';
var okLabel = $link.data('confirmOk') || 'Usun';
var cancelLabel = $link.data('confirmCancel') || 'Anuluj';
if (!href) {
return false;
}
if (typeof $.confirm === 'function') {
$.confirm({
title: String(title),
content: String(message),
type: 'red',
boxWidth: '560px',
useBootstrap: false,
animation: 'scale',
closeAnimation: 'scale',
backgroundDismissAnimation: 'shake',
container: 'body',
theme: 'modern',
columnClass: '',
typeAnimated: true,
lazyOpen: false,
draggable: false,
closeIcon: true,
containerFluid: true,
escapeKey: true,
backgroundDismiss: true,
animationBounce: 1.1,
watchInterval: 100,
offsetTop: 0,
offsetBottom: 0,
customClass: 'table-list-confirm-dialog',
buttons: {
cancel: {
text: String(cancelLabel),
btnClass: 'btn-default'
},
confirm: {
text: String(okLabel),
btnClass: 'btn-danger',
action: function() {
window.location.href = href;
}
}
}
});
return false;
}
if (window.confirm(String(message))) {
window.location.href = href;
}
return false;
});
$(document).off(
'change.tableListAutoFilter',
'.js-table-filters-form select, .js-table-filters-form input[type="date"], .js-table-filters-form input[type="text"]'
);
$(document).on(
'change.tableListAutoFilter',
'.js-table-filters-form select, .js-table-filters-form input[type="date"], .js-table-filters-form input[type="text"]',
function() {
var form = $(this).closest('form');
if (form.length) {
form.trigger('submit');
}
}
);
})(window.jQuery);
</script>