[Tugas 3 Pemrograman Web - Codepostal - Website Pencari Kode Pos Melalui Provinsi, Kota/Kabupaten, Kecamatan, Kelurahan]

 

  •  Hilmi Zharfan Rachmadi
  • 5025201268
  • Pemrograman Web Kelas B
Berikut adalah sumber yang saya gunakan untuk database Provinsi, Kota/Kabupaten, Kecamatan, Kelurahan dan Kode Pos: edwin/database-kodepos-seluruh-indonesia: SQL Dump untuk data kodepos seluruh Indonesia (MySQL) (github.com)

Dengan bantuan Notepad++, Database ini saya konversi menjadi file .csv


Kemudian, dengan Excel, saya mengedit file .csv agar sesuai urutan Provinsi, Kota/Kabupaten, Kecamatan, Kelurahan, dan Kode Pos. Selain itu, saya juga memformatnya agar sesuai dengan syntax array JS. 




Dalam membuat dependent dropdown yang datanya di-populate dari array, saya menggunakan referensi video berikut: (125) HTML JavaScript Dependent Dropdown List, Cascading Unlimited Levels - e.2 p.1 - YouTube

Kode HTML:

<!DOCTYPE html>
<html lang="en">

<head>

    <title>Codepostal</title>

    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <link rel="stylesheet" type="text/css" href="assets/css/style.css">
    <link rel="preconnect" href="https://fonts.gstatic.com">

    <!-- Fonts -->
    <link href='https://fonts.googleapis.com/css?family=Raleway:100,200,300,400,500,600,700,800,900' rel='stylesheet'>

    <!-- Icons -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css" integrity="sha512-xh6O/CkQoPOWDdYTDqeRdPCVd1SpvCA9XXcUnZS2FmJNp1coAFzvtCN9BmamE+4aHK8yyUHUSCcJHgXloTyT2A==" crossorigin="anonymous" referrerpolicy="no-referrer"
    />

</head>

<body>

    <!----Header Section Start---->
    <div class="header">
        <h2>CODE<span>POSTAL</span></h2>
        <h3 id="description">Mencari Kode Pos berdasarkan Provinsi, Kota/Kabupaten, Kecamatan, dan Kelurahan</h3>
    </div>
    <!-- Header Section End-->

    <!----Content Section Start---->
    <section>
        <div class="container">
            <div class="card">
                <div class="card-content">
                    <div class="content">
                        <!----Dropdown Section Start---->
                        <div>
                            <div class="dropdown-menu" id="provinsi-drop">
                                <label class="label">Provinsi</label>
                                <div class="control">
                                    <div class="select is-rounded" id="select-provinsi">
                                        <select id="provinsi"> </select>
                                    </div>
                                </div>
                            </div>
                            <div class="dropdown-menu" id="kabupaten-drop">
                                <label class="label">Kota atau Kabupaten</label>
                                <div class="control">
                                    <div class="select is-rounded" id="select-kotakab">
                                        <select id="kabupaten"></select>
                                    </div>
                                </div>
                            </div>
                            <div class="dropdown-menu" id="kecamatan-drop">
                                <label class="label">Kecamatan</label>
                                <div class="control">
                                    <div class="select is-rounded" id="select-kecamatan">
                                        <select id="kecamatan"></select>
                                    </div>
                                </div>
                            </div>
                            <div class="dropdown-menu" id="kelurahan-drop">
                                <label class="label">Kelurahan</label>
                                <div class="control">
                                    <div class="select is-rounded" id="select-kecamatan">
                                        <select id="kelurahan"></select>
                                    </div>
                                </div>
                            </div>
                            <div class="dropdown-menu" id="kodepos-drop">
                                <label class="label">Hasil Kode Pos</label>
                                <div class="control">
                                    <div class="select is-rounded" id="select-kecamatan">
                                        <select id="kodepos"></select>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <!----Dropdown Section End---->
                    </div>
                </div>
            </div>
        </div>
    </section>
    <!----Content Section End---->

    <!----Footer Section Start---->
    <div class="footer">

    </div>
    <!-- Footer Section End-->

    <script src="assets/js/main.js"></script>
</body>

</html>

Kode CSS:

* {
    padding: 0;
    margin: 0;
    font-family: 'Raleway', sans-serif;
    box-sizing: inherit;
}

html {
    box-sizing: border-box;
}


/* Header */

.header {
    background-color: transparent;
    padding: 20px 40px;
}

.header h2 {
    margin: 0;
    font-weight: 800;
    font-size: 4.5rem;
    color: white;
    text-align: center;
}

.header h2 span {
    color: #fb7500;
}

#description {
    margin-top: -15px;
    text-align: center;
    color: white;
    font-weight: 400;
    font-size: 0.75rem;
}


/* Content */

body {
    background-image: url(../img/bg.png);
    color: #4a4a4a;
    font-size: 1rem;
    font-weight: 400;
    line-height: 1.5
}

.section {
    padding: 3rem 1.5rem
}

.container {
    flex-grow: 1;
    margin: 0 auto;
    margin-top: 20px;
    margin-bottom: -25px;
    position: relative;
    width: auto
}

.card {
    background: rgba(0, 0, 0, 0.7);
    border-radius: .25rem;
    box-shadow: 0 .5em 1em -.125em rgba(10, 10, 10, .1), 0 0 0 1px rgba(10, 10, 10, .02);
    color: #4a4a4a;
    padding-left: 1rem;
    padding-top: 1rem;
    padding-bottom: 1rem;
    max-width: 100%;
    overflow: hidden;
    position: relative
}

.card-content {
    padding: 1.5rem
}


/* Dropdown */

#kabupaten-drop {
    margin-top: 1rem !important
}

#kecamatan-drop {
    margin-top: 1rem !important
}

#kelurahan-drop {
    margin-top: 1rem !important
}

#kodepos-drop {
    margin-top: 1rem !important
}

.select:not(.is-multiple):not(.is-loading):after {
    border: 3px solid transparent;
    border-radius: 2px;
    border-right: 0;
    border-top: 0;
    content: " ";
    display: block;
    height: .625em;
    margin-top: -.4375em;
    pointer-events: none;
    position: absolute;
    top: 50%;
    transform: rotate(-45deg);
    transform-origin: center;
    width: .625em
}

.select {
    display: inline-block;
    max-width: 100%;
    position: relative;
    vertical-align: top
}

.select select {
    -moz-appearance: none;
    -webkit-appearance: none;
    align-items: center;
    border: 1px solid transparent;
    border-radius: 4px;
    box-shadow: none;
    display: inline-flex;
    font-size: 1rem;
    height: 2.5em;
    justify-content: flex-start;
    line-height: 1.5;
    padding: calc(.5em - 1px) calc(.75em - 1px);
    position: relative;
    vertical-align: top;
    background-color: black;
    border-color: #dbdbdb;
    border-radius: 4px;
    color: white;
}

.select:not(.is-multiple):not(.is-loading):after {
    border-color: #fb7500;
    right: 1.125em;
    z-index: 4
}

.select.is-rounded select {
    border-radius: 290486px;
    padding-left: 1em
}

.select select:not([multiple]) {
    padding-right: 2.5em
}

.option {
    /* Whatever color  you want */
    background-color: #82caff;
}

.label {
    color: #fb7500;
    display: block;
    font-size: 1rem;
    font-weight: 600;
}

.label:not(:last-child) {
    margin-bottom: .5em
}

*,
:after,
:before {
    box-sizing: inherit
}


/* Footer */

.footer {
    position: absolute;
    bottom: 0;
    width: 100%;
    height: 1.5rem;
    background: #fb7500;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}


/* Responsive */

@media print,
screen and (min-width:769px) {
    .columns:not(.is-desktop) {
        display: flex
    }
}

@-webkit-keyframes spinAround {
    0% {
        transform: rotate(0)
    }
    to {
        transform: rotate(359deg)
    }
}

@keyframes spinAround {
    0% {
        transform: rotate(0)
    }
    to {
        transform: rotate(359deg)
    }
}

@media screen and (min-width:1024px) {
    .container {
        max-width: 960px
    }
}

@media screen and (min-width:1216px) {
    .container:not(.is-max-desktop) {
        max-width: 1152px
    }
}

@media screen and (min-width:1408px) {
    .container:not(.is-max-desktop):not(.is-max-widescreen) {
        max-width: 1344px
    }
}

Kode JS:
// Class for dropdown menus
class DropDown {

    constructor(data) {
        this.data = data;
        this.targets = [];
    }

    // Filter dropdown data based on previous levels
    filterData(filtersAsArray) {
        return this.data.filter(r => filtersAsArray.every((item, i) => item === r[i]));
    }

    // Get unique values
    getUniques(dataAsArray, index) {
        const uniqueOptions = new Set();
        dataAsArray.forEach(r => uniqueOptions.add(r[index]));
        return [...uniqueOptions];
    }

    populateDropdown(el, listAsArray) {
        el.innerHTML = "";
        listAsArray.forEach(item => {
            const option = document.createElement("option");
            option.textContent = item;
            el.appendChild(option);
        });
    }

    createPopulateDropdownFunction(el, elsDependsOn) {
        return () => {
            const elsDependsOnValues = elsDependsOn.length === 0 ? null : elsDependsOn.map(depEl => depEl.value);
            const dataToUse = elsDependsOn.length === 0 ? this.data : this.filterData(elsDependsOnValues);
            const listToUse = this.getUniques(dataToUse, elsDependsOn.length);
            this.populateDropdown(el, listToUse);
        }
    }

    add(options) {
        const el = options.target;
        const elsDependsOn = options.dependsOn.length === 0 ? [] : options.dependsOn;
        const eventFunction = this.createPopulateDropdownFunction(el, elsDependsOn);
        const targetObject = { el: el, elsDependsOn: elsDependsOn, func: eventFunction };
        targetObject.elsDependsOn.forEach(depEl => depEl.addEventListener("change", eventFunction));
        this.targets.push(targetObject);
        return this;
    }

    initialize() {
        this.targets.forEach(t => t.func());
        return this;
    }

    quickDropDown(arrayOfIds) {
        arrayOfIds.forEach((item, i) => {
            const option = { target: item, dependsOn: arrayOfIds.slice(0, i) };
            this.add(option);
        });
        this.initialize();
        return this;
    }

}

// Postal code data taken from a database in github
var postalData = [
    ["DKI JAKARTA", "JAKARTA PUSAT", "GAMBIR", "GAMBIR", "10110"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "GAMBIR", "KEBON KELAPA", "10120"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "GAMBIR", "PETOJO UTARA", "10130"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "GAMBIR", "DURI PULO", "10140"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "GAMBIR", "CIDENG", "10150"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "GAMBIR", "PETOJO SELATAN", "10160"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "TANAH ABANG", "BENDUNGAN HILIR", "10210"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "TANAH ABANG", "KARET TENGSIN", "10220"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "TANAH ABANG", "KEBON MELATI", "10230"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "TANAH ABANG", "KEBON KACANG", "10240"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "TANAH ABANG", "KAMPUNG BALI", "10250"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "TANAH ABANG", "PETAMBURAN", "10260"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "TANAH ABANG", "GELORA", "10270"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "MENTENG", "MENTENG", "10310"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "MENTENG", "PEGANGSAAN", "10320"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "MENTENG", "CIKINI", "10330"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "MENTENG", "KEBON SIRIH", "10340"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "MENTENG", "GONDANGDIA", "10350"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "SENEN", "SENEN", "10410"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "SENEN", "KWITANG", "10420"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "SENEN", "KENARI", "10430"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "SENEN", "PASEBAN", "10440"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "SENEN", "KRAMAT", "10450"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "SENEN", "BUNGUR", "10460"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "CEMPAKA PUTIH", "CEMPAKA PUTIH TIMUR", "10510"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "CEMPAKA PUTIH", "CEMPAKA PUTIH BARAT", "10520"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "JOHAR BARU", "GALUR", "10530"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "JOHAR BARU", "TANAH TINGGI", "10540"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "JOHAR BARU", "KAMPUNG RAWA", "10550"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "JOHAR BARU", "JOHAR BARU", "10560"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "CEMPAKA PUTIH", "RAWASARI", "10570"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "KEMAYORAN", "GUNUNG SAHARI SELATAN", "10610"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "KEMAYORAN", "KEMAYORAN", "10620"],
    ["DKI JAKARTA", "JAKARTA PUSAT", "KEMAYORAN", "KEBON KOSONG", "10630"]
];

var level1 = document.getElementById("provinsi");
var level2 = document.getElementById("kabupaten");
var level3 = document.getElementById("kecamatan");
var level4 = document.getElementById("kelurahan");
var level5 = document.getElementById("kodepos");

var dd = new DropDown(postalData).quickDropDown([level1, level2, level3, level4, level5]);

Di atas saya hanya menampilkan beberapa datanya saja, karena data aslinya sangat banyak, mencapai sekitar 81000.

Berikut adalah tampilan website Codepostal:


Website sudah di-deploy dan dapat dikunjungi melalui link berikut: Codepostal (hilmizr.github.io)
Link Repository: https://github.com/hilmizr/codepostal.git

Comments