Modul 7: Tabel Buah Editable [2]

Tujuan Program

Tujuan Program

Tujuan dari program ini adalah untuk membuat tabel buah yang dapat diedit oleh pengguna. Pengguna dapat memasukkan informasi nama buah, berat buah, dan URL gambar buah melalui formulir di bagian atas halaman. Setelah memasukkan data, pengguna dapat menekan tombol "Add" untuk menambahkan baris baru ke dalam tabel buah. Tabel ini memiliki fungsi tambahan, seperti mengatur batas berat buah dan memberi warna latar belakang merah pada sel-sel yang melebihi batas berat tersebut. Selain itu, setiap baris tabel memiliki tombol "Edit" yang memungkinkan pengguna mengedit informasi buah yang telah dimasukkan, dan tombol "Delete" untuk menghapus baris dari tabel.

Tampilan Awal Program

Tampilan Setelah Menekan "Add"

Tampilan Setelah "Save"

Tetapkan Berat Buah Maksimal


Source Code

Source code program ini bisa dilihat di Repository berikut: Source Code Mini Project
Github Repository: Main Repository

Kalian bisa mencoba program ini secara online dengan mengakses link berikut: Github Pages
  index.html
<!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Mini Project 2</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <h1>Table Buah Editable</h1>
        <form>
            <label class="item-a">Nama Buah</label>
            <input type="text" id="inputNamaBuah" class="item-b" placeholder="Insert Fruit Name"> <br>
            <label class="item-c">Jumlah Berat</label>
            <input type="number" id="inputBeratBuah" min="1" class="item-d" placeholder="Insert Fruit Weight">
            <span class="item-e">Kg</span> <br>
            <label class="item-f">Gambar</label>
            <input type="text" id="inputGambarBuah" class="item-g" placeholder="Insert Fruit Image Link (Enable Internet)"> <br>
            <button onclick="addFruitData()" class="item-h">Add</button>
        </form>
    
        <hr>
        
        <span>Tetapkan Limit Berat Buah:</span> <br>
        <input type="number" id="setWeight" min="1" placeholder="Set Fruit Max Weight">
        <button onclick="setWeight()">Set</button> <br>
    
        <table id="isiTableBuah">
            <tr>
                <th>No</th>
                <th>Nama Buah</th>
                <th>Berat</th>
                <th>Gambar</th>
                <th>Action</th>
            </tr>
        </table>
    
        <script src="script.js"></script>
    </body>
    </html>
    

  script.js
    // Dapatkan Elemen HTML
    const namaBuah = document.getElementById("inputNamaBuah");
    const beratBuah = document.getElementById("inputBeratBuah");
    const gambarBuah = document.getElementById("inputGambarBuah");
    const tableBuah = document.getElementById("isiTableBuah");
    
    
    // Function untuk menetapkan limit berat
    function setWeight() {
        let inputLimit = document.getElementById("setWeight");
    
        if (inputChecker(inputLimit)) {
            let limitValue = Number(inputLimit.value);
            let tableLength = tableBuah.childElementCount;
    
            for (let i = 1; i < tableLength; i++) {
                let tableDataBerat = tableBuah.getElementsByTagName("tr")[i].getElementsByTagName("td")[2];
    
                if (parseFloat(tableDataBerat.textContent) >= limitValue) {
                    tableDataBerat.style.backgroundColor = "red";
                } else {
                    tableDataBerat.style.backgroundColor = "";
                }
            }
        }
        
    }
    
    
    // Buat Function yang sering digunakan
    function createInput(inputType, inputValue) {
        let input = document.createElement("input");
        input.setAttribute("type", inputType);
        if (inputType === "number") {
            input.setAttribute("min", "1");
        }
        input.value = inputValue;
        return input;
    }
    
    function createButton(textContent, onclickFunction) {
        let button = document.createElement("button");
        button.textContent = textContent;
        button.setAttribute("onclick", onclickFunction);
        return button;
    }
    
    function createImg(src) {
        let img = document.createElement("img");
        img.setAttribute("src", src);
        img.setAttribute("alt", "Gambar Buah");
        img.setAttribute("width", "100vw");
        return img;
    }
    
    function inputChecker(inputElement) {
        return inputElement && inputElement.value;
    }
    
    
    // Function Utama
    // Function menambahkan data input ke table
    function addFruitData() {
        event.preventDefault();
        
        if (inputChecker(namaBuah) && inputChecker(beratBuah) && inputChecker(gambarBuah)) {
            let tr = document.createElement("tr");
    
            let nomorUrut = document.createTextNode(tableBuah.childElementCount);
    
            let tableInputNama = createInput("text", namaBuah.value);
            let tableInputBerat = createInput("number", Number(beratBuah.value));
            let tableInputGambar = createInput("text", gambarBuah.value);
            
            let deleteButton = createButton("Hapus", "deleteRow(this)");
            let saveButton = createButton("Save", "saveRow(this)");
    
            let buttonCell = document.createElement("div");
            buttonCell.appendChild(deleteButton);
            buttonCell.appendChild(saveButton);
    
            let tableDataArray = [
                nomorUrut,
                tableInputNama,
                tableInputBerat,
                tableInputGambar,
                buttonCell
            ]
    
            for (let i = 0; i < tableDataArray.length; i++) {
                let td = document.createElement("td");
                td.appendChild(tableDataArray[i]);
                tr.appendChild(td);
                tableBuah.appendChild(tr);  
            }
    
        } else {
            window.alert("INPUT TIDAK BOLEH KOSONG");
        }
    }
    
    // Function menyimpan input table dan menampilkan dalam format biasa
    function saveRow(button) {
        let tableButtonRow = button.closest("tr");
        if (tableButtonRow) {
            let namaBuah = tableButtonRow.children[1].getElementsByTagName("input")[0];
            let beratBuah = tableButtonRow.children[2].getElementsByTagName("input")[0];
            let gambarBuah = tableButtonRow.children[3].getElementsByTagName("input")[0];
                
            if (inputChecker(namaBuah) && inputChecker(beratBuah) && inputChecker(gambarBuah)) {
                let namaBuahText = document.createTextNode(namaBuah.value);
                let beratBuahText = document.createTextNode(beratBuah.value + " kg");
                let gambarBuahImg = createImg(gambarBuah.value);
    
                tableButtonRow.children[1].replaceChild(namaBuahText, namaBuah);
                tableButtonRow.children[2].replaceChild(beratBuahText, beratBuah);
                tableButtonRow.children[3].replaceChild(gambarBuahImg, gambarBuah);
    
                let buttonBuah = tableButtonRow.children[4].getElementsByTagName("div")[0];
                let deleteButton = buttonBuah.children[0];
                let saveButton = buttonBuah.children[1];
    
                buttonBuah.removeChild(deleteButton);
                buttonBuah.removeChild(saveButton);
    
                let editButton = createButton("Edit", "editRow(this)");
                buttonBuah.appendChild(editButton);
    
            } else {
                window.alert("INPUT TABLE TIDAK BOLEH KOSONG");
            }
        }
        setWeight();
    }
    
    // Function menghapus row table
    function deleteRow(button) {
        let tableButtonRow = button.closest("tr");
        if (tableButtonRow) {
            tableBuah.removeChild(tableButtonRow);
            updateNomorUrut();
        }
    }  
    
    // Function mengupdate nomor urut
    function updateNomorUrut() {
        let rows = tableBuah.getElementsByTagName("tr");
        for (let i = 0; i < rows.length; i++) {
            rows[i + 1].children[0].textContent = i + 1;
        }
    }
    
    // Function mengedit data
    function editRow(button) {
        let tableButtonRow = button.closest("tr");
    
        if (tableButtonRow) {
            let namaBuahText = tableButtonRow.children[1].textContent;
            let beratBuahText = tableButtonRow.children[2].textContent;
            let gambarBuahImgSrc = tableButtonRow.children[3].getElementsByTagName("img")[0].getAttribute("src");
    
            let inputNamaBuah = createInput("text", namaBuahText);
            let inputBeratBuah = createInput("number", parseFloat(beratBuahText));
            let inputGambarBuah = createInput("text", gambarBuahImgSrc);
    
            let inputDataArray = [
                inputNamaBuah,
                inputBeratBuah,
                inputGambarBuah
            ];
    
            for (let i = 0; i < inputDataArray.length; i++) {
                tableButtonRow.children[i + 1].replaceChild(inputDataArray[i], tableButtonRow.children[i + 1].firstChild);
            }
    
            let buttonBuah = tableButtonRow.children[4].getElementsByTagName("div")[0];
            let editButton = buttonBuah.getElementsByTagName("button")[0];
            buttonBuah.removeChild(editButton);
    
            let deleteButton = createButton("Hapus", "deleteRow(this)");
            let saveButton = createButton("Save", "saveRow(this)");
            buttonBuah.appendChild(deleteButton);
            buttonBuah.appendChild(saveButton);
        }
    }
    

Pembahasan

1. Buat Struktur HTML

Buat struktur HTML seperti pada source code. Bagian HTML bertujuan untuk membentuk antarmuka pengguna (UI). Pada HTML, terdapat form yang memungkinkan pengguna memasukkan informasi nama buah, berat buah, dan URL gambar buah. Setelah itu, terdapat tombol "Add" untuk menambahkan data buah ke dalam tabel.

2. Tambahkan Javascript

Tambahkan tag <script> pada HTML untuk menambahkan Javascript. Bila Javascript berada di file terpisah (external), tambahkan attribute 'src'. Kode seperti pada source code script.js.

Pembahasan Javascript Source Code

1. Inisialisasi variabel, dapatkan elemen HTML berdasarkan id dan simpan dalam variabel.
const namaBuah = document.getElementById("inputNamaBuah");
const beratBuah = document.getElementById("inputBeratBuah");
const gambarBuah = document.getElementById("inputGambarBuah");
const tableBuah = document.getElementById("isiTableBuah");

2. Function membuat elemen Input, Button, dan Image.
Function createInput() digunakan untuk membuat elemen input HTML dengan jenis tertentu (misalnya, teks atau angka) dan nilai awal yang ditentukan. Fungsi ini menerima dua parameter: inputType untuk menentukan jenis input yang akan dibuat (misalnya, "text" atau "number") dan inputValue untuk menentukan nilai awal input tersebut. Selain itu, jika jenis input adalah "number", maka akan ditambahkan atribut "min" dengan nilai "1" untuk memastikan bahwa input angka memiliki nilai minimal yang valid.
function createInput(inputType, inputValue) {
    let input = document.createElement("input");
    input.setAttribute("type", inputType);
    if (inputType === "number") {
        input.setAttribute("min", "1");
    }
    input.value = inputValue;
    return input;
}

⟹ Function createButton() bertugas untuk membuat elemen tombol HTML dengan teks tertentu dan menetapkan fungsi yang akan dipanggil saat tombol tersebut ditekan. Fungsi ini menerima dua parameter: textContent untuk menentukan teks yang akan ditampilkan pada tombol dan onclickFunction untuk menetapkan fungsi yang akan dipanggil saat tombol ditekan.
function createButton(textContent, onclickFunction) {
    let button = document.createElement("button");
    button.textContent = textContent;
    button.setAttribute("onclick", onclickFunction);
    return button;
}

 Function createImg() digunakan untuk membuat elemen gambar HTML dengan sumber gambar (src) yang ditentukan. Fungsi ini menerima satu parameter: src untuk menentukan URL gambar yang akan ditampilkan. Setelah membuat elemen gambar, fungsi ini menetapkan atribut "alt" dengan nilai "Gambar Buah" untuk menyediakan deskripsi alternatif untuk gambar, dan atribut "width" dengan nilai "100vw" untuk menetapkan lebar gambar sesuai dengan lebar layar.
function createImg(src) {
    let img = document.createElement("img");
    img.setAttribute("src", src);
    img.setAttribute("alt", "Gambar Buah");
    img.setAttribute("width", "100vw");
    return img;
}


3. Function memeriksa Input, Function inputChecker() bertugas untuk memeriksa apakah sebuah elemen input tidak kosong. Fungsi ini menerima satu parameter: inputElement, yang merupakan elemen input HTML yang ingin diperiksa. Fungsi ini mengembalikan nilai true jika inputElement memiliki nilai yang tidak kosong, dan false jika sebaliknya.
function inputChecker(inputElement) {
    return inputElement && inputElement.value;
}

4. Function menambah data Input ke table, Function addFruitData() berfungsi untuk menambahkan data buah ke dalam tabel. Pertama, fungsi ini mencegah perilaku default dari formulir dengan menggunakan event.preventDefault() untuk menghindari pembaruan halaman. Selanjutnya, fungsi memeriksa apakah input nama buah, berat buah, dan URL gambar buah tidak kosong menggunakan inputChecker(). Jika input valid, function membuat elemen-elemen HTML yang dibutuhkan, seperti nomor urut, input nama buah, input berat buah, input gambar buah, tombol hapus, dan tombol simpan. Selanjutnya, function membentuk baris tabel baru dengan menambahkan elemen-elemen ini ke dalam elemen <tr>. Akhirnya, baris tabel baru tersebut ditambahkan ke dalam tabel buah. Jika ada input yang kosong, fungsi akan menampilkan pesan peringatan.
function addFruitData() {
    event.preventDefault();
    
    if (inputChecker(namaBuah) && inputChecker(beratBuah) && inputChecker(gambarBuah)) {
        let tr = document.createElement("tr");

        let nomorUrut = document.createTextNode(tableBuah.childElementCount);

        let tableInputNama = createInput("text", namaBuah.value);
        let tableInputBerat = createInput("number", Number(beratBuah.value));
        let tableInputGambar = createInput("text", gambarBuah.value);
        
        let deleteButton = createButton("Hapus", "deleteRow(this)");
        let saveButton = createButton("Save", "saveRow(this)");

        let buttonCell = document.createElement("div");
        buttonCell.appendChild(deleteButton);
        buttonCell.appendChild(saveButton);

        let tableDataArray = [
            nomorUrut,
            tableInputNama,
            tableInputBerat,
            tableInputGambar,
            buttonCell
        ]

        for (let i = 0; i < tableDataArray.length; i++) {
            let td = document.createElement("td");
            td.appendChild(tableDataArray[i]);
            tr.appendChild(td);
            tableBuah.appendChild(tr);  
        }

    } else {
        window.alert("INPUT TIDAK BOLEH KOSONG");
    }
}

5. Function menyimpan data Input table, Function saveRow() berperan dalam menyimpan input yang dimasukkan pengguna dalam tabel dan menampilkan input tersebut dalam format yang biasa. Pertama, function mencari baris tabel terdekat dari tombol "Save" yang ditekan oleh pengguna. Kemudian, function memeriksa apakah input pada nama buah, berat buah, dan gambar buah tidak kosong. Jika input valid, function mengganti elemen input dengan teks biasa dan elemen input gambar dengan elemen gambar HTML. Selanjutnya, function menghapus tombol "Save" dan "Delete" dari baris tersebut dan menggantinya dengan tombol "Edit". Jika input tidak valid, maka akan muncul pesan peringatan.
function saveRow(button) {
    let tableButtonRow = button.closest("tr");
    if (tableButtonRow) {
        let namaBuah = tableButtonRow.children[1].getElementsByTagName("input")[0];
        let beratBuah = tableButtonRow.children[2].getElementsByTagName("input")[0];
        let gambarBuah = tableButtonRow.children[3].getElementsByTagName("input")[0];
            
        if (inputChecker(namaBuah) && inputChecker(beratBuah) && inputChecker(gambarBuah)) {
            let namaBuahText = document.createTextNode(namaBuah.value);
            let beratBuahText = document.createTextNode(beratBuah.value + " kg");
            let gambarBuahImg = createImg(gambarBuah.value);

            tableButtonRow.children[1].replaceChild(namaBuahText, namaBuah);
            tableButtonRow.children[2].replaceChild(beratBuahText, beratBuah);
            tableButtonRow.children[3].replaceChild(gambarBuahImg, gambarBuah);

            let buttonBuah = tableButtonRow.children[4].getElementsByTagName("div")[0];
            let deleteButton = buttonBuah.children[0];
            let saveButton = buttonBuah.children[1];

            buttonBuah.removeChild(deleteButton);
            buttonBuah.removeChild(saveButton);

            let editButton = createButton("Edit", "editRow(this)");
            buttonBuah.appendChild(editButton);

        } else {
            window.alert("INPUT TABLE TIDAK BOLEH KOSONG");
        }
    }
    setWeight();
}

6. Function menghapus baris (row) table dan update nomor urut.
 Function deleteRow() berfungsi untuk menghapus baris tabel yang mengandung tombol "Hapus" yang ditekan. Fungsi ini menggunakan method closest("tr") untuk mencari elemen <tr> terdekat yang mengandung tombol yang ditekan. Jika baris ditemukan, maka baris tersebut dihapus dari tabel, dan fungsi updateNomorUrut() dipanggil untuk memperbarui nomor urut pada setiap baris tabel.
function deleteRow(button) {
    let tableButtonRow = button.closest("tr");
    if (tableButtonRow) {
        tableBuah.removeChild(tableButtonRow);
        updateNomorUrut();
    }
}  

 Function updateNomorUrut() bertugas untuk mengupdate nomor urut pada setiap baris tabel setelah adanya perubahan dalam struktur tabel. Fungsi ini menggunakan metode getElementsByTagName("tr") untuk mendapatkan semua elemen <tr> dalam tabel. Selanjutnya, dilakukan iterasi melalui setiap baris tabel, dan nomor urut pada setiap baris diperbarui sesuai dengan indeks iterasi.
function updateNomorUrut() {
    let rows = tableBuah.getElementsByTagName("tr");
    for (let i = 0; i < rows.length; i++) {
        rows[i + 1].children[0].textContent = i + 1;
    }
}

7. Function mengedit data table, Function editRow() bertanggung jawab untuk mengaktifkan mode pengeditan pada baris tabel yang dipilih oleh pengguna. Ketika pengguna menekan tombol "Edit" pada suatu baris tabel, function ini akan dijalankan. Function ini mengambil baris tabel terdekat dari tombol "Edit" yang ditekan, kemudian mengambil nilai teks dari setiap sel pada baris tersebut. Nilai-nilai teks ini kemudian digunakan untuk membuat input baru untuk setiap kolom data, yang memungkinkan pengguna untuk mengedit nilai. Setelah input dibuat, tombol "Edit" dihapus dan tombol "Save" dan "Delete" ditambahkan untuk memungkinkan pengguna menyimpan perubahan atau membatalkan pengeditan.
function editRow(button) {
    let tableButtonRow = button.closest("tr");

    if (tableButtonRow) {
        let namaBuahText = tableButtonRow.children[1].textContent;
        let beratBuahText = tableButtonRow.children[2].textContent;
        let gambarBuahImgSrc = tableButtonRow.children[3].getElementsByTagName("img")[0].getAttribute("src");

        let inputNamaBuah = createInput("text", namaBuahText);
        let inputBeratBuah = createInput("number", parseFloat(beratBuahText));
        let inputGambarBuah = createInput("text", gambarBuahImgSrc);

        let inputDataArray = [
            inputNamaBuah,
            inputBeratBuah,
            inputGambarBuah
        ];

        for (let i = 0; i < inputDataArray.length; i++) {
            tableButtonRow.children[i + 1].replaceChild(inputDataArray[i], tableButtonRow.children[i + 1].firstChild);
        }

        let buttonBuah = tableButtonRow.children[4].getElementsByTagName("div")[0];
        let editButton = buttonBuah.getElementsByTagName("button")[0];
        buttonBuah.removeChild(editButton);

        let deleteButton = createButton("Hapus", "deleteRow(this)");
        let saveButton = createButton("Save", "saveRow(this)");
        buttonBuah.appendChild(deleteButton);
        buttonBuah.appendChild(saveButton);
    }
}

8. Function menetapkan limit berat buah, Function setWeight() bertanggung jawab untuk menetapkan batas berat buah yang ditentukan oleh pengguna dan mengubah warna latar belakang sel-sel tabel yang melebihi batas tersebut. Pertama, function ini mendapatkan nilai input batas berat dari elemen HTML dengan id "setWeight". Kemudian, dilakukan pemeriksaan apakah input tersebut valid menggunakan function inputChecker(). Jika valid, nilai batas berat diambil dan selanjutnya dilakukan iterasi melalui setiap baris tabel (mulai dari indeks 1, mengingat indeks 0 berisi header). Untuk setiap baris, berat buah pada sel kolom yang sesuai diambil, dan jika berat melebihi batas yang ditetapkan, warna latar belakang sel tersebut diubah menjadi merah; sebaliknya, jika tidak melebihi, warna latar belakang dikembalikan ke kondisi awal.
function setWeight() {
    let inputLimit = document.getElementById("setWeight");

    if (inputChecker(inputLimit)) {
        let limitValue = Number(inputLimit.value);
        let tableLength = tableBuah.childElementCount;

        for (let i = 1; i < tableLength; i++) {
            let tableDataBerat = tableBuah.getElementsByTagName("tr")[i].getElementsByTagName("td")[2];

            if (parseFloat(tableDataBerat.textContent) >= limitValue) {
                tableDataBerat.style.backgroundColor = "red";
            } else {
                tableDataBerat.style.backgroundColor = "";
            }
        }
    }
}

End

Jika sudah, kalian bisa mencoba program tersebut dengan mengakses laman ini.

Posting Komentar

0 Komentar