Files
pomysloweprezenty.pl/admin/templates/components/grid-edit-replacement.php
Jacek Pyziak 3ecbe628dc Add view classes for articles, banners, languages, menu, newsletter, containers, shop categories, clients, payment methods, products, and search
- Created Articles.php for rendering article views including full articles, miniature lists, and news sections.
- Added Banners.php for handling banner displays.
- Introduced Languages.php for rendering language options.
- Implemented Menu.php for dynamic menu rendering.
- Developed Newsletter.php for newsletter view rendering.
- Created Scontainers.php for rendering specific containers.
- Added ShopCategory.php for category descriptions and product listings.
- Introduced ShopClient.php for managing client-related views such as address editing and order history.
- Implemented ShopPaymentMethod.php for displaying payment methods in the basket.
- Created ShopProduct.php for generating product URLs.
- Added ShopSearch.php for rendering a simple search form.
- Added .htaccess file to enhance security by restricting access to sensitive files and directories.
2026-02-21 23:00:15 +01:00

172 lines
6.8 KiB
PHP

<?php
/**
* Zastepnik gridEdit — generuje panel z przyciskami zapisu/anulowania i formularzem.
*
* Wymagane zmienne:
* $gridId — identyfikator formularza (np. 'layout-edit')
* $gridTitle — tytuł panelu
* $gridSaveUrl — URL zapisu (AJAX POST)
* $gridBackUrl — URL powrotu po zapisie / anulowaniu
* $gridHidden — tablica ukrytych pól [['name' => ..., 'value' => ...], ...]
* $gridContent — HTML zawartość formularza (z ob_get_clean())
* $gridPersist — (bool) czy zostać na stronie po zapisie
*/
$gridPersist = !empty($gridPersist);
?>
<!-- iCheck -->
<link rel="stylesheet" type="text/css" href="/libraries/grid/plugins/icheck/skins/minimal/minimal.css" />
<link rel="stylesheet" type="text/css" href="/libraries/grid/plugins/icheck/skins/minimal/blue.css" />
<script type="text/javascript" src="/libraries/grid/plugins/icheck/icheck.min.js"></script>
<!-- impromptu -->
<link rel="stylesheet" type="text/css" href="/libraries/grid/plugins/impromptu/jquery-impromptu.css" />
<script type="text/javascript" src="/libraries/grid/plugins/impromptu/jquery-impromptu.js"></script>
<div class="row">
<div class="col col-xs-12">
<div class="g-container" data="table:<?= htmlspecialchars($gridId) ?>">
<div class="panel panel-info panel-border top">
<div class="panel-heading">
<span class="panel-title"><?= htmlspecialchars($gridTitle) ?></span>
</div>
<?php if (!empty($gridSaveUrl)): ?>
<div class="panel-heading p10 pl15" id="g-menu" style="height: auto;">
<?php if ($gridPersist): ?>
<a href="#" id="g-edit-save-close" class="btn btn-system btn-sm"
persist_edit="0"
back_url="<?= htmlspecialchars($gridBackUrl) ?>"
url="<?= htmlspecialchars($gridSaveUrl) ?>">
<i class="fa fa-check-circle mr5"></i>Zatwierdź i zamknij
</a>
<?php endif; ?>
<a href="#" id="g-edit-save" class="btn btn-success btn-sm"
persist_edit="<?= $gridPersist ? '1' : '0' ?>"
id_param="id"
back_url="<?= htmlspecialchars($gridBackUrl) ?>"
url="<?= htmlspecialchars($gridSaveUrl) ?>">
<i class="fa fa-check-circle mr5"></i>Zatwierdź
</a>
<a href="<?= htmlspecialchars($gridBackUrl) ?>" class="btn btn-dark btn-sm" id="g-edit-cancel">
<i class="fa fa-reply mr5"></i>Wstecz
</a>
</div>
<?php endif; ?>
<div class="panel-body">
<form method="POST" id="fg-<?= htmlspecialchars($gridId) ?>" class="g-form form-horizontal" enctype="multipart/form-data">
<?php if (!empty($gridHidden) && is_array($gridHidden)): ?>
<?php foreach ($gridHidden as $h): ?>
<input type="hidden" name="<?= htmlspecialchars($h['name']) ?>" id="<?= htmlspecialchars($h['name']) ?>" value="<?= htmlspecialchars($h['value'] ?? '') ?>" />
<?php endforeach; ?>
<?php endif; ?>
<?= $gridContent ?>
</form>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
jQuery(function() {
jQuery('.g-checkbox, .g-radio, .icheck').iCheck({
checkboxClass: 'icheckbox_minimal-blue',
radioClass: 'iradio_minimal-blue'
});
function showGridMessage(type, text) {
var safeText = $('<div/>').text(text || '').html();
var alertClass = type === 'error' ? 'alert-danger' : 'alert-primary';
var html = '<div class="row js-form-message"><div class="col col-xs-12"><div class="alert ' + alertClass + ' alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button><i class="fa fa-info pr10"></i>' + safeText + '</div></div></div>';
$('#content .js-form-message').remove();
$('#content').prepend(html);
}
$('#g-edit-save, #g-edit-save-close').on('click', function(e) {
e.preventDefault();
var $btn = $(this);
var url = $btn.attr('url');
var backUrl = $btn.attr('back_url');
var persist = $btn.attr('persist_edit');
var formId = 'fg-<?= $gridId ?>';
if (typeof CKEDITOR !== 'undefined' && CKEDITOR.instances) {
for (var i in CKEDITOR.instances) {
if (CKEDITOR.instances.hasOwnProperty(i)) CKEDITOR.instances[i].updateElement();
}
}
// Serializacja kompatybilna z grid.js — JSON w parametrze 'values'
var values = $('#' + formId).serializeArray();
var formattedValues = {};
$.each(values, function(i, field) {
var fieldName = field.name.replace(/\[\]$/, '');
var nestedMatch = fieldName.match(/^(.+?)\[(.+?)\]$/);
if (nestedMatch) {
var mainField = nestedMatch[1];
var subField = nestedMatch[2];
if (!formattedValues[mainField]) {
formattedValues[mainField] = {};
}
formattedValues[mainField][subField] = field.value;
} else if (field.name.indexOf('[]', field.name.length - 2) !== -1) {
if (!formattedValues[fieldName]) {
formattedValues[fieldName] = [];
}
formattedValues[fieldName].push(field.value);
} else {
formattedValues[fieldName] = field.value;
}
});
// Normalizacja checkboxów tablicowych (boolean-like)
(function() {
var $form = $('#' + formId);
var groups = {};
$form.find('input[type="checkbox"][name$="[]"]').each(function() {
var n = this.name;
(groups[n] = groups[n] || []).push(this);
});
$.each(groups, function(nameWithBrackets, inputs) {
var vals = {};
$.each(inputs, function(_, el) { vals[(el.getAttribute('value') || '').toLowerCase()] = true; });
var boolSet = {'': true, '1': true, 'on': true, 'true': true, 'yes': true};
var isBool = true;
$.each(vals, function(v) { if (!boolSet[v]) isBool = false; });
if (isBool) {
var baseKey = nameWithBrackets.replace(/\[\]$/, '');
formattedValues[baseKey] = $.map(inputs, function(el) { return el.checked ? '1' : '0'; });
}
});
})();
$.ajax({
url: url,
type: 'POST',
data: {
gtable: formId.replace('fg-', ''),
values: JSON.stringify(formattedValues),
a: 'gsave'
},
dataType: 'json',
success: function(r) {
if (r.status === 'ok' || r.success) {
if (backUrl && persist === '0') {
window.location.href = backUrl;
} else {
showGridMessage('success', r.msg || r.message || 'Zmiany zostały zapisane.');
if (r.id) {
$('#fg-' + formId.replace('fg-','') + ' input[name="id"]').val(r.id);
}
}
} else {
showGridMessage('error', r.msg || r.message || 'Wystąpił błąd.');
}
},
error: function() {
showGridMessage('error', 'Wystąpił błąd połączenia.');
}
});
});
});
</script>