finale 2.0.0
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
@php
|
||||
$filterTags = $filterTags ?? (\App\Models\Tag::orderBy('name')->get());
|
||||
$activeTags = (array) request('tag', []);
|
||||
@endphp
|
||||
@if($filterTags->isNotEmpty())
|
||||
<div class="tag-filter-bar px-3 py-2 bg-light border-bottom" style="display:flex;flex-wrap:wrap;gap:4px;align-items:center;">
|
||||
<span class="small font-weight-bold text-muted mr-1"><i class="fas fa-tags mr-1"></i>Tag:</span>
|
||||
@foreach($filterTags as $tag)
|
||||
@php
|
||||
$isActive = in_array($tag->slug, $activeTags);
|
||||
$query = request()->query();
|
||||
if ($isActive) {
|
||||
$newTags = array_values(array_diff($activeTags, [$tag->slug]));
|
||||
if (empty($newTags)) {
|
||||
unset($query['tag']);
|
||||
} else {
|
||||
$query['tag'] = $newTags;
|
||||
}
|
||||
} else {
|
||||
$query['tag'] = array_merge($activeTags, [$tag->slug]);
|
||||
}
|
||||
$url = request()->url() . '?' . http_build_query($query);
|
||||
@endphp
|
||||
<a href="{{ $url }}" class="badge tag-filter-badge" style="background-color:{{ $tag->color ?? '#6c757d' }};color:#fff;{{ $isActive ? '' : 'opacity:0.45;' }}font-size:0.8rem;padding:4px 10px;border-radius:12px;text-decoration:none;">
|
||||
{{ $tag->name }}
|
||||
</a>
|
||||
@endforeach
|
||||
@if(!empty($activeTags))
|
||||
<a href="{{ request()->url() }}" class="badge badge-light" style="font-size:0.8rem;padding:4px 10px;border-radius:12px;text-decoration:none;">
|
||||
<i class="fas fa-times mr-1"></i>Cancella filtri
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
@@ -0,0 +1,123 @@
|
||||
@php
|
||||
$allTags = $allTags ?? \App\Models\Tag::orderBy('name')->get();
|
||||
$selectedTags = old('tags', $selectedTags ?? []);
|
||||
$tagFieldName = $tagFieldName ?? 'tags';
|
||||
$selectorId = 'tag-selector-' . md5($tagFieldName);
|
||||
$selectedTagObjects = $allTags->whereIn('id', $selectedTags);
|
||||
@endphp
|
||||
|
||||
<div class="form-group" id="{{ $selectorId }}">
|
||||
<label>{{ $label ?? 'Tag' }}</label>
|
||||
|
||||
<div class="tag-selector-container" style="border:1px solid #ced4da;border-radius:.25rem;padding:8px;background:#fff;">
|
||||
<div class="tag-selected d-flex flex-wrap mb-1" style="gap:4px;">
|
||||
@foreach($selectedTagObjects as $tag)
|
||||
<span class="tag-pill badge d-inline-flex align-items-center" data-tag-id="{{ $tag->id }}" style="background-color:{{ $tag->color ?? '#6c757d' }};color:#fff;padding:4px 10px;border-radius:12px;font-size:0.85rem;">
|
||||
{{ $tag->name }}
|
||||
<button type="button" class="tag-remove btn btn-xs p-0 ml-1 text-white" style="line-height:1;font-size:14px;background:none;border:none;" onclick="removeTag(event, '{{ $selectorId }}', {{ $tag->id }})">×</button>
|
||||
</span>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="tag-search-input">
|
||||
<input type="text" class="form-control form-control-sm" placeholder="Cerca tag..." oninput="filterTags(event, '{{ $selectorId }}')" autocomplete="off">
|
||||
</div>
|
||||
|
||||
<div class="tag-available mt-1" style="max-height:140px;overflow-y:auto;display:flex;flex-wrap:wrap;gap:4px;">
|
||||
@foreach($allTags as $tag)
|
||||
<button type="button" class="tag-btn btn btn-sm {{ in_array($tag->id, $selectedTags) ? 'tag-selected' : '' }}" data-tag-id="{{ $tag->id }}" data-tag-name="{{ $tag->name }}" data-tag-color="{{ $tag->color ?? '#6c757d' }}" style="background-color:{{ $tag->color ?? '#6c757d' }};color:#fff;border-radius:12px;cursor:pointer;{{ in_array($tag->id, $selectedTags) ? '' : 'opacity:0.5;' }}" onclick="toggleTag(event, '{{ $selectorId }}', {{ $tag->id }})">
|
||||
{{ $tag->name }}
|
||||
</button>
|
||||
@endforeach
|
||||
@if($allTags->isEmpty())
|
||||
<p class="text-muted small mb-0 w-100">Nessun tag disponibile. <a href="{{ route('impostazioni.index') }}#tag">Crea i tag</a> nelle Impostazioni.</p>
|
||||
@endif
|
||||
<p class="tag-no-match text-muted small mb-0 w-100" style="display:none;">Nessun tag corrisponde alla ricerca.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tag-hidden-inputs">
|
||||
@foreach($selectedTags as $selectedId)
|
||||
<input type="hidden" name="{{ $tagFieldName }}[]" value="{{ $selectedId }}">
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@once
|
||||
@push('scripts')
|
||||
<script>
|
||||
function toggleTag(e, selId, tagId) {
|
||||
e.preventDefault();
|
||||
var container = document.getElementById(selId);
|
||||
var btn = container.querySelector('.tag-btn[data-tag-id="' + tagId + '"]');
|
||||
if (!btn) return;
|
||||
|
||||
var isSelected = btn.classList.contains('tag-selected');
|
||||
var selectedBox = container.querySelector('.tag-selected');
|
||||
var hiddenContainer = container.querySelector('.tag-hidden-inputs');
|
||||
|
||||
if (isSelected) {
|
||||
btn.classList.remove('tag-selected');
|
||||
btn.style.opacity = '0.5';
|
||||
var pill = container.querySelector('.tag-pill[data-tag-id="' + tagId + '"]');
|
||||
if (pill) pill.remove();
|
||||
var hidden = hiddenContainer.querySelector('input[value="' + tagId + '"]');
|
||||
if (hidden) hidden.remove();
|
||||
} else {
|
||||
btn.classList.add('tag-selected');
|
||||
btn.style.opacity = '1';
|
||||
var name = btn.dataset.tagName;
|
||||
var color = btn.dataset.tagColor || '#6c757d';
|
||||
var pill = document.createElement('span');
|
||||
pill.className = 'tag-pill badge d-inline-flex align-items-center';
|
||||
pill.style.cssText = 'background-color:' + color + ';color:#fff;padding:4px 10px;border-radius:12px;font-size:0.85rem;';
|
||||
pill.dataset.tagId = tagId;
|
||||
pill.innerHTML = name + '<button type="button" class="tag-remove btn btn-xs p-0 ml-1 text-white" style="line-height:1;font-size:14px;background:none;border:none;" onclick="removeTag(event, \'' + selId + '\', ' + tagId + ')">×</button>';
|
||||
selectedBox.appendChild(pill);
|
||||
|
||||
if (hiddenContainer.querySelector('input[value="' + tagId + '"]')) return;
|
||||
var hidden = document.createElement('input');
|
||||
hidden.type = 'hidden';
|
||||
hidden.name = '{{ $tagFieldName }}[]';
|
||||
hidden.value = tagId;
|
||||
hiddenContainer.appendChild(hidden);
|
||||
}
|
||||
}
|
||||
|
||||
function removeTag(e, selId, tagId) {
|
||||
e.preventDefault();
|
||||
var container = document.getElementById(selId);
|
||||
var btn = container.querySelector('.tag-btn[data-tag-id="' + tagId + '"]');
|
||||
if (btn) {
|
||||
btn.classList.remove('tag-selected');
|
||||
btn.style.opacity = '0.5';
|
||||
}
|
||||
var pill = container.querySelector('.tag-pill[data-tag-id="' + tagId + '"]');
|
||||
if (pill) pill.remove();
|
||||
var hiddenContainer = container.querySelector('.tag-hidden-inputs');
|
||||
var hidden = hiddenContainer.querySelector('input[value="' + tagId + '"]');
|
||||
if (hidden) hidden.remove();
|
||||
}
|
||||
|
||||
function filterTags(e, selId) {
|
||||
var container = document.getElementById(selId);
|
||||
var q = e.target.value.toLowerCase();
|
||||
var btns = container.querySelectorAll('.tag-btn');
|
||||
var visibleCount = 0;
|
||||
btns.forEach(function(btn) {
|
||||
var name = btn.dataset.tagName.toLowerCase();
|
||||
if (name.includes(q)) {
|
||||
btn.style.display = '';
|
||||
visibleCount++;
|
||||
} else {
|
||||
btn.style.display = 'none';
|
||||
}
|
||||
});
|
||||
var noMatch = container.querySelector('.tag-no-match');
|
||||
if (noMatch) {
|
||||
noMatch.style.display = visibleCount === 0 ? 'block' : 'none';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@endpush
|
||||
@endonce
|
||||
Reference in New Issue
Block a user