713 lines
37 KiB
PHP
713 lines
37 KiB
PHP
<!DOCTYPE html>
|
|
<html lang="en">
|
|
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
|
|
|
<title>Ellia Cellular</title>
|
|
<meta content="" name="description">
|
|
<meta content="" name="keywords">
|
|
|
|
<!-- Favicons -->
|
|
<link href="{{ asset('assets/img/favicon.png') }}" rel="icon">
|
|
<link href="{{ asset('assets/img/apple-touch-icon.png') }}" rel="apple-touch-icon">
|
|
|
|
<!-- Google Fonts -->
|
|
<link href="https://fonts.gstatic.com" rel="preconnect">
|
|
<link
|
|
href="https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i,700,700i|Nunito:300,300i,400,400i,600,600i,700,700i|Poppins:300,300i,400,400i,500,500i,600,600i,700,700i"
|
|
rel="stylesheet">
|
|
|
|
<!-- Tambahkan ini di bagian <head> atau sebelum penutup </body> -->
|
|
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
|
|
|
|
|
<!-- Vendor CSS Files -->
|
|
<link href="{{ asset('assets/vendor/bootstrap/css/bootstrap.min.css') }}" rel="stylesheet">
|
|
<link href="{{ asset('assets/vendor/bootstrap-icons/bootstrap-icons.css') }}" rel="stylesheet">
|
|
<link href="{{ asset('assets/vendor/boxicons/css/boxicons.min.css') }}" rel="stylesheet">
|
|
<link href="{{ asset('assets/vendor/quill/quill.snow.css') }}" rel="stylesheet">
|
|
<link href="{{ asset('assets/vendor/quill/quill.bubble.css') }}" rel="stylesheet">
|
|
<link href="{{ asset('assets/vendor/remixicon/remixicon.css') }}" rel="stylesheet">
|
|
<link href="{{ asset('assets/vendor/simple-datatables/style.css') }}" rel="stylesheet">
|
|
|
|
<!-- Template Main CSS File -->
|
|
<link href="{{ asset('assets/css/style.css') }}" rel="stylesheet">
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<!-- ======= Header ======= -->
|
|
@include('header')
|
|
<!-- ======= Sidebar ======= -->
|
|
@include('sidebar')
|
|
|
|
<main id="main" class="main">
|
|
<div class="pagetitle">
|
|
<h1>Pengeluaran</h1>
|
|
<nav>
|
|
<ol class="breadcrumb">
|
|
<li class="breadcrumb-item"><a href="{{ route('dashboard') }}">Home</a></li>
|
|
<li class="breadcrumb-item">Pengeluaran</li>
|
|
</ol>
|
|
</nav>
|
|
</div><!-- End Page Title -->
|
|
|
|
<section class="section dashboard">
|
|
<div class="row">
|
|
|
|
<!-- Left side columns -->
|
|
<div class="col-lg-12">
|
|
<div class="row">
|
|
|
|
<!-- Total Pengeluaran Tahun Ini Card -->
|
|
<div class="col-xxl-4 col-md-6">
|
|
<div class="card info-card total-pengeluaran-tahun-ini">
|
|
<div class="card-body">
|
|
<h5 class="card-title">Total Pengeluaran Tahun Ini</h5>
|
|
<div class="d-flex align-items-center">
|
|
<div
|
|
class="card-icon rounded-circle d-flex align-items-center justify-content-center">
|
|
<i class="bi bi-cart"></i>
|
|
</div>
|
|
<div class="ps-3">
|
|
<h6>Rp {{ number_format($totalPengeluaranTahunIni, 0, ',', '.') }}</h6>
|
|
<span
|
|
class="small pt-1 fw-bold {{ $isPengeluaranTahunIniNaik ? 'text-danger bi bi-graph-up' : 'text-success bi bi-graph-down' }}">
|
|
Rp {{ number_format(abs($selisihPengeluaranTahunIni), 0, ',', '.') }}
|
|
{{ $isPengeluaranTahunIniNaik ? 'lebih tinggi' : 'lebih rendah' }} dari
|
|
tahun lalu
|
|
</span>
|
|
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Total Pengeluaran Bulan Ini Card -->
|
|
<div class="col-xxl-4 col-md-6">
|
|
<div class="card info-card total-pengeluaran-bulan-ini">
|
|
<div class="card-body">
|
|
<h5 class="card-title">Total Pengeluaran Bulan Ini</h5>
|
|
<div class="d-flex align-items-center">
|
|
<div
|
|
class="card-icon rounded-circle d-flex align-items-center justify-content-center">
|
|
<i class="bi bi-bag"></i>
|
|
</div>
|
|
<div class="ps-3">
|
|
<h6>Rp {{ number_format($totalPengeluaranBulanIni, 0, ',', '.') }}</h6>
|
|
<span
|
|
class="small pt-1 fw-bold {{ $isPengeluaranBulanIniNaik ? 'text-danger bi bi-graph-up' : 'text-success bi bi-graph-down' }}">
|
|
Rp {{ number_format(abs($selisihPengeluaranBulanIni), 0, ',', '.') }}
|
|
{{ $isPengeluaranBulanIniNaik ? 'lebih tinggi' : 'lebih rendah' }} dari
|
|
bulan lalu
|
|
</span>
|
|
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Pengeluaran Rata-Rata Bulan Ini Card -->
|
|
<div class="col-xxl-4 col-md-6">
|
|
<div class="card info-card pengeluaran-rata-rata-bulan-ini">
|
|
<div class="card-body">
|
|
<h5 class="card-title">Pengeluaran Rata-Rata Bulan Ini</h5>
|
|
<div class="d-flex align-items-center">
|
|
<div
|
|
class="card-icon rounded-circle d-flex align-items-center justify-content-center">
|
|
<i class="bi bi-cash-coin"></i>
|
|
</div>
|
|
<div class="ps-3">
|
|
<h6>Rp {{ number_format($rataRataPengeluaranBulanIni, 0, ',', '.') }}</h6>
|
|
<span
|
|
class="small pt-1 fw-bold {{ $isRataRataPengeluaranNaik ? 'text-danger bi bi-graph-up' : 'text-success bi bi-graph-down' }}">
|
|
Rp {{ number_format(abs($selisihRataRataPengeluaran), 0, ',', '.') }}
|
|
{{ $isRataRataPengeluaranNaik ? 'lebih tinggi' : 'lebih rendah' }} dari
|
|
bulan lalu
|
|
</span>
|
|
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<section class="section">
|
|
<div class="row">
|
|
<div class="col-lg-12">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<h5 class="card-title">Data Pengeluaran</h5>
|
|
<div class="mb-2">
|
|
<input type="text" class="form-control" id="searchInput"
|
|
placeholder="Cari..." style="width: 200px;">
|
|
</div>
|
|
<div class="mb-1 d-flex align-items-center">
|
|
<label class="me-2">Tampilkan:</label>
|
|
<select id="entriesPerPage" class="form-select w-auto">
|
|
<option value="5">5</option>
|
|
<option value="10">10</option>
|
|
<option value="all">Semua</option>
|
|
</select>
|
|
</div>
|
|
<div class="d-flex justify-content-end align-items-center mb-3">
|
|
<button type="button" class="btn btn-success" data-bs-toggle="modal"
|
|
data-bs-target="#tambahPengeluaran">
|
|
+ Tambah Pengeluaran
|
|
</button>
|
|
</div>
|
|
<table class="table table-striped table-bordered" id="expenseTable">
|
|
<thead>
|
|
<tr>
|
|
<th>No</th>
|
|
<th>Nama Pengeluaran</th>
|
|
<th>Kategori</th>
|
|
<th>Deskripsi Pengeluaran</th>
|
|
<th>Total Pengeluaran</th>
|
|
<th>Waktu dan Tanggal</th>
|
|
<th>Aksi</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@forelse ($expense as $e)
|
|
<tr>
|
|
<td>{{ $loop->iteration }}</td>
|
|
<td>{{ $e->nama_pengeluaran }}</td>
|
|
<td>{{ $e->kategori_pengeluaran }}</td>
|
|
<td>{{ $e->deskripsi_pengeluaran }}</td>
|
|
<td>Rp
|
|
{{ number_format($e->total_pengeluaran, 0, ',', '.') }}
|
|
</td>
|
|
<td>{{ \Carbon\Carbon::parse($e->tanggal)->format('d-m-Y') }}
|
|
{{ \Carbon\Carbon::parse($e->waktu)->format('H:i:s') }}
|
|
</td>
|
|
<td>
|
|
<button type="button" class="btn btn-primary btn-sm"
|
|
data-bs-toggle="modal"
|
|
data-bs-target="#editPengeluaran{{ $e->id }}">
|
|
Edit
|
|
</button>
|
|
<button type="button" class="btn btn-danger btn-sm"
|
|
onclick="confirmDelete({{ $e->id }})">
|
|
Hapus
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td colspan="7" class="text-center">Belum ada
|
|
pengeluaran yang tersedia.</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
</table>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</main><!-- End #main -->
|
|
|
|
{{-- <section class="section">
|
|
<div class="row">
|
|
<div class="col-lg-12">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<h5 class="card-title">Data Pengeluaran</h5>
|
|
<div class="mb-2">
|
|
<input type="text" class="form-control" id="searchInput" placeholder="Cari..."
|
|
style="width: 200px;">
|
|
</div>
|
|
<div class="mb-1 d-flex align-items-center">
|
|
<label class="me-2">Tampilkan:</label>
|
|
<select id="entriesPerPage" class="form-select w-auto">
|
|
<option value="5">5</option>
|
|
<option value="10">10</option>
|
|
<option value="all">Semua</option>
|
|
</select>
|
|
</div>
|
|
<div class="d-flex justify-content-end align-items-center mb-3">
|
|
<button type="button" class="btn btn-success" data-bs-toggle="modal"
|
|
data-bs-target="#tambahPengeluaran">
|
|
+ Tambah Pengeluaran
|
|
</button>
|
|
</div>
|
|
<table class="table table-striped table-bordered" id="expenseTable">
|
|
<thead>
|
|
<tr>
|
|
<th>No</th>
|
|
<th>Nama Pengeluaran</th>
|
|
<th>Kategori</th>
|
|
<th>Deskripsi Pengeluaran</th>
|
|
<th>Total Pengeluaran</th>
|
|
<th>Waktu dan Tanggal</th>
|
|
<th>Aksi</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach ($expense as $e)
|
|
<tr>
|
|
<td>{{ $loop->iteration }}</td>
|
|
<td>{{ $e->nama_pengeluaran }}</td>
|
|
<td>{{ $e->kategori_pengeluaran }}</td>
|
|
<td>{{ $e->deskripsi_pengeluaran }}</td>
|
|
<td>Rp {{ number_format($e->total_pengeluaran, 0, ',', '.') }}</td>
|
|
<td>{{ \Carbon\Carbon::parse($e->tanggal)->format('d-m-Y') }} - {{ \Carbon\Carbon::parse($e->waktu)->format('H:i:s') }}</td>
|
|
<td>
|
|
<button type="button" class="btn btn-primary btn-sm"
|
|
data-bs-toggle="modal"
|
|
data-bs-target="#editPengeluaran{{ $e->id }}">
|
|
Edit
|
|
</button>
|
|
<!-- Tombol Hapus -->
|
|
<button type="button" class="btn btn-danger btn-sm"
|
|
onclick="confirmDelete({{ $e->id }})">Hapus</button>
|
|
|
|
</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</main><!-- End #main --> --}}
|
|
|
|
<!-- Modal Tambah-->
|
|
<div class="modal fade" id="tambahPengeluaran" tabindex="-1" aria-labelledby="modaltambahpengeluaranLabel"
|
|
aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="modalTambahPengeluaranLabel">Tambah Data Pengeluaran</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form action="{{ route('expense.store') }}" method="POST" enctype="multipart/form-data">
|
|
@csrf
|
|
<div class="mb-3">
|
|
<label for="nama_pengeluaran" class="form-label">Nama Pengeluaran</label>
|
|
<input type="text" class="form-control" id="nama_pengeluaran" name="nama_pengeluaran"
|
|
required>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="kategori_pengeluaran" class="form-label">Kategori Pengeluaran</label>
|
|
<select class="form-select" id="kategori_pengeluaran" name="kategori_pengeluaran"
|
|
required>
|
|
<option value="Pengeluaran Bulanan">Pengeluaran Bulanan</option>
|
|
<option value="Pengeluaran Opsional">Pengeluaran Opsional</option>
|
|
<option value="Gaji Karyawan">Gaji Karyawan</option>
|
|
<option value="Lain-Lain">Lain-Lain</option>
|
|
</select>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="deskripsi_pengeluaran" class="form-label">Deskripsi Pengeluaran</label>
|
|
<input type="text" class="form-control" id="deskripsi_pengeluaran"
|
|
name="deskripsi_pengeluaran" required>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="total_pengeluaran" class="form-label">Total Pengeluaran</label>
|
|
<input type="text" class="form-control" id="total_pengeluaran"
|
|
name="total_pengeluaran" required>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="waktu" class="form-label">Waktu</label>
|
|
<input type="time" class="form-control" id="waktu" name="waktu" required
|
|
onclick="this.showPicker()">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="tanggal" class="form-label">Tanggal</label>
|
|
<input type="date" class="form-control" id="tanggal" name="tanggal" required
|
|
onclick="this.showPicker()">
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Tutup</button>
|
|
<button type="submit" class="btn btn-primary">Simpan Data</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal Edit -->
|
|
@foreach ($expense as $e)
|
|
<!-- Modal Edit -->
|
|
<div class="modal fade" id="editPengeluaran{{ $e->id }}" tabindex="-1"
|
|
aria-labelledby="modalEditPengeluaranLabel" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="modalEditPengeluaranLabel">Edit Data Pengeluaran</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"
|
|
aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form action="{{ route('expense.update', $e->id) }}" method="POST"
|
|
enctype="multipart/form-data">
|
|
@csrf
|
|
@method('PUT')
|
|
<div class="mb-3">
|
|
<label for="nama_pengeluaran" class="form-label">Nama Pengeluaran</label>
|
|
<input type="text" class="form-control" id="nama_pengeluaran"
|
|
name="nama_pengeluaran" value="{{ $e->nama_pengeluaran }}" required>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="kategori_pengeluaran" class="form-label">Kategori Pengeluaran</label>
|
|
<select class="form-select" id="kategori_pengeluaran" name="kategori_pengeluaran"
|
|
required>
|
|
<option value="Pengeluaran Bulanan"
|
|
{{ $e->kategori_pengeluaran == 'Pengeluaran Bulanan' ? 'selected' : '' }}>
|
|
Pengeluaran Bulanan</option>
|
|
<option value="Pengeluaran Opsional"
|
|
{{ $e->kategori_pengeluaran == 'Pengeluaran Opsional' ? 'selected' : '' }}>
|
|
Pengeluaran Opsional</option>
|
|
<option value="Gaji Karyawan"
|
|
{{ $e->kategori_pengeluaran == 'Gaji Karyawan' ? 'selected' : '' }}>Gaji
|
|
Karyawan</option>
|
|
<option value="Lain-Lain"
|
|
{{ $e->kategori_pengeluaran == 'Lain-Lain' ? 'selected' : '' }}>Lain-Lain
|
|
</option>
|
|
</select>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="deskripsi_pengeluaran" class="form-label">Deskripsi Pengeluaran</label>
|
|
<input type="text" class="form-control" id="deskripsi_pengeluaran"
|
|
name="deskripsi_pengeluaran" value="{{ $e->deskripsi_pengeluaran }}" required>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="total_pengeluaran" class="form-label">Total Pengeluaran</label>
|
|
<input type="text" class="form-control" id="total_pengeluaran"
|
|
name="total_pengeluaran" value="{{ $e->total_pengeluaran }}" required>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="waktu" class="form-label">Waktu</label>
|
|
<input type="time" class="form-control" id="waktu" name="waktu"
|
|
value="{{ \Carbon\Carbon::parse($e->waktu)->format('H:i') }}" required
|
|
onclick="this.showPicker()">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label for="tanggal" class="form-label">Tanggal</label>
|
|
<input type="date" class="form-control" id="tanggal" name="tanggal"
|
|
value="{{ \Carbon\Carbon::parse($e->tanggal)->format('Y-m-d') }}" required
|
|
onclick="this.showPicker()">
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Tutup</button>
|
|
<button type="submit" class="btn btn-primary">Simpan Perubahan</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endforeach
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ======= Footer ======= -->
|
|
@include('footer')
|
|
|
|
<a href="#" class="back-to-top d-flex align-items-center justify-content-center"><i
|
|
class="bi bi-arrow-up-short"></i></a>
|
|
|
|
<!-- Vendor JS Files -->
|
|
<script src="{{ asset('assets/vendor/apexcharts/apexcharts.min.js') }}"></script>
|
|
<script src="{{ asset('assets/vendor/bootstrap/js/bootstrap.bundle.min.js') }}"></script>
|
|
<script src="{{ asset('assets/vendor/chart.js/chart.umd.js') }}"></script>
|
|
<script src="{{ asset('assets/vendor/echarts/echarts.min.js') }}"></script>
|
|
<script src="{{ asset('assets/vendor/quill/quill.js') }}"></script>
|
|
<script src="{{ asset('assets/vendor/simple-datatables/simple-datatables.js') }}"></script>
|
|
<script src="{{ asset('assets/vendor/tinymce/tinymce.min.js') }}"></script>
|
|
<script src="{{ asset('assets/vendor/php-email-form/validate.js') }}"></script>
|
|
|
|
<!-- Template Main JS File -->
|
|
<script src="{{ asset('assets/js/main.js') }}"></script>
|
|
|
|
<!-- Ini buat sweet alert Konfirmasi Hapus-->
|
|
<script>
|
|
function confirmDelete(expenseId) {
|
|
Swal.fire({
|
|
title: 'Apakah Anda Yakin?',
|
|
text: "Pengeluaran ini akan dihapus!",
|
|
icon: 'warning',
|
|
showCancelButton: true,
|
|
confirmButtonColor: '#d33',
|
|
cancelButtonColor: '#3085d6',
|
|
confirmButtonText: 'Ya, Hapus!',
|
|
cancelButtonText: 'Batal'
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
// Mengirimkan request delete ke server
|
|
fetch(`/expense/delete/${expenseId}`, {
|
|
method: 'DELETE',
|
|
headers: {
|
|
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
|
}
|
|
}).then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
Swal.fire(
|
|
'Dihapus!',
|
|
'Pengeluaran berhasil dihapus.',
|
|
'success'
|
|
).then(() => {
|
|
location.reload(); // Reload halaman setelah konfirmasi berhasil
|
|
});
|
|
} else {
|
|
Swal.fire(
|
|
'Gagal!',
|
|
'Pengeluaran gagal dihapus.',
|
|
'error'
|
|
);
|
|
}
|
|
})
|
|
.catch(error => console.error('Terjadi kesalahan:', error));
|
|
}
|
|
})
|
|
}
|
|
</script>
|
|
|
|
<script>
|
|
document.addEventListener("DOMContentLoaded", function() {
|
|
const table = document.getElementById(
|
|
"expenseTable"); // Pastikan ID sesuai dengan tabel di expense.blade.php
|
|
const tbody = table.querySelector("tbody");
|
|
const rows = Array.from(tbody.querySelectorAll("tr"));
|
|
const headers = table.querySelectorAll("thead th");
|
|
const paginationContainer = document.createElement("div");
|
|
paginationContainer.className = "pagination-container mt-3 d-flex justify-content-end";
|
|
|
|
const searchInput = document.getElementById("searchInput");
|
|
const entriesPerPageSelect = document.getElementById("entriesPerPage");
|
|
|
|
let currentPage = 1;
|
|
let rowsPerPage = parseInt(entriesPerPageSelect.value) || 5;
|
|
let currentSortColumn = null;
|
|
let currentSortDirection = "asc";
|
|
|
|
function filterRows() {
|
|
const filter = searchInput.value.toLowerCase();
|
|
return rows.filter(row => row.innerText.toLowerCase().includes(filter));
|
|
}
|
|
|
|
function sortRows(columnIndex, direction) {
|
|
rows.sort((a, b) => {
|
|
const aText = a.cells[columnIndex].innerText.trim().toLowerCase();
|
|
const bText = b.cells[columnIndex].innerText.trim().toLowerCase();
|
|
|
|
if (!isNaN(aText) && !isNaN(bText)) {
|
|
return direction === "asc" ? aText - bText : bText - aText;
|
|
}
|
|
|
|
return direction === "asc" ? aText.localeCompare(bText) : bText.localeCompare(aText);
|
|
});
|
|
}
|
|
|
|
function displayTablePage(page) {
|
|
const filteredRows = filterRows();
|
|
const totalPages = Math.ceil(filteredRows.length / rowsPerPage);
|
|
|
|
if (page > totalPages) page = totalPages;
|
|
if (page < 1) page = 1;
|
|
|
|
tbody.innerHTML = "";
|
|
|
|
if (entriesPerPageSelect.value === "all") {
|
|
filteredRows.forEach(row => tbody.appendChild(row));
|
|
} else {
|
|
const startIndex = (page - 1) * rowsPerPage;
|
|
const endIndex = startIndex + rowsPerPage;
|
|
|
|
const rowsToDisplay = filteredRows.slice(startIndex, endIndex);
|
|
rowsToDisplay.forEach(row => tbody.appendChild(row));
|
|
|
|
updatePagination(page, totalPages);
|
|
}
|
|
|
|
currentPage = page;
|
|
}
|
|
|
|
function updatePagination(currentPage, totalPages) {
|
|
paginationContainer.innerHTML = "";
|
|
|
|
if (totalPages <= 1) return;
|
|
|
|
const maxPagesToShow = 5;
|
|
let startPage = Math.max(1, currentPage - Math.floor(maxPagesToShow / 2));
|
|
let endPage = Math.min(totalPages, startPage + maxPagesToShow - 1);
|
|
|
|
if (endPage - startPage + 1 < maxPagesToShow) {
|
|
startPage = Math.max(1, endPage - maxPagesToShow + 1);
|
|
}
|
|
|
|
for (let i = startPage; i <= endPage; i++) {
|
|
const button = document.createElement("button");
|
|
button.textContent = i;
|
|
button.className = `btn btn-sm btn-outline-primary mx-1 ${i === currentPage ? "active" : ""}`;
|
|
button.addEventListener("click", () => displayTablePage(i));
|
|
paginationContainer.appendChild(button);
|
|
}
|
|
}
|
|
|
|
headers.forEach((header, index) => {
|
|
header.addEventListener("click", () => {
|
|
if (currentSortColumn === index) {
|
|
currentSortDirection = currentSortDirection === "asc" ? "desc" : "asc";
|
|
} else {
|
|
currentSortColumn = index;
|
|
currentSortDirection = "asc";
|
|
}
|
|
|
|
sortRows(index, currentSortDirection);
|
|
displayTablePage(1);
|
|
});
|
|
});
|
|
|
|
searchInput.addEventListener("keyup", () => displayTablePage(1));
|
|
|
|
entriesPerPageSelect.addEventListener("change", function() {
|
|
rowsPerPage = entriesPerPageSelect.value === "all" ? rows.length : parseInt(
|
|
entriesPerPageSelect.value);
|
|
displayTablePage(1);
|
|
});
|
|
|
|
displayTablePage(1);
|
|
table.parentNode.appendChild(paginationContainer);
|
|
});
|
|
</script>
|
|
|
|
{{-- <script>
|
|
document.getElementById('searchInput').addEventListener('keyup', function() {
|
|
let filter = this.value.toLowerCase();
|
|
let rows = document.querySelectorAll('tbody tr');
|
|
|
|
rows.forEach(row => {
|
|
let text = row.innerText.toLowerCase();
|
|
row.style.display = text.includes(filter) ? '' : 'none';
|
|
});
|
|
});
|
|
</script>
|
|
|
|
|
|
<!-- Ini buat datatables Custom Rownya dengan Sorting -->
|
|
<script>
|
|
document.addEventListener("DOMContentLoaded", function() {
|
|
const table = document.getElementById("expenseTable"); // Pastikan ID sesuai dengan tabel di expense.blade.php
|
|
const tbody = table.querySelector("tbody");
|
|
const rows = Array.from(tbody.querySelectorAll("tr"));
|
|
const headers = table.querySelectorAll("thead th");
|
|
const paginationContainer = document.createElement("div");
|
|
paginationContainer.className = "pagination-container mt-3 d-flex justify-content-end";
|
|
|
|
const searchInput = document.getElementById("searchInput");
|
|
const entriesPerPageSelect = document.getElementById("entriesPerPage");
|
|
|
|
let currentPage = 1;
|
|
let rowsPerPage = parseInt(entriesPerPageSelect.value) || 5;
|
|
let currentSortColumn = null;
|
|
let currentSortDirection = "asc";
|
|
|
|
function filterRows() {
|
|
const filter = searchInput.value.toLowerCase();
|
|
return rows.filter(row => row.innerText.toLowerCase().includes(filter));
|
|
}
|
|
|
|
function sortRows(columnIndex, direction) {
|
|
rows.sort((a, b) => {
|
|
const aText = a.cells[columnIndex].innerText.trim().toLowerCase();
|
|
const bText = b.cells[columnIndex].innerText.trim().toLowerCase();
|
|
|
|
if (!isNaN(aText) && !isNaN(bText)) {
|
|
return direction === "asc" ? aText - bText : bText - aText;
|
|
}
|
|
|
|
return direction === "asc" ? aText.localeCompare(bText) : bText.localeCompare(aText);
|
|
});
|
|
}
|
|
|
|
function displayTablePage(page) {
|
|
const filteredRows = filterRows();
|
|
const totalPages = Math.ceil(filteredRows.length / rowsPerPage);
|
|
|
|
if (page > totalPages) page = totalPages;
|
|
if (page < 1) page = 1;
|
|
|
|
tbody.innerHTML = "";
|
|
|
|
if (entriesPerPageSelect.value === "all") {
|
|
filteredRows.forEach(row => tbody.appendChild(row));
|
|
} else {
|
|
const startIndex = (page - 1) * rowsPerPage;
|
|
const endIndex = startIndex + rowsPerPage;
|
|
|
|
const rowsToDisplay = filteredRows.slice(startIndex, endIndex);
|
|
rowsToDisplay.forEach(row => tbody.appendChild(row));
|
|
|
|
updatePagination(page, totalPages);
|
|
}
|
|
|
|
currentPage = page;
|
|
}
|
|
|
|
function updatePagination(currentPage, totalPages) {
|
|
paginationContainer.innerHTML = "";
|
|
|
|
if (totalPages <= 1) return;
|
|
|
|
for (let i = 1; i <= totalPages; i++) {
|
|
const button = document.createElement("button");
|
|
button.textContent = i;
|
|
button.className = `btn btn-sm btn-outline-primary mx-1 ${i === currentPage ? "active" : ""}`;
|
|
button.addEventListener("click", () => displayTablePage(i));
|
|
paginationContainer.appendChild(button);
|
|
}
|
|
}
|
|
|
|
headers.forEach((header, index) => {
|
|
header.addEventListener("click", () => {
|
|
if (currentSortColumn === index) {
|
|
currentSortDirection = currentSortDirection === "asc" ? "desc" : "asc";
|
|
} else {
|
|
currentSortColumn = index;
|
|
currentSortDirection = "asc";
|
|
}
|
|
|
|
sortRows(index, currentSortDirection);
|
|
displayTablePage(1);
|
|
});
|
|
});
|
|
|
|
searchInput.addEventListener("keyup", () => displayTablePage(1));
|
|
|
|
entriesPerPageSelect.addEventListener("change", function() {
|
|
rowsPerPage = entriesPerPageSelect.value === "all" ? rows.length : parseInt(entriesPerPageSelect.value);
|
|
displayTablePage(1);
|
|
});
|
|
|
|
displayTablePage(1);
|
|
table.parentNode.appendChild(paginationContainer);
|
|
});
|
|
</script> --}}
|
|
|
|
|
|
|
|
|
|
</body>
|
|
|
|
</html>
|