PWEB - Latihan Membuat Web Pencarian Kode Pos

 Latihan Membuat Web Pencarian Kode Pos


Nama :Putu Ravindra Wiguna

NRP : 5025201237


    Pada latihan kali ini, diminta untuk membuat suatu website yang dapat melakukan pencarian kode pos dari nama Provinsi, Kabupaten/Kota, Kecamatan, dan Kelurahan. Untuk kali ini website yang saya buat ini masih menggunakan vanilla HTML-CSS-JS. 

    Proses pengerjaan website ini saya mulai dengan mencari tutorial bagaimana cara membuat dropdown pada website. Saya menggunakan dropdown ini untuk mencegah user memasukkan input yang invalid serta memudahkan user untuk menemukan daerah yang ingin dicari. Setelah melakukan googling, saya menemukan tutorial untuk membuat dropdown yang dynamic yaitu pada link berikut: Create dynamic DropDownList in HTML using JavaScript . Alasan dibuat dynamic adalah agar input daerah berikutnya yang merupakan bagian dari daerah sebelumnya ( misalkan provinsi lalu kabupaten) terikat, sehingga memudahkan user menemukan daerah yang diinginkan serta mengurangi input invalid dan juga agar dropdown list tidak berisi terlalu banyak item. Setelah memahami kode pada website tersebut, saya memodifikasinya untuk keperluan website saya.

    Lalu untuk data yang akan ditampilkan pada dropdown tersebut setelah berpikir panjang, saya memutuskan untuk mengambil data dari suatu file JSON untuk memudahkan parsing dan pengambilan data/atribut dari data yang ada karena dari javascript sendiri sudah menghandle hal tersebut dan pengambilan data dari JSON tersebut cukup intuitive dan mudah dibaca dan dilakukan (oleh programmer). Namun untuk mencari file JSON tersebut saya belum menemukannya, sehingga yang saya lakuan mengubah data yang saya temui (berformat .csv) yang sudah ditambahkan kolom dibagian atas csv, dari link berikut: Wilayah-Administratif-Indonesia/csv at master · edwardsamuel/Wilayah-Administratif-Indonesia (github.com) ke format .json dengan bantuan website csv to json berikut ini: CSVJSON - CSVJSON
    Untuk mengambil data dari json tersebut, saya mencari tutorial kembali, dan mendapatkan tutorial dari The Coding Train: (1) 1.4: JSON - Working with Data and APIs in JavaScript - YouTube. Setelah beberapa trial and error saya berhasil mendapatkan data dari json dan ditampilkan di dropdown.

    Langkah selanjutnya adalah agar membuat isi dropdown dinamis, di sini yang saya lakukan adalah mengambil (fetch) data json kabupaten, kecamatan, dan kelurahan pada awal saat membuka website untuk mempersingkat waktu, kemudian data yang sudah diambil tersebut saya filter sesuai dengan daerah di atasnya. Awalnya saya menggunakan fungsi .filter pada javascript, namun fungsi tersebut sangat lambat untuk data yang banyak, maka dari itu saya memotong waktu untuk memfilter data dari O(n) fungsi filter (sepertinya kompleksitas filter adalah O(n), tetapi belum dapat saya konfirmasi) menjadi O(log(n) + k). Yakni dengan menggunakan binary search lalu melaukan linear search hingga menemukan keseluruhan data yang sesuai. Hal ini dapat dilakukan karena csv yang saya dapat telah terurut dan masing-masing daerah memiliki kode yang berupa integer.

    Setelah mengimplementasikan hal tersebut, sekarang waktunya mendapatkan kode pos. Ini saya dapatkan dari repository github berikut: ArrayAccess/Indonesia-Postal-And-Area: Indonesia Postal Code & Area (BPS) (github.com)  yang didalamnya terdapat directory - directory yang berisikan file json mengenai informasi kode pos daerah termasuk nama, dan atribut lainnya. Sama seperti di atas, file json dari github tersebut saya fetch yang urlnya saya sesuaikan dengan kode provinsi, kabupaten, dan kecamatan hingga kelurahannya. Terakhir menambahkan hasil json kode pos ke HTML.

    Fitur utama telah selesai, dan kini saatnya menambahkan sedikit CSS agar tampilan website lebih menarik. Itulah proses pembuatan tugas ini, dan berikut adalah source code programnya:

index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kode Pos</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="title">
<h1>Pencari Kode Pos</h1>
</div>
<div class="content">
<div id="provinsi">
<p>Provinsi</p>
<p id="debugProvinsi">Sedang mengambil data</p>
<select name="nama_provinsi" id="dropdownProvinsi" onchange="updateKabupaten()">
<option value="Empty">Empty</option>
</select>
</div>
<div id="kotaKabupaten">
<p>Kota atau Kabupaten</p>
<p id="debugKabupaten"></p>
<select name="nama_kabupaten" id="dropdownKabupaten" onchange="updateKecamatan()">
<option value="Empty">Empty</option>
</select>
</div>
<div id="kecamatan">
<p>Kecamatan</p>
<p id="debugKecamatan"></p>
<select name="nama_kecamatan" id="dropdownKecamatan" onchange="updateKelurahan()">
<option value="Empty">Empty</option>
</select>
</div>
<div id="kelurahan">
<p>Desa atau Kelurahan</p>
<p id="debugKelurahan"></p>
<select name="nama_kelurahan" id="dropdownKelurahan">
<option value="Empty">Empty</option>
</select>
</div>
<div id="output">
<p>Hasil Pencarian</p>
<div id="result">
</div>
<a href="#" id="tombolCari" onclick="getKodePos()">Cari!</a>
</div>
</div>
<script src="js/script.js"></script>
</body>
</html>
view raw index.html hosted with ❤ by GitHub


style.css

@import url('https://fonts.googleapis.com/css2?family=Kreon:wght@300;400;500;600;700&family=Ubuntu:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap');
body, html{
height: 100%;
margin: 0;
padding: 0;
/* font-family: 'Ubuntu', arial; */
font-family: 'Kreon', arial;
text-align: center;
background-color: rgb(244, 207, 165);
}
.title{
font-family: 'Ubuntu', arial;
background-color: rgb(218, 125, 19);
height: fit-content;
padding-top: 10px;
display: flex;
justify-content: center ;
text-transform: uppercase;
}
.content{
/* padding-top: 10px; */
/* margin-top: -10px; */
font-size: 25px;
}
#tombolCari{
background-color: white;
padding: 5px 25px;
text-decoration: none;
color: black;
border-radius: 15px;
}
select{
font-family: 'Ubuntu', arial;
padding: 5px 25px;
text-align: center;
border-radius: 5px;
text-transform: uppercase;
font-weight: 400;
width: 50vw;
}
view raw style.css hosted with ❤ by GitHub


script.js

// ===== UTIL FUNCTIONs =========
function UpdateDropDownList(idDropDown, dataOption) {
// get DropDownList element.
let dropDownElement = document.getElementById(idDropDown);
while (dropDownElement.hasChildNodes()) {
dropDownElement.removeChild(dropDownElement.firstChild);
}
// default
let temp = document.createElement("OPTION");
temp.innerHTML = "Pilih Salah Satu";
temp.value = "-1";
//Add the Option element to DropDownList.
dropDownElement.options.add(temp);
// Add the Options to the DropDownList.
for (var i = 0; i < dataOption.length; i++) {
var option = document.createElement("OPTION");
option.innerHTML = dataOption[i].NamaDiri;
option.value = dataOption[i].KodeDiri;
dropDownElement.options.add(option);
}
};
function disable_dropdown(idDropDown){
let dd = document.getElementById(idDropDown);
dd.disabled = true;
}
function enable_dropdown(idDropDown){
let dd = document.getElementById(idDropDown);
dd.disabled = false;
}
// ========================================================================= //
// urls tempat json
const url_provinsi = "./json/daerah/provinsi.json";
const url_kabupaten = "./json/daerah/kabupaten.json";
const url_kecamatan = "./json/daerah/kecamatan.json";
const url_kelurahan = "./json/daerah/kelurahan.json";
// --- FUNCTIONS TO FETCH JSON -----
async function getAllProvinsi(){
// display debug
let debug = document.getElementById("debugProvinsi");
debug.innerHTML = "Sedang mengambil data. . .";
const response = await fetch(url_provinsi);
const data = await response.json();
// console.log(data);
UpdateDropDownList("dropdownProvinsi", data);
debug.innerHTML = "";
// disable kabupaten dan kecamatan
disable_dropdown("dropdownKabupaten");
disable_dropdown("dropdownKecamatan");
disable_dropdown("dropdownKelurahan");
}
let fetchedDataKecamatan = null;
let hasfetchKecamatan = false;
async function initKecamatan(){
// display debug
let debug = document.getElementById("debugKecamatan");
debug.innerHTML = "Sedang mengambil data. . .";
const response = await fetch(url_kecamatan);
const data = await response.json();
fetchedDataKecamatan = data;
hasfetchKecamatan = true;
debug.innerHTML = "";
}
let fetchedDataKabupaten = null;
let hasfetchKabupaten = false;
async function initKabupaten(){
// display debug
let debug = document.getElementById("debugKabupaten");
debug.innerHTML = "Sedang mengambil data. . .";
const response = await fetch(url_kabupaten);
const data = await response.json();
fetchedDataKabupaten = data;
hasfetchKabupaten= true;
debug.innerHTML = "";
}
let fetchedDataKelurahan = null;
let hasfetchKelurahan = false;
async function initKelurahan(){
// display debug
let debug = document.getElementById("debugKelurahan");
debug.innerHTML = "Sedang mengambil data. . .";
const response = await fetch(url_kelurahan);
const data = await response.json();
fetchedDataKelurahan = data;
hasfetchKelurahan = true;
debug.innerHTML = "";
}
function binser_data_and_return_all(dataJson, tkodeParent){
let left = -1;
let right = dataJson.length+1;
/*
misal array ini dan cari 6
3 4 5 6 6 6 8 9
0 1 2 3 4 5 6 7
F F F T F F F F
l = -1, r = 9
m = 8/2 = 4
6 is same, but update r, r = 4
l = -1 r = 4
m = 3/2 = 1
4 is low, update l, l = 2
l = 2, r = 4
m = 6/2 = 3
6 is same, update r, r = 3
l = 2, r = 3
m = 2
5 is low, update l, l = 3
l = 3, r = 3
*/
while(left < right){
let middle = Math.floor((left+right)/2);
console.log(left, middle, right);
if(dataJson[middle].KodeParent < tkodeParent){
left = middle+1;
}
else if(dataJson[middle] > tkodeParent){
right = middle-1;
}
else{
// uh mundur sir, but jangan -1
right = middle;
}
}
// now linear search
let anakParent = [
];
for(let i = right;i<dataJson.length;i++){
// console.log(dataJson[i]);
if(dataJson[i].KodeParent == tkodeParent){
anakParent.push(dataJson[i]);
// console.log("tambah");
}
else if(dataJson[i].KodeParent > tkodeParent){
// console.log("selesai");
break;
}
}
return anakParent;
}
async function getAllKabupaten(kodeProvinsi){
// display debug
let debug = document.getElementById("debugKabupaten");
debug.innerHTML = "Sedang mengambil data. . .";
let data = null;
if(! hasfetchKabupaten){
const response = await fetch(url_kabupaten);
data = await response.json();
fetchedDataKabupaten = data;
}
else{
data = fetchedDataKabupaten;
}
debug.innerHTML = "Sedang memfilter kabupaten";
let filtered_kabupaten = binser_data_and_return_all(data, kodeProvinsi);
UpdateDropDownList("dropdownKabupaten", filtered_kabupaten);
hasfetchKabupaten = true;
debug.innerHTML = "";
}
async function getAllKelurahan(kodeKecamatan){
// display debug
let debug = document.getElementById("debugKelurahan");
debug.innerHTML = "Sedang mengambil data. . .";
let data = null;
if(! hasfetchKelurahan){
const response = await fetch(url_kecamatan);
data = await response.json();
fetchedDataKecamatan = data;
}
else{
data = fetchedDataKelurahan;
}
debug.innerHTML = "Sedang memfilter kelurahan";
console.log(data[0]);
let filtered_kelurahan = binser_data_and_return_all(data, kodeKecamatan);
UpdateDropDownList("dropdownKelurahan", filtered_kelurahan);
hasfetchKelurahan = true;
debug.innerHTML = "";
}
async function getAllKecamatan(kodeKabupaten){
// display debug
let debug = document.getElementById("debugKecamatan");
debug.innerHTML = "Sedang mengambil data. . .";
let data = null;
if(! hasfetchKecamatan){
const response = await fetch(url_kecamatan);
data = await response.json();
fetchedDataKecamatan = data;
}
else{
data = fetchedDataKecamatan;
}
debug.innerHTML = "Sedang memfilter kecamatan";
let filtered_kecamatan = binser_data_and_return_all(data, kodeKabupaten);
UpdateDropDownList("dropdownKecamatan", filtered_kecamatan);
hasfetchKecamatan = true;
debug.innerHTML = "";
}
function updateKabupaten(){
let dde = document.getElementById("dropdownProvinsi");
let kodeProvinsi = dde.value;
if(kodeProvinsi != -1){
getAllKabupaten(kodeProvinsi);
// enable kabupaten
enable_dropdown("dropdownKabupaten");
}
// disable kecamatan, suruh milih kabupaten dulu
disable_dropdown("dropdownKecamatan");
disable_dropdown("dropdownKelurahan");
}
function updateKecamatan(){
let dde = document.getElementById("dropdownKabupaten");
let kodeKabupaten = dde.value;
if(kodeKabupaten != -1){
getAllKecamatan(kodeKabupaten);
// enable kecamatan
enable_dropdown("dropdownKecamatan");
}
// disable kelurahan
disable_dropdown("dropdownKelurahan");
}
function updateKelurahan(){
let dde = document.getElementById("dropdownKecamatan");
let kodeKecamatan = dde.value;
if(kodeKecamatan != -1){
getAllKelurahan(kodeKecamatan);
// enable kelurahan
enable_dropdown("dropdownKelurahan");
}
}
function get_postal_json_url(){
//example: "https://raw.githubusercontent.com/ArrayAccess/Indonesia-Postal-And-Area/master/data/json/area/62/11/1101/1101010/1101010.json"
let kodeProvinsi = document.getElementById("dropdownProvinsi").value;
let kodeKabupaten = document.getElementById("dropdownKabupaten").value;
let kodeKecamatan = document.getElementById("dropdownKecamatan").value;
let kodeKelurahan = document.getElementById("dropdownKelurahan").value;
if(kodeKelurahan != -1){
return `https://raw.githubusercontent.com/ArrayAccess/Indonesia-Postal-And-Area/master/data/json/area/62/${kodeProvinsi}/${kodeKabupaten}/${kodeKecamatan}/${kodeKelurahan}/${kodeKelurahan}.json`;
}
return `https://raw.githubusercontent.com/ArrayAccess/Indonesia-Postal-And-Area/master/data/json/area/62/${kodeProvinsi}/${kodeKabupaten}/${kodeKecamatan}/${kodeKecamatan}.json`;
}
async function getKodePos(){
if(!document.getElementById("dropdownKecamatan").disabled && document.getElementById("dropdownKecamatan").value != -1){
let data = null;
// alert("nyari");
let result = document.getElementById("result");
const response = await fetch(get_postal_json_url());
data = await response.json();
result.innerHTML = `
<p>Kode Pos:</p>
<p>${data.postal}</p>
`;
}
else{
alert("Mohon memilih daerah hingga paling tidak ditingkat kecamatan");
}
}
// ambil kelurahan
initKelurahan();
// ambil kecamatan dulu deh
initKecamatan();
// ambil kabupaten juga dulu deh
initKabupaten();
// ambil semua data provinsi dan update dropdown list
getAllProvinsi();
view raw script.js hosted with ❤ by GitHub


Selengkapnya dapat dilihat pada repository github berikut: RavindraWiguna/MembuatWebPencariKodePos (github.com)


Berikut Link websitenya: Kode Pos (ravindrawiguna.github.io)

Berikut tampilan website: 



Komentar

Postingan populer dari blog ini

Latihan CRUD - Pendaftaran Siswa Baru

Latihan membuat laporan PDF