Membuat Pagination dari Data JSON Menggunakan PHP (LKS Nasional 2021 Web Technologies)

Sudah lama rasanya saya tidak menulis artikel di Blog ini. Tiba-tiba terpikirkan oleh saya untuk melanjutkan seri pengerjaan modul LKS Nasional 2021 bidang Web Technologies. Meskipun sekarang sudah memasuki tahun 2023, tak ada salahnya untuk melanjutkan seri tersebut.

Bagi yang baru saja menemukan seri ini dan anda sedang berlatih untuk mengikuti Lomba Kompetensi Siswa SMK, silahkan coba kunjungi repositori GitHub saya terkait pengerjaan beberapa soal LKS Nasional 2021 bidang Web Technologies. Meski untuk saat ini hanya ada beberapa modul speedtest saja.

GitHub - hsnfirdaus/lksn21-web-technologies: Soal dan contoh pengerjaan LKSN Web Technologies 2021.
Soal dan contoh pengerjaan LKSN Web Technologies 2021. - GitHub - hsnfirdaus/lksn21-web-technologies: Soal dan contoh pengerjaan LKSN Web Technologies 2021.
github.com
Preview link to GitHub - hsnfirdaus/lksn21-web-technologies: Soal dan contoh pengerjaan LKSN Web Technologies 2021.

Membuat Pagination dengan PHP

Untuk artikel kali ini, saya akan mencoba membahas modul D, yaitu membuat pagination menggunakan PHP dari data JSON. Dalam aturan di soal, kita boleh menggunakan bootstrap, tetapi dilarang menggunakan JavaScript. Namun, disini saya akan menggunakan CSS Native saja agar lebih greget. Berikut ini adalah gambar contoh hasil pengerjaan soal yang saya ambil dari dokumen:

Contoh Hasil Pengerjaan Modul Speedtest Bagian D, Pagination.

Ada beberapa aturan lain yang harus dipenuhi terkait pengerjaan soal tersebut:

  1. Kita diharuskan untuk menampilkan 5 data dari JSON di setiap halamannya.
    1. 5 Link pagination untuk berpindah halaman harus ditampilkan di setiap halamannya.
      1. Terdapat button previous dan next untuk berpindah halaman.
        1. Nomor halaman saat ini harus berada di tengah pagination.

          Disini saya akan mengasumsikan anda memiliki pengetahuan dasar tentang HTML, CSS dan PHP. Langsung saja, kita akan mengerjakan soal tersebut dengan HTML, CSS dan PHP.

          Membuat Struktur Dasar HTML dalam Script PHP

          Tentunya, pertama-tama kita akan membuat struktur dasar HTML untuk halaman yang akan dibuat. Silahkan buat sebuah file php (saya memberikan nama index.php) berisikan struktur dasar seperti berikut ini:

          <!DOCTYPE html>
          <html>
          
          <head>
          	<meta name="viewport" content="width=device-width, initial-scale=1">
          	<meta charset="utf-8">
          	<title>Pagination</title>
          	<link rel="stylesheet" type="text/css" href="style.css" />
          </head>
          
          <body>
          	<main id="container">
          		
          	</main>
          </body>
          
          </html>

          Pada kode diatas saya juga meload css dari file style.css (file ini akan kita buat di tahap akhir). Kita akan menampung seluruh kode yang akan kita buat selanjutnya di dalam tag main.

          Membaca Data Dari File JSON

          Langkah awal dalam mengerjakan soal tersebut, kita harus membaca file JSON yang ada di dalam modul tersebut dengan menggunakan PHP. Tentu saja hal ini tidaklah sulit, kita hanya perlu memanggil fungsi file_get_contents dan json_decode. Pastikan anda telah meletakan file data.json dari modul di repositori saya ke dalam folder yang sama dengan file PHP tadi.

          <?php
          $data = json_decode(file_get_contents('data.json'), TRUE);
          ?>

          Masukan kode PHP tersebut di dalam tag main yang sudah kita buat sebelumnya. Fungsi file_get_contents akan membaca data raw dari path yang dimasukkan sebagai argumen (data.json). Sebenarnya kita bisa juga menggunakan fungsi fopen untuk membaca file, namun saya rasa file_get_contents lebih mudah dan cocok digunakan untuk keperluan kita saat ini.

          Fungsi json_decode berfungsi untuk melakukan parsing data JSON dari raw data yang sudah dibaca dengan fungsi file_get_contents tadi. Terdapat dua argumen di fungsi ini, argumen pertama adalah data json yang akan di decode, argumen selanjutnya bersifat opsional yang berisikan boolean (true/false). Secara default fungsi tersebut akan mendecode data menjadi sebuah objek PHP, bukan array. Ketika argumen kedua kita isi TRUE maka fungsi tersebut akan mendecode data JSON tersebut menjadi PHP array.

          Membaca Nomor Halaman Saat ini dan Memotong Konten

          Setelah kita mendapatkan data berupa array, kita harus membaca nomor halaman saat ini dari query string dan memotong data tersebut sesuai nomor halaman saat ini, sehingga kode kita akan menjadi:

          <?php
          $data = json_decode(file_get_contents('data.json'), TRUE);
          $page = is_numeric(@$_GET['page']) ? $_GET['page'] : 1;
          $limit = 5;
          $start = ($page - 1) * $limit;
          $total_page = ceil((count($data) - 1) / $limit);
          $items = array_slice($data, $start, $limit);
          ?>

          Kita akan menampung nomor halaman saat ini di variable page. Menggunakan fungsi is_numeric, kita mengecek apakah yang dikirimkan di query string ?page= benar benar berupa angka. Jika query string kosong ataupun bukan berupa angka kita atur defaultnya menjadi 1. tanda ? dan : di variable page merupakan shorthand untuk if dalam PHP.

          Variable limit untuk mendefinisikan jumlah data yang akan ditampilkan per halamannya, variable start untuk menentukan indeks mulainya data, misalnya di halaman pertama, maka data harus dimulai dari indeks 0, halaman kedua mulai dari indeks 5 dan seterusnya. Variable total_page tempat kita menghitung total halaman berdasarkan total panjang array (menggunakan fungsi count) dibagi limit data per halaman. Fungsi ceil untuk membulatkan hasil bagi keatas. Misalnya total panjang array adalah 13, kita bagi dengan limit data per halaman yaitu 5, maka hasilnya adalah berupa koma (2,xx), disini harus dibulatkan menjadi 3 agar kita dapat melihat data setelah desimal ( indeks ke 11,12, dan 13) melalui pagination.

          Kita harus memotong data array hasil decode di awal dengan menggunakan array_slice dan kita simpan di variable items. Dalam fungsi array_slice, argumen pertama ($data) adalah array yang akan dipotong, argumen kedua ($start) adalah indeks awal mulainya hasil array, argumen ketiga ($limit) adalah limit jumlah data array yang dipotong. Jadi misalkan kita berada di halaman kedua, berarti startnya akan 5, dan limitnya 5, berarti array_slice akan menampilkan data di indeks ke 5,6,7,8,9.

          Ingat!

          Indeks array di php dimulai dari 0, bukan 1.

          Menampilkan Data Setiap Halaman

          Setelah data array telah terpotong berdasarkan nomor halaman saat ini, selanjutnya kita akan menampilkan data tersebut sebagai output html. Buat kode seperti dibawah ini setelah kode php diatas:

          <h1>Data Pagination Halaman
          	<?php echo $page; ?>
          </h1>
          <section class="item-list">
          	<?php
          	foreach ($items as $item) {
          		?>
          		<div class="item">
          			<h2>
          				<?php echo $item['name']; ?>
          			</h2>
          			<ul>
          				<li>Age :
          					<?php echo $item['age']; ?>
          				</li>
          				<li>Gender :
          					<?php echo $item['gender']; ?>
          				</li>
          				<li>Company :
          					<?php echo $item['company']; ?>
          				</li>
          				<li>Email :
          					<?php echo $item['email']; ?>
          				</li>
          				<li>Phone :
          					<?php echo $item['phone']; ?>
          				</li>
          				<li>Address :
          					<?php echo $item['address']; ?>
          				</li>
          			</ul>
          		</div>
          		<?php
          	}
          	?>
          </section>

          Kita menggunakan fungsi foreach untuk melakukan looping (iterate data array yang sudah ada). Sebenarnya kita bisa juga menggunakan fungsi for untuk looping, tetapi saya lebih menyukai foreach ketika tidak perlu mengetahui indeks data saat ini. Data yang kita tampilkan diatas berdasarkan data JSON dari soal yang ada.

          Membuat Pagination

          Selanjutnya kita menuju ke inti soal, yaitu membuat pagination. Pertama kita buat container dengan tag nav terlebih dahulu:

          <nav id="paging">
          </nav>

          Pertama kita definisikan dulu ukuran pagination yang akan ditampilkan, misalnya di soal kita diharuskan menampilkan 5 buah pagination angka, maka kita masukan angka 4 ke variable $paging_size, ini karena satu pagination angka akan kita tampilkan nomor halaman saat ini:

          <?php
          $paging_size = 4;
          $each_side_size = ($paging_size / 2);
          ?>

          Lalu kita buat kondisi ketika halaman saat ini lebih besar dari 1, kita akan menampilkan link ke halaman sebelumnya dengan simbol < atau dalam html entities nya adalah &lt;. Sedangkan ketika halaman saat ini tidak lebih besar dari 1, kita hanya akan menampilkan tag span dengan simbol yang sama (<).

          <?php
          if ($page > 1) {
          	?>
          	<a href="?page=<?php echo $page - 1; ?>">&lt;</a>
          	<?php
          } else {
          	?>
          	<span>&lt;</span>
          	<?php
          }
          ?>

          Selanjutnya kita perlu menghitung offset halaman, misalnya ketika kita berada di halaman pertama, maka offset sebelah kanan nomor halaman haruslah 2, sehingga total paging disebelah kanan nomor halaman 1 adalah 4 buah link. Ketika kita berada di akhir halaman, offset sebelah kiri nomor halaman haruslah 2, sehingga total link paging disebelah kiri nomor halaman terakhir adalah 4.

          Logikanya, kita set secara default variable $addition (jumlah offset halaman) menjadi 0. Ketika jumlah halaman - nomor halaman saat ini kurang dari jumlah seharusnya link paging sebelah kanan, Maka kita set addition untuk yang sebelah kiri menjadi sisanya ( jumlah seharusnya link sebelah kanan - jumlah halaman - nomor halaman saat ini ). Misalnya kita berada di halaman 10, dan total halaman 10, sisi kanan dan kiri seharusnya berisikan 2 link, maka variable $addition akan mendapatkan 2 - 10 - 10 = 2 tambahan link disebelah kiri.

          <?php
          $addition = 0;
          if ($total_page - $page < $each_side_size) {
          	$addition = $each_side_size - ($total_page - $page);
          }
          ?>

          Selanjutnya kita melakukan looping kebelakang untuk menampilkan link halaman sebelah kiri. Gunakan fungsi for, indeksnya dimulai dari Jumlah setiap sisi + additional dan berakir hingga indeksnya berada >= 1, pastikan untuk menggunakan $i-- agar kita melakukan looping kebelakang, bukan kedepan. Mengapa kebelakang? karena dengan demikian kita bisa mendapatkan nomor halaman untuk link tersebut dengan cara mengurangi halaman dengan indeks saat ini ($page - $i).

          Pastikan juga untuk membuat pengecekan kondisi nomor halaman haruslah lebih dari 0 untuk menghindari halaman minus. Kita juga akan mengurangi variable $paging_size setiap kali looping di sebelah kiri agar untuk nomor halaman sebelah kanan akan menampilkan sisanya.

          <?php
          for ($i = $each_side_size + $addition; $i >= 1; $i--) {
          	if ($page - $i > 0) {
          		$paging_size--;
          		?>
          		<a href="?page=<?php echo $page - $i; ?>"><?php echo $page - $i; ?></a>
          		<?php
          	}
          }
          ?>

          Setelah melakukan looping nomor halaman sebelah kiri, ditengah kita harus menampilkan nomor halaman saat ini dengan menggunakan tag HTML span.

          <span>
          	<?php echo $page; ?>
          </span>

          Untuk sebelah kanan kita hanya perlu melakukan looping kedepan dari 1 hingga sisa paging_size (sudah otomatis berkurang karena di looping sebelah kiri kita juga mengurangi variable ini). Untuk menampilkan nomor halamannya berarti halaman saat ini + indeksnya. Pastikan juga untuk mengecek agar indeksnya tidak lebih dari total halaman.

          <?php
          for ($i = 1; $i <= $paging_size; $i++) {
          	if ($page + $i <= $total_page) {
          		?>
          		<a href="?page=<?php echo $page + $i; ?>"><?php echo $page + $i; ?></a>
          		<?php
          	}
          }
          ?>

          Terakhir kita buat kondisi jika nomor halaman saat ini kurang dari total halaman, kita tampilkan link ke halaman selanjutnya dengan simbol >. Sedangkan jika tidak kurang dari total halaman kita gunakan tag html span.

          <?php
          if ($page < $total_page) {
          	?>
          	<a href="?page=<?php echo $page + 1; ?>">&gt;</a>
          	<?php
          } else {
          	?>
          	<span>&gt;</span>
          	<?php
          }
          ?>

          Hasil Akhir File PHP

          Ketika anda sudah menggabungkan keseluruhan kodenya menjadi sebuah file PHP, kurang lebih keseluruhan filenya akan seperti berikut:

          <!DOCTYPE html>
          <html>
          
          <head>
          	<meta name="viewport" content="width=device-width, initial-scale=1">
          	<meta charset="utf-8">
          	<title>Pagination</title>
          	<link rel="stylesheet" type="text/css" href="style.css" />
          </head>
          
          <body>
          	<main id="container">
          		<?php
          		$data = json_decode(file_get_contents('data.json'), TRUE);
          		$page = is_numeric(@$_GET['page']) ? $_GET['page'] : 1;
          		$limit = 5;
          		$start = ($page - 1) * $limit;
          		$total_page = ceil((count($data) - 1) / $limit);
          		$items = array_slice($data, $start, $limit);
          		?>
          		<h1>Data Pagination Halaman
          			<?php echo $page; ?>
          		</h1>
          		<section class="item-list">
          			<?php
          			foreach ($items as $item) {
          				?>
          				<div class="item">
          					<h2>
          						<?php echo $item['name']; ?>
          					</h2>
          					<ul>
          						<li>Age :
          							<?php echo $item['age']; ?>
          						</li>
          						<li>Gender :
          							<?php echo $item['gender']; ?>
          						</li>
          						<li>Company :
          							<?php echo $item['company']; ?>
          						</li>
          						<li>Email :
          							<?php echo $item['email']; ?>
          						</li>
          						<li>Phone :
          							<?php echo $item['phone']; ?>
          						</li>
          						<li>Address :
          							<?php echo $item['address']; ?>
          						</li>
          					</ul>
          				</div>
          				<?php
          			}
          			?>
          		</section>
          		<nav id="paging">
          			<?php
          			$paging_size = 4;
          			$each_side_size = ($paging_size / 2);
          			if ($page > 1) {
          				?>
          				<a href="?page=<?php echo $page - 1; ?>">&lt;</a>
          				<?php
          			} else {
          				?>
          				<span>&lt;</span>
          				<?php
          			}
          			$addition = 0;
          			if ($total_page - $page < $each_side_size) {
          				$addition = $each_side_size - ($total_page - $page);
          			}
          			for ($i = $each_side_size + $addition; $i >= 1; $i--) {
          				if ($page - $i > 0) {
          					$paging_size--;
          					?>
          					<a href="?page=<?php echo $page - $i; ?>"><?php echo $page - $i; ?></a>
          					<?php
          				}
          			}
          			?>
          
          			<span>
          				<?php echo $page; ?>
          			</span>
          			<?php
          			for ($i = 1; $i <= $paging_size; $i++) {
          				if ($page + $i <= $total_page) {
          					?>
          					<a href="?page=<?php echo $page + $i; ?>"><?php echo $page + $i; ?></a>
          					<?php
          				}
          			}
          			if ($page < $total_page) {
          				?>
          				<a href="?page=<?php echo $page + 1; ?>">&gt;</a>
          				<?php
          			} else {
          				?>
          				<span>&gt;</span>
          				<?php
          			}
          			?>
          		</nav>
          	</main>
          </body>
          
          </html>

          Menambahkan CSS

          Di awal saya menjelaskan kita meload css dari file style.css yang belum kita buat, disini saya menambahkan sedikit css untuk mempercantik tampilan:

          * {
          	box-sizing: border-box;
          }
          
          a {
          	text-decoration: none;
          }
          
          body {
          	font-family: sans-serif;
          	--primary: #001d35;
          	--secondary: #c2e7ff;
          	--secondary-light: #f3f6fc;
          	color: #000000d0;
          	font-size: 11pt;
          	line-height: 1.5;
          	background-color: var(--secondary-light);
          }
          
          #container {
          	max-width: 1000px;
          	margin: auto;
          	padding: 40px 0;
          }
          h1 {
          	text-align: center;
          	margin-bottom: 40px;
          }
          .item {
          	padding: 20px;
          	background-color: var(--secondary);
          	margin: 20px 0;
          	border-radius: 10px;
          }
          
          .item a {
          	color: var(--primary);
          }
          
          #paging {
          	display: flex;
          	flex-wrap: wrap;
          	justify-content: center;
          	margin: 10px 0;
          	gap: 5px;
          }
          
          #paging a,
          #paging span {
          	font-weight: bold;
          	display: inline-flex;
          	align-items: center;
          	justify-content: center;
          	width: 35px;
          	height: 35px;
          	background: var(--secondary);
          	color: var(--primary);
          	border-radius: 5px;
          }
          
          #paging span {
          	background: var(--primary);
          	color: var(--secondary-light);
          }
          

          Saya tidak akan menjelaskan isi dari CSS tersebut karena tujuan dari artikel ini bukanlah hal itu. Apalagi sebenarnya kita diperbolehkan untuk menggunakan bootstrap.

          Menjalankan File PHP

          Silahkan coba jalankan file PHP tersebut, boleh menggunakan XAMPP ataupun built in server dari PHP. Saya menggunakan linux, sehingga cara mudahnya adalah menggunakan built in server dari PHP:

          php -S localhost:8080

          Setelah mengunjungi halaman development server anda, seharusnya akan memunculkan tampilan seperti berikut ini:

          Preview hasil akhir tutorial

          Silahkan coba untuk berpindah halaman, seharusnya hasilnya sudah sesuai dengan requirements dari soal.

          Kesimpulan

          Membuat pagination menggunakan bahasa pemrograman PHP sebenarnya tidaklah terlalu sulit ketika anda sudah memahami fungsi-fungsi dasar PHP. Fungsi-fungsi for, foreach dan if else saja sebenarnya sudah cukup untuk membuat pagination sederhana. Namun, karena data yang diberikan berupa JSON kita juga membutuhkan fungsi json_decode dan file_get_contents untuk memparse datanya.

          Jika anda memiliki pertanyaan, jangan ragu untuk menghubungi media sosial saya!

          Terima Kasih telah membaca artikel ini, semoga bermanfaat!