refactor: move product category sub-group datatable rendering from client-side JavaScript to a dedicated server-side Blade partial.

This commit is contained in:
pbao9
2026-02-12 08:22:39 +07:00
parent 99b61bfb51
commit 3b1beef66e
3 changed files with 49 additions and 40 deletions
@@ -123,7 +123,13 @@ class ProductCategoryController extends Controller
return '<div class="form-check d-flex align-items-center justify-content-center"><input class="form-check-input dt-checkbox" type="checkbox" value="' . $d->id . '"></div>';
}
)
->rawColumns(['details_control', 'action', 'is_active', 'checkbox'])
->addColumn(
'sub_group_html',
function ($d) {
return view('administrator.pages.product.categories.datatable.sub_group', ['children' => $d->children])->render();
}
)
->rawColumns(['details_control', 'action', 'is_active', 'checkbox', 'sub_group_html'])
->make(true);
}
}
@@ -0,0 +1,41 @@
@php
use App\Enums\Status;
@endphp
@if($children->isNotEmpty())
<div class="p-3 bg-light rounded">
<h6 class="mb-2 text-primary font-weight-bold">Sub Group</h6>
<table class="table table-sm table-bordered bg-white mb-0">
<thead class="thead-light">
<tr>
<th>Group</th>
<th>Slug</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
@foreach ($children as $child)
<tr>
<td>{{ $child->name }}</td>
<td>{{ $child->slug }}</td>
<td>
<x-admin-badge :variant="$child->is_active ? Status::ACTIVE->value : Status::DEACTIVE->value">
{{ $child->is_active ? Status::ACTIVE->label() : Status::DEACTIVE->label() }}
</x-admin-badge>
</td>
<td>
<div class="d-flex gap-2">
<a href="{{ route('products.group.edit', $child->id) }}"
class="btn btn-icon btn-sm btn-outline-primary" title="Edit">
<i data-lucide="edit-2" width="14" height="14"></i>
</a>
</div>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
@endif
@@ -82,12 +82,10 @@ $tabs = [
lucide.createIcons();
}
// Disable double click on rows to prevent unwanted editing
$('#productTable tbody').off('dblclick');
}, 100);
});
// Child Row (Details Control) Handler
var tableId = '#productTable';
$(tableId + ' tbody').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
@@ -115,49 +113,13 @@ $tabs = [
}
}
// Re-init icons for the newly added markup (plus/minus)
if (typeof lucide !== 'undefined') {
lucide.createIcons();
}
});
function format(d) {
// `d` is the original data object for the row
if (!d.children || d.children.length === 0) {
return '';
}
var childHtml = '<div class="p-3 bg-light rounded">';
childHtml += '<h6 class="mb-2 text-primary font-weight-bold">Sub Categories</h6>';
childHtml += '<table class="table table-sm table-bordered bg-white mb-0">';
childHtml += '<thead class="thead-light"><tr><th>Group</th><th>Slug</th><th>Status</th><th>Action</th></tr></thead>';
childHtml += '<tbody>';
d.children.forEach(function (child) {
// Re-use logic for status badge if possible, or simple text for now
var statusBadge = child.is_active ?
'<span class="badge bg-success">Active</span>' :
'<span class="badge bg-secondary">Inactive</span>';
// Build Action Buttons (Edit/Delete)
var editUrl = '{{ route("products.group.edit", ":id") }}'.replace(':id', child.id);
var actionButtons = `
<div class="d-flex gap-2">
<a href="${editUrl}" class="btn btn-icon btn-sm btn-outline-primary" title="Edit">
<i data-lucide="edit-2" width="14" height="14"></i>
</a>
</div>
`;
childHtml += '<tr>' +
'<td>' + child.name + '</td>' +
'<td>' + child.slug + '</td>' +
'<td>' + statusBadge + '</td>' +
'<td>' + actionButtons + '</td>' +
'</tr>';
});
childHtml += '</tbody></table></div>';
return childHtml;
return d.sub_group_html;
}
});
</script>