feat: dropdown Kelas dependen berdasarkan Jurusan & Tingkat
Saat user pilih Jurusan dan/atau Tingkat Kelas, dropdown Kelas otomatis terfilter hanya menampilkan kelas yang cocok. Menggunakan JS client-side dengan data options dari backend.
This commit is contained in:
@@ -53,7 +53,20 @@ class StudentReportController extends Controller
|
|||||||
->sortBy('department_name')
|
->sortBy('department_name')
|
||||||
->pluck('department_name', 'department_code');
|
->pluck('department_name', 'department_code');
|
||||||
|
|
||||||
return view('students.index', compact('students', 'classLevels', 'classNames', 'departments'));
|
// Data kelas dengan level & jurusan untuk filter dependen
|
||||||
|
$classOptions = Student::where('is_active', true)
|
||||||
|
->selectRaw('DISTINCT class_name, class_level, department_code')
|
||||||
|
->whereNotNull('class_name')
|
||||||
|
->where('class_name', '!=', '')
|
||||||
|
->orderBy('class_name')
|
||||||
|
->get()
|
||||||
|
->map(fn($c) => [
|
||||||
|
'name' => $c->class_name,
|
||||||
|
'level' => $c->class_level,
|
||||||
|
'dept' => $c->department_code,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return view('students.index', compact('students', 'classLevels', 'classNames', 'departments', 'classOptions'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function show(Student $student): View
|
public function show(Student $student): View
|
||||||
|
|||||||
@@ -57,7 +57,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-[11px] font-semibold text-gray-400 uppercase tracking-wider mb-1.5">Kelas</label>
|
<label class="block text-[11px] font-semibold text-gray-400 uppercase tracking-wider mb-1.5">Kelas</label>
|
||||||
<select name="class_name"
|
<select name="class_name" id="filter-class-name"
|
||||||
class="w-full px-4 py-2.5 border border-gray-200 rounded-xl text-sm bg-gray-50/50 focus:bg-white focus:outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition">
|
class="w-full px-4 py-2.5 border border-gray-200 rounded-xl text-sm bg-gray-50/50 focus:bg-white focus:outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition">
|
||||||
<option value="">Semua Kelas</option>
|
<option value="">Semua Kelas</option>
|
||||||
@foreach($classNames as $cn)
|
@foreach($classNames as $cn)
|
||||||
@@ -192,4 +192,47 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script>
|
||||||
|
// Data kelas untuk filter dependen
|
||||||
|
const classOptions = @json($classOptions);
|
||||||
|
|
||||||
|
function filterKelas() {
|
||||||
|
const dept = document.querySelector('select[name="department"]').value;
|
||||||
|
const level = document.querySelector('select[name="class_level"]').value;
|
||||||
|
const kelasSelect = document.getElementById('filter-class-name');
|
||||||
|
const currentVal = kelasSelect.value;
|
||||||
|
|
||||||
|
// Filter
|
||||||
|
let filtered = classOptions;
|
||||||
|
if (dept) filtered = filtered.filter(c => c.dept === dept);
|
||||||
|
if (level) filtered = filtered.filter(c => c.level === level);
|
||||||
|
|
||||||
|
// Sort unique names
|
||||||
|
const names = [...new Set(filtered.map(c => c.name))].sort();
|
||||||
|
|
||||||
|
// Rebuild options
|
||||||
|
kelasSelect.innerHTML = '<option value="">Semua Kelas</option>';
|
||||||
|
names.forEach(n => {
|
||||||
|
const opt = document.createElement('option');
|
||||||
|
opt.value = n;
|
||||||
|
opt.textContent = n;
|
||||||
|
if (n === currentVal) opt.selected = true;
|
||||||
|
kelasSelect.appendChild(opt);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
const deptSelect = document.querySelector('select[name="department"]');
|
||||||
|
const levelSelect = document.querySelector('select[name="class_level"]');
|
||||||
|
|
||||||
|
deptSelect.addEventListener('change', filterKelas);
|
||||||
|
levelSelect.addEventListener('change', filterKelas);
|
||||||
|
|
||||||
|
// Apply initial filter if level/dept pre-selected
|
||||||
|
if (deptSelect.value || levelSelect.value) filterKelas();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
Reference in New Issue
Block a user