update component
This commit is contained in:
@ -144,7 +144,11 @@ if ($canAdmin) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($item->image): ?>
|
||||
<div class="mb-4">
|
||||
<img src="/<?php echo $item->image ?>" alt="" class="img-fluid h-50 w-100 shadow-sm" style="border-radius: 15px;">
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ($item->firma_obbligatoria && $this->getModel()->userCanFirmare($item->id, $this->getModel()->currentUser->id) && !empty($buttons)) : ?>
|
||||
<div class="mt-4">
|
||||
<div class="d-flex flex-wrap gap-2" data-sign-group="circolare-<?php echo (int)$item->id; ?>">
|
||||
@ -171,8 +175,7 @@ if ($canAdmin) {
|
||||
</button>
|
||||
<?php else: ?>
|
||||
<form method="post"
|
||||
action="<?=
|
||||
Route::_('index.php?option=com_circolari&task=circolare.sign&id=' . (int)$item->id); ?>"
|
||||
action="<?= Route::_('index.php?option=com_circolari&task=circolare.sign&id=' . (int)$item->id); ?>"
|
||||
class="d-inline-block">
|
||||
<input type="hidden" name="bottone_id" value="<?php echo $btnId; ?>">
|
||||
<button type="submit"
|
||||
@ -190,52 +193,139 @@ if ($canAdmin) {
|
||||
<div class="article-body mt-3">
|
||||
<?php echo $item->description; ?>
|
||||
</div>
|
||||
<h6>Allegati</h6>
|
||||
<?php
|
||||
$href = htmlspecialchars((string)($item->attachment ?? ''), ENT_QUOTES, 'UTF-8');
|
||||
$label = htmlspecialchars((string)($item->allegato_titolo ?: 'Allegato'), ENT_QUOTES, 'UTF-8');
|
||||
$title = 'Scarica ' . $label;
|
||||
?>
|
||||
<div class="row g-3 mb-2">
|
||||
<div class="col-12 col-lg-6">
|
||||
<div class="card card-documento card-bg card-icon rounded shadow-sm h-100">
|
||||
<div class="card-body d-flex align-items-center">
|
||||
<svg class="icon" aria-hidden="true" focusable="false" style="fill:#d1344c;">
|
||||
<use xlink:href="/media/templates/site/tpl_istituzionale/images/sprites.svg#it-file-pdf"></use>
|
||||
</svg>
|
||||
<div class="card-icon-content">
|
||||
<p class="mb-0">
|
||||
<a
|
||||
class="text-decoration-none"
|
||||
href="<?php echo $href; ?>"
|
||||
download
|
||||
title="<?php echo htmlspecialchars($title, ENT_QUOTES, 'UTF-8'); ?>"
|
||||
data-focus-mouse="false"
|
||||
>
|
||||
<strong><?php echo $label; ?></strong>
|
||||
<span class="visually-hidden"> (file PDF)</span>
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
// Normalizza lista allegati: prima prova array $item->attachments (nuova logica),
|
||||
// altrimenti fallback ai vecchi campi singoli $item->attachment / $item->allegato_titolo.
|
||||
$attachments = [];
|
||||
|
||||
// 1) Nuova logica: array di allegati dal Model (path, title, ordering)
|
||||
if (!empty($item->attachments) && is_array($item->attachments)) {
|
||||
foreach ($item->attachments as $att) {
|
||||
$path = (string) ($att['path'] ?? ($att->path ?? ''));
|
||||
if ($path === '') continue;
|
||||
$title = (string) ($att['title'] ?? ($att->title ?? ''));
|
||||
$ord = (int) ($att['ordering'] ?? ($att->ordering ?? 0));
|
||||
$attachments[] = ['href' => $path, 'label' => $title, 'ordering' => $ord];
|
||||
}
|
||||
}
|
||||
|
||||
// 2) Fallback legacy: singolo allegato
|
||||
if (empty($attachments) && !empty($item->attachment)) {
|
||||
$attachments[] = [
|
||||
'href' => (string) $item->attachment,
|
||||
'label' => (string) ($item->allegato_titolo ?: ''),
|
||||
'ordering' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
// Ordina per ordering, poi per label
|
||||
usort($attachments, function ($a, $b) {
|
||||
$o = ($a['ordering'] <=> $b['ordering']);
|
||||
if ($o !== 0) return $o;
|
||||
return strcmp((string)$a['label'], (string)$b['label']);
|
||||
});
|
||||
|
||||
// Mappa icone in base all'estensione (puoi adattare gli id alle tue sprite)
|
||||
$spritePath = '/media/templates/site/tpl_istituzionale/images/sprites.svg';
|
||||
function _att_icon_id(string $ext): string
|
||||
{
|
||||
$ext = strtolower($ext);
|
||||
if (in_array($ext, ['pdf'], true)) return 'it-file-pdf';
|
||||
if (in_array($ext, ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'svg', 'tif', 'tiff', 'heic', 'heif'], true)) return 'it-file-image';
|
||||
if (in_array($ext, ['doc', 'docx', 'rtf', 'odt'], true)) return 'it-file-doc';
|
||||
if (in_array($ext, ['xls', 'xlsx', 'ods', 'csv'], true)) return 'it-file-xls';
|
||||
if (in_array($ext, ['ppt', 'pptx', 'odp'], true)) return 'it-file-ppt';
|
||||
if (in_array($ext, ['zip', 'rar', '7z', 'gz', 'bz2', 'tar'], true)) return 'it-file-zip';
|
||||
return 'it-file'; // generico
|
||||
}
|
||||
?>
|
||||
|
||||
<?php if (!empty($attachments)): ?>
|
||||
<h6 class="mt-4"><?php echo JText::_('Allegati'); ?></h6>
|
||||
<div class="row g-3 mb-2">
|
||||
<?php foreach ($attachments as $att):
|
||||
$hrefRaw = (string) ($att['href'] ?? '');
|
||||
$labelRaw = (string) ($att['label'] ?? '');
|
||||
// Fallback label = basename del file se non presente
|
||||
$basename = basename(htmlspecialchars_decode($hrefRaw));
|
||||
$label = trim($labelRaw) !== '' ? $labelRaw : $basename;
|
||||
|
||||
// Estensione per icona e testo accessibile
|
||||
$ext = strtolower(pathinfo($basename, PATHINFO_EXTENSION));
|
||||
if ($ext === 'jpeg') {
|
||||
$ext = 'jpg';
|
||||
} // coerenza
|
||||
$iconId = _att_icon_id($ext);
|
||||
|
||||
$href = htmlspecialchars($hrefRaw, ENT_QUOTES, 'UTF-8');
|
||||
$labelEsc = htmlspecialchars($label, ENT_QUOTES, 'UTF-8');
|
||||
$titleAttr = 'Scarica ' . $label;
|
||||
$titleEsc = htmlspecialchars($titleAttr, ENT_QUOTES, 'UTF-8');
|
||||
|
||||
// Testo accessibile sul tipo file (es. "file PDF", "file immagine", ecc.)
|
||||
$a11yType = '';
|
||||
switch ($iconId) {
|
||||
case 'it-file-pdf':
|
||||
$a11yType = ' (file PDF)';
|
||||
break;
|
||||
case 'it-file-image':
|
||||
$a11yType = ' (file immagine)';
|
||||
break;
|
||||
case 'it-file-doc':
|
||||
$a11yType = ' (documento)';
|
||||
break;
|
||||
case 'it-file-xls':
|
||||
$a11yType = ' (foglio di calcolo)';
|
||||
break;
|
||||
case 'it-file-ppt':
|
||||
$a11yType = ' (presentazione)';
|
||||
break;
|
||||
case 'it-file-zip':
|
||||
$a11yType = ' (archivio compresso)';
|
||||
break;
|
||||
default:
|
||||
$a11yType = $ext ? ' (file .' . htmlspecialchars($ext, ENT_QUOTES, 'UTF-8') . ')' : '';
|
||||
}
|
||||
?>
|
||||
<div class="col-12 col-lg-6">
|
||||
<div class="card card-documento card-bg card-icon rounded shadow-sm h-100">
|
||||
<div class="card-body d-flex align-items-center">
|
||||
<svg class="icon" aria-hidden="true" focusable="false" style="fill:#d1344c;">
|
||||
<use xlink:href="<?php echo $spritePath . '#' . $iconId; ?>"></use>
|
||||
</svg>
|
||||
<div class="card-icon-content">
|
||||
<p class="mb-0">
|
||||
<a
|
||||
class="text-decoration-none"
|
||||
href="<?php echo $href; ?>"
|
||||
download
|
||||
title="<?php echo $titleEsc; ?>"
|
||||
data-focus-mouse="false">
|
||||
<strong><?php echo $labelEsc; ?></strong>
|
||||
<span class="visually-hidden"><?php echo $a11yType; ?></span>
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.card.card-icon .icon {
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
flex-shrink: 0;
|
||||
margin: 0 8px 0 0;
|
||||
}
|
||||
<style>
|
||||
.card.card-icon .icon {
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
flex-shrink: 0;
|
||||
margin: 0 8px 0 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
<?php if ($canAdmin): ?>
|
||||
<?php if ($canAdmin & $item->firma_obbligatoria): ?>
|
||||
<div class="card mt-4">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<strong>Firme ricevute</strong>
|
||||
|
||||
@ -7,6 +7,8 @@ use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Uri\Uri;
|
||||
use Joomla\CMS\Editor\Editor;
|
||||
use Joomla\CMS\Plugin\PluginHelper;
|
||||
|
||||
HTMLHelper::_('bootstrap.tooltip');
|
||||
HTMLHelper::_('behavior.formvalidator');
|
||||
@ -28,141 +30,299 @@ foreach ((array) $menu->getItems('component_id', (int) $component->id) as $mi) {
|
||||
$cancelUrl = $cancelItemId
|
||||
? Route::_('index.php?Itemid=' . $cancelItemId)
|
||||
: Uri::root() . 'index.php?option=com_circolari&view=circolari';
|
||||
|
||||
// Editor preferito (CKEditor se attivo, altrimenti editor di default)
|
||||
$preferred = 'ckeditor';
|
||||
$editorName = PluginHelper::isEnabled('editors', $preferred)
|
||||
? $preferred
|
||||
: Factory::getApplication()->get('editor');
|
||||
$editor = Editor::getInstance($editorName);
|
||||
|
||||
// Helper piccole funzioni
|
||||
function e($s){ return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); }
|
||||
?>
|
||||
<div class="container py-3">
|
||||
<h2 class="mb-3"><?php echo Text::_('Nuova circolare'); ?></h2>
|
||||
<h2 class="mb-3"><?php echo $item->id ?? '' ? Text::_('Modifica circolare') : Text::_('Nuova circolare'); ?></h2>
|
||||
|
||||
<form action="<?php echo Route::_('index.php?option=com_circolari&task=form.save'); ?>" method="post" class="form-validate">
|
||||
<form action="<?php echo $action; ?>" method="post" name="adminForm" id="adminForm"
|
||||
class="form-validate" enctype="multipart/form-data">
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="title"><?php echo Text::_('Titolo'); ?></label>
|
||||
<input type="text" id="title" name="title" required
|
||||
class="form-control"
|
||||
value="<?php echo htmlspecialchars($item->title ?? '', ENT_QUOTES, 'UTF-8'); ?>">
|
||||
</div>
|
||||
<ul class="nav nav-tabs" id="circolareTabs" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active" id="tab-contenuto" data-bs-toggle="tab" data-bs-target="#pane-contenuto" type="button" role="tab" aria-controls="pane-contenuto" aria-selected="true">
|
||||
<?php echo Text::_('Contenuto'); ?>
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" id="tab-media" data-bs-toggle="tab" data-bs-target="#pane-media" type="button" role="tab" aria-controls="pane-media" aria-selected="false">
|
||||
<?php echo Text::_('Immagini/Allegati'); ?>
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" id="tab-firma" data-bs-toggle="tab" data-bs-target="#pane-firma" type="button" role="tab" aria-controls="pane-firma" aria-selected="false">
|
||||
<?php echo Text::_('Firma'); ?>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="alias"><?php echo Text::_('Alias (opzionale)'); ?></label>
|
||||
<input type="text" id="alias" name="alias" class="form-control"
|
||||
value="<?php echo htmlspecialchars($item->alias ?? '', ENT_QUOTES, 'UTF-8'); ?>">
|
||||
</div>
|
||||
<div class="tab-content border border-top-0 rounded-bottom p-3 shadow-sm" id="circolareTabsContent">
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="categoria_id"><?php echo Text::_('Categoria'); ?></label>
|
||||
<select id="categoria_id" name="categoria_id" class="form-select" required>
|
||||
<option value="0">-- <?php echo Text::_('Seleziona'); ?> --</option>
|
||||
<?php foreach ((array) $this->categorie as $c):
|
||||
$cid = (int) ($c['id'] ?? 0);
|
||||
$ctitle = (string) ($c['title'] ?? '');
|
||||
$cstate = (int) ($c['state'] ?? 1);
|
||||
if ($cstate !== 1) continue; // solo pubblicate
|
||||
?>
|
||||
<option value="<?php echo $cid; ?>"
|
||||
<?php echo (!empty($item->categoria_id) && (int)$item->categoria_id === $cid) ? 'selected' : ''; ?>>
|
||||
<?php echo htmlspecialchars($ctitle, ENT_QUOTES, 'UTF-8'); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="tab-pane fade show active" id="pane-contenuto" role="tabpanel" aria-labelledby="tab-contenuto" tabindex="0">
|
||||
<div class="row g-3">
|
||||
<div class="col-lg-8">
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="title"><?php echo Text::_('Titolo'); ?></label>
|
||||
<input type="text" id="title" name="title" required class="form-control"
|
||||
value="<?php echo e($item->title ?? ''); ?>">
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="description"><?php echo Text::_('Testo'); ?></label>
|
||||
<textarea id="description" name="description" class="form-control" rows="8"><?php
|
||||
echo htmlspecialchars($item->description ?? '', ENT_QUOTES, 'UTF-8');
|
||||
?></textarea>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="description"><?php echo Text::_('Testo'); ?></label>
|
||||
<?php
|
||||
$desc = !empty($item->description) ? $item->description : '';
|
||||
echo $editor->display('description', $desc, '100%', '320', '60', '20', true);
|
||||
?>
|
||||
<div class="form-text"><?php echo Text::_('Inserisci il contenuto della circolare.'); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label" for="state"><?php echo Text::_('Stato'); ?></label>
|
||||
<select id="state" name="state" class="form-select">
|
||||
<option value="1" <?php echo ((int)($item->state ?? 1) === 1 ? 'selected' : ''); ?>>
|
||||
<?php echo Text::_('Pubblicata'); ?>
|
||||
</option>
|
||||
<option value="0" <?php echo ((int)($item->state ?? 1) === 0 ? 'selected' : ''); ?>>
|
||||
<?php echo Text::_('Bozza/Non pubblicata'); ?>
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="card h-100">
|
||||
<div class="card-body">
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="alias"><?php echo Text::_('Alias (opzionale)'); ?></label>
|
||||
<input type="text" id="alias" name="alias" class="form-control" value="<?php echo e($item->alias ?? ''); ?>">
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<label class="form-label" for="jform_firma_obbligatoria"><?php echo Text::_('Firma obbligatoria'); ?></label>
|
||||
<?php $fo = (int) ($item->firma_obbligatoria ?? 0); ?>
|
||||
<select name="firma_obbligatoria" id="jform_firma_obbligatoria" class="form-select">
|
||||
<option value="0" <?php echo $fo === 0 ? 'selected' : ''; ?>><?php echo Text::_('No'); ?></option>
|
||||
<option value="1" <?php echo $fo === 1 ? 'selected' : ''; ?>><?php echo Text::_('Sì'); ?></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="categoria_id"><?php echo Text::_('Categoria'); ?></label>
|
||||
<select id="categoria_id" name="categoria_id" class="form-select" required>
|
||||
<option value="0">-- <?php echo Text::_('Seleziona'); ?> --</option>
|
||||
<?php foreach ((array) $this->categorie as $c):
|
||||
$cid = (int) ($c['id'] ?? 0);
|
||||
$ctitle = (string) ($c['title'] ?? '');
|
||||
$cstate = (int) ($c['state'] ?? 1);
|
||||
if ($cstate !== 1) continue;
|
||||
?>
|
||||
<option value="<?php echo $cid; ?>"
|
||||
<?php echo (!empty($item->categoria_id) && (int)$item->categoria_id === $cid) ? 'selected' : ''; ?>>
|
||||
<?php echo e($ctitle); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4 firma-block" style="display:none;">
|
||||
<label class="form-label" for="jform_tipologia_firma_id"><?php echo Text::_('Tipologia firma'); ?></label>
|
||||
<select name="tipologia_firma_id" id="jform_tipologia_firma_id" class="form-select">
|
||||
<option value="0">-- <?php echo Text::_('Seleziona'); ?> --</option>
|
||||
<?php
|
||||
$selTipo = (int) ($item->tipologia_firma_id ?? 0);
|
||||
foreach ((array)$this->firmetipi as $t) {
|
||||
$tid = (int) $t['id'];
|
||||
$nm = (string) $t['nome'];
|
||||
echo '<option value="' . $tid . '" ' . ($selTipo === $tid ? 'selected' : '') . '>'
|
||||
. htmlspecialchars($nm, ENT_QUOTES, 'UTF-8') . '</option>';
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<div class="form-text"><?php echo Text::_('Anteprima bottoni:'); ?></div>
|
||||
<div id="anteprima-bottoni" class="mt-1"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-3 mt-2 firma-block" style="display:none;">
|
||||
<div class="col-md-6 firma-block" style="display:none;">
|
||||
<label class="form-label" for="jform_usergroup_ids">
|
||||
<?php echo Text::_('Gruppi che possono firmare'); ?>
|
||||
</label>
|
||||
|
||||
<select id="jform_usergroup_ids"
|
||||
name="usergroup_ids[]"
|
||||
class="form-select"
|
||||
multiple
|
||||
size="8">
|
||||
<?php foreach ((array) ($this->allUserGroups ?? []) as $g):
|
||||
$gid = (int) ($g['id'] ?? 0);
|
||||
$gtitle = (string) ($g['title'] ?? '');
|
||||
$sel = in_array($gid, (array) ($this->selectedGroupIds ?? []), true) ? 'selected' : '';
|
||||
?>
|
||||
<option value="<?php echo $gid; ?>" <?php echo $sel; ?>>
|
||||
<?php echo htmlspecialchars($gtitle, ENT_QUOTES, 'UTF-8'); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
|
||||
<div class="form-text pc-muted">
|
||||
<?php echo Text::_('Seleziona i gruppi utenti abilitati alla firma di questa circolare.'); ?>
|
||||
<div class="mb-0">
|
||||
<label class="form-label" for="state"><?php echo Text::_('Stato'); ?></label>
|
||||
<select id="state" name="state" class="form-select">
|
||||
<option value="1" <?php echo ((int)($item->state ?? 1) === 1 ? 'selected' : ''); ?>>
|
||||
<?php echo Text::_('Pubblicata'); ?>
|
||||
</option>
|
||||
<option value="0" <?php echo ((int)($item->state ?? 1) === 0 ? 'selected' : ''); ?>>
|
||||
<?php echo Text::_('Bozza/Non pubblicata'); ?>
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label required" id="jform_scadenza-lbl" for="jform_scadenza">
|
||||
<?php echo Text::_('Scadenza firma'); ?><span class="star" aria-hidden="true"> *</span>
|
||||
</label>
|
||||
<input type="datetime-local" name="scadenza" id="jform_scadenza" class="form-control"
|
||||
value="<?php
|
||||
$sc = (string) ($item->scadenza ?? '');
|
||||
if ($sc !== '') {
|
||||
echo htmlspecialchars(str_replace(' ', 'T', substr($sc, 0, 16)), ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
?>">
|
||||
|
||||
<div class="tab-pane fade" id="pane-media" role="tabpanel" aria-labelledby="tab-media" tabindex="0">
|
||||
<?php $existingImage = (string)($item->image ?? ''); ?>
|
||||
<div class="mb-4">
|
||||
<label class="form-label" for="image_file"><?php echo Text::_('Immagine'); ?></label>
|
||||
|
||||
<?php if ($existingImage) : ?>
|
||||
<div class="d-flex align-items-center gap-3 mb-2">
|
||||
<img src="<?php echo e($existingImage); ?>" alt="Anteprima immagine"
|
||||
style="max-height:80px; width:auto; border:1px solid #eee; padding:2px;">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="image_remove" name="image_remove" value="1">
|
||||
<label class="form-check-label" for="image_remove"><?php echo Text::_('Rimuovi immagine'); ?></label>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="image_existing" value="<?php echo e($existingImage); ?>">
|
||||
<?php endif; ?>
|
||||
|
||||
<input type="file" id="image_file" name="image_file" class="form-control"
|
||||
accept="image/*,.jpg,.jpeg,.JPG,.JPEG,.png,.gif,.webp,.svg,.heic,.HEIC,.heif,.bmp,.tif,.tiff">
|
||||
<div class="form-text"><?php echo Text::_('Carica una nuova immagine (opzionale).'); ?></div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
$existingAttachments = [];
|
||||
if (!empty($this->attachments) && is_array($this->attachments)) {
|
||||
$existingAttachments = $this->attachments;
|
||||
} elseif (!empty($item->attachments) && is_array($item->attachments)) {
|
||||
$existingAttachments = $item->attachments;
|
||||
}
|
||||
?>
|
||||
<div class="mb-2">
|
||||
<label class="form-label d-block"><?php echo Text::_('Allegati'); ?></label>
|
||||
|
||||
<div id="attachments-list" class="row g-3">
|
||||
<?php $idx = 0;
|
||||
foreach ($existingAttachments as $att) :
|
||||
$path = (string)(is_array($att) ? ($att['path'] ?? '') : ($att->path ?? ''));
|
||||
$title = (string)(is_array($att) ? ($att['title'] ?? '') : ($att->title ?? ''));
|
||||
$ordering = (int)(is_array($att) ? ($att['ordering'] ?? 0) : ($att->ordering ?? 0));
|
||||
if ($path === '') continue;
|
||||
$pathEsc = e($path);
|
||||
$titleEsc = e($title);
|
||||
?>
|
||||
<div class="col-12" data-att-row>
|
||||
<div class="border rounded p-3 bg-light">
|
||||
<div class="mb-2">
|
||||
<strong class="d-block mb-1"><?php echo Text::_('File esistente'); ?>:</strong>
|
||||
<a href="<?php echo $pathEsc; ?>" target="_blank" rel="noopener">
|
||||
<?php echo e(basename(htmlspecialchars_decode($path))); ?>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="row g-2 align-items-end">
|
||||
<div class="col-md-5">
|
||||
<label class="form-label" for="att_<?php echo $idx; ?>_title"><?php echo Text::_('Titolo'); ?></label>
|
||||
<input type="text" class="form-control"
|
||||
id="att_<?php echo $idx; ?>_title"
|
||||
name="attachments[<?php echo $idx; ?>][title]"
|
||||
value="<?php echo $titleEsc; ?>">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label" for="att_<?php echo $idx; ?>_ordering"><?php echo Text::_('Ordine'); ?></label>
|
||||
<input type="number" class="form-control"
|
||||
id="att_<?php echo $idx; ?>_ordering"
|
||||
name="attachments[<?php echo $idx; ?>][ordering]"
|
||||
value="<?php echo (int)$ordering; ?>">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label" for="att_<?php echo $idx; ?>_file"><?php echo Text::_('Sostituisci file'); ?></label>
|
||||
<input type="file" class="form-control"
|
||||
id="att_<?php echo $idx; ?>_file"
|
||||
name="attachments[<?php echo $idx; ?>][file]"
|
||||
accept="*/*,image/*,.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.zip,.jpg,.jpeg,.JPG,.JPEG,.png,.gif,.webp,.svg,.heic,.HEIC,.heif,.bmp,.tif,.tiff">
|
||||
<div class="form-text"><?php echo Text::_('Lascia vuoto per mantenere il file esistente.'); ?></div>
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<div class="form-check mt-4">
|
||||
<input class="form-check-input" type="checkbox"
|
||||
id="att_<?php echo $idx; ?>_remove"
|
||||
name="attachments[<?php echo $idx; ?>][remove]"
|
||||
value="1">
|
||||
<label class="form-check-label" for="att_<?php echo $idx; ?>_remove"><?php echo Text::_('Rimuovi'); ?></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="attachments[<?php echo $idx; ?>][path]" value="<?php echo $pathEsc; ?>">
|
||||
</div>
|
||||
</div>
|
||||
<?php $idx++; endforeach; ?>
|
||||
</div>
|
||||
|
||||
<div class="d-flex gap-2 mt-2">
|
||||
<button type="button" class="btn btn-outline-primary" id="add-attachment-btn">
|
||||
+ <?php echo Text::_('Aggiungi allegato'); ?>
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-danger d-none" id="remove-last-attachment-btn">
|
||||
<?php echo Text::_('Rimuovi ultima riga'); ?>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<template id="attachment-row-template">
|
||||
<div class="col-12" data-att-row>
|
||||
<div class="border rounded p-3">
|
||||
<div class="row g-2 align-items-end">
|
||||
<div class="col-md-5">
|
||||
<label class="form-label"><?php echo Text::_('Titolo'); ?></label>
|
||||
<input type="text" class="form-control" name="__NAME__[title]" value="">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label"><?php echo Text::_('Ordine'); ?></label>
|
||||
<input type="number" class="form-control" name="__NAME__[ordering]" value="0">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label"><?php echo Text::_('File'); ?></label>
|
||||
<input type="file" class="form-control" name="__NAME__[file]"
|
||||
accept="*/*,image/*,.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.zip,.jpg,.jpeg,.JPG,.JPEG,.png,.gif,.webp,.svg,.heic,.HEIC,.heif,.bmp,.tif,.tiff" required>
|
||||
</div>
|
||||
<div class="col-md-1 d-flex justify-content-end">
|
||||
<button type="button" class="btn btn-sm btn-outline-danger mt-4" data-remove-row>
|
||||
<?php echo Text::_('Rimuovi'); ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pane-firma" role="tabpanel" aria-labelledby="tab-firma" tabindex="0">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label" for="jform_firma_obbligatoria"><?php echo Text::_('Firma obbligatoria'); ?></label>
|
||||
<?php $fo = (int) ($item->firma_obbligatoria ?? 0); ?>
|
||||
<select name="firma_obbligatoria" id="jform_firma_obbligatoria" class="form-select">
|
||||
<option value="0" <?php echo $fo === 0 ? 'selected' : ''; ?>><?php echo Text::_('No'); ?></option>
|
||||
<option value="1" <?php echo $fo === 1 ? 'selected' : ''; ?>><?php echo Text::_('Sì'); ?></option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-md-4 firma-block" style="display:none;">
|
||||
<label class="form-label" for="jform_tipologia_firma_id"><?php echo Text::_('Tipologia firma'); ?></label>
|
||||
<select name="tipologia_firma_id" id="jform_tipologia_firma_id" class="form-select">
|
||||
<option value="0">-- <?php echo Text::_('Seleziona'); ?> --</option>
|
||||
<?php
|
||||
$selTipo = (int) ($item->tipologia_firma_id ?? 0);
|
||||
foreach ((array)$this->firmetipi as $t) {
|
||||
$tid = (int) $t['id'];
|
||||
$nm = (string) $t['nome'];
|
||||
echo '<option value="' . $tid . '" ' . ($selTipo === $tid ? 'selected' : '') . '>'
|
||||
. e($nm) . '</option>';
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<div class="form-text"><?php echo Text::_('Anteprima bottoni:'); ?></div>
|
||||
<div id="anteprima-bottoni" class="mt-1"></div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4 mt-4 firma-block" style="display:none;">
|
||||
<label class="form-label" for="jform_notify">Invia email agli aventi diritto</label>
|
||||
<input type="hidden" name="notify" value="0">
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" id="jform_notify" name="notify" value="1">
|
||||
<label class="form-check-label" for="jform_notify">Sì, invia subito</label>
|
||||
<div class="col-md-4 firma-block">
|
||||
<label class="form-label required " id="jform_scadenza-lbl" for="jform_scadenza">
|
||||
<?php echo Text::_('Scadenza firma'); ?><span class="star" aria-hidden="true"> *</span>
|
||||
</label>
|
||||
<input type="datetime-local" name="scadenza" id="jform_scadenza" class="form-control"
|
||||
value="<?php
|
||||
$sc = (string) ($item->scadenza ?? '');
|
||||
if ($sc !== '') echo e(str_replace(' ', 'T', substr($sc, 0, 16)));
|
||||
?>">
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 firma-block" style="display:none;">
|
||||
<label class="form-label" for="jform_usergroup_ids"><?php echo Text::_('Gruppi che possono firmare'); ?></label>
|
||||
<select id="jform_usergroup_ids" name="usergroup_ids[]" class="form-select" multiple size="8">
|
||||
<?php foreach ((array) ($this->allUserGroups ?? []) as $g):
|
||||
$gid = (int) ($g['id'] ?? 0);
|
||||
$gtitle = (string) ($g['title'] ?? '');
|
||||
$sel = in_array($gid, (array) ($this->selectedGroupIds ?? []), true) ? 'selected' : '';
|
||||
?>
|
||||
<option value="<?php echo $gid; ?>" <?php echo $sel; ?>><?php echo e($gtitle); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="form-text"><?php echo Text::_('Seleziona i gruppi utenti abilitati alla firma.'); ?></div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 firma-block">
|
||||
<label class="form-label" for="jform_notify"><?php echo Text::_('Invia email agli aventi diritto'); ?></label>
|
||||
<input type="hidden" name="notify" value="0">
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" id="jform_notify" name="notify" value="1">
|
||||
<label class="form-check-label" for="jform_notify"><?php echo Text::_('Sì, invia subito'); ?></label>
|
||||
</div>
|
||||
<div class="form-text"><?php echo Text::_('Invia una notifica agli utenti dei gruppi selezionati.'); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-text">Invia una notifica agli utenti dei gruppi abilitati alla firma.</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 d-flex gap-2">
|
||||
@ -171,19 +331,53 @@ $cancelUrl = $cancelItemId
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="id" value="<?php echo (int) ($this->item->id ?? 0); ?>">
|
||||
<?php echo \Joomla\CMS\HTML\HTMLHelper::_('form.token'); ?>
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
|
||||
<script type="application/json" id="bottoni-map">
|
||||
<?php
|
||||
echo json_encode($this->bottoniMap ?? [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
?>
|
||||
<?php echo json_encode($this->bottoniMap ?? [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); ?>
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
function byId(id) {
|
||||
return document.getElementById(id);
|
||||
// Allegati repeater
|
||||
var addBtn = document.getElementById('add-attachment-btn');
|
||||
var removeLastBtn = document.getElementById('remove-last-attachment-btn');
|
||||
var list = document.getElementById('attachments-list');
|
||||
var tpl = document.getElementById('attachment-row-template')?.content;
|
||||
var nextIndex = <?php echo (int)($idx ?? 0); ?>;
|
||||
|
||||
function toggleRemoveLast() {
|
||||
var rows = list?.querySelectorAll('[data-att-row].is-new') || [];
|
||||
if (removeLastBtn) removeLastBtn.classList.toggle('d-none', rows.length === 0);
|
||||
}
|
||||
function addRow() {
|
||||
if (!tpl || !list) return;
|
||||
var clone = document.importNode(tpl, true);
|
||||
clone.querySelectorAll('input[name*="__NAME__"]').forEach(function(el) {
|
||||
el.name = el.name.replace('__NAME__', 'attachments[' + nextIndex + ']');
|
||||
});
|
||||
var row = clone.querySelector('[data-att-row]');
|
||||
row.classList.add('is-new');
|
||||
list.appendChild(clone);
|
||||
nextIndex++;
|
||||
toggleRemoveLast();
|
||||
}
|
||||
function removeRow(btn) {
|
||||
var row = btn.closest('[data-att-row]');
|
||||
if (row) { row.remove(); toggleRemoveLast(); }
|
||||
}
|
||||
addBtn && addBtn.addEventListener('click', addRow);
|
||||
removeLastBtn && removeLastBtn.addEventListener('click', function() {
|
||||
var rows = list.querySelectorAll('[data-att-row].is-new');
|
||||
if (rows.length) { rows[rows.length - 1].remove(); toggleRemoveLast(); }
|
||||
});
|
||||
list && list.addEventListener('click', function(e) {
|
||||
if (e.target && e.target.hasAttribute('data-remove-row')) removeRow(e.target);
|
||||
});
|
||||
toggleRemoveLast();
|
||||
|
||||
// Firma: show/hide blocchi + anteprima bottoni
|
||||
function byId(id){ return document.getElementById(id); }
|
||||
const obb = byId('jform_firma_obbligatoria');
|
||||
const tipo = byId('jform_tipologia_firma_id');
|
||||
const scad = byId('jform_scadenza');
|
||||
@ -207,14 +401,11 @@ $cancelUrl = $cancelItemId
|
||||
|
||||
function toggleFirma() {
|
||||
const need = obb && obb.value === '1';
|
||||
blocks.forEach(function(el) {
|
||||
el.style.display = need ? '' : 'none';
|
||||
});
|
||||
blocks.forEach(function(el) { el.style.display = need ? '' : 'none'; });
|
||||
if (scad) {
|
||||
if (need) {
|
||||
scad.setAttribute('required', 'required');
|
||||
scad.setAttribute('aria-required', 'true');
|
||||
// aggiungi asterisco al label se manca
|
||||
var lbl = document.getElementById('jform_scadenza-lbl');
|
||||
if (lbl) {
|
||||
lbl.classList.add('required');
|
||||
@ -232,8 +423,7 @@ $cancelUrl = $cancelItemId
|
||||
var lbl = document.getElementById('jform_scadenza-lbl');
|
||||
if (lbl) {
|
||||
lbl.classList.remove('required');
|
||||
var st = lbl.querySelector('.star');
|
||||
if (st) st.remove();
|
||||
var st = lbl.querySelector('.star'); if (st) st.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -244,7 +434,6 @@ $cancelUrl = $cancelItemId
|
||||
if (e.target === obb) toggleFirma();
|
||||
if (e.target === tipo) renderPreview();
|
||||
});
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
toggleFirma();
|
||||
renderPreview();
|
||||
@ -252,4 +441,4 @@ $cancelUrl = $cancelItemId
|
||||
})();
|
||||
</script>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user