---
# System prepended metadata

title: TUẦN 3

---

TUẦN 3:
# **LẬP TRÌNH JAVASCRIPT**
Lập trình website theo đề bài: website có chức năng thêm, đọc, sửa, xóa (CRUD) các môn học bằng JavaScript.

## file index.html
```
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width>, initial-scale=1.0">
    <title>Môn học</title>
</head>
<body>
    <div class="form">
        <div class="form-group">
            <label for="name">Môn học:</label>
            <input id="name" type="text" class="form-input">
            <div class="error-message"></div>
        </div>

        <div class="form-group">
            <input id="index" type="hidden">
        </div>

        <button id="save" onclick="addNew()">Thêm môn học</button>
        <button id="update" onclick="changeSubject()" style="display: none">Sửa tên môn học</button>
    </div>

    <table border="1" id="tableContent">
        <tr>
            <th>ID</th>
            <th>Tên môn học</th>
            <th>Hoạt động</th>
            </tr>
    </table>

    <script src="crud.js"></script>
</body>
</html>
```

## file crud.js
```
// CRUD
function resetInput()
{
    document.getElementById("name").value = ""
}

function validateInput()
{
    let formElement = document.querySelector(".form")
    let inputElement = formElement.querySelectorAll(".form-input")
    for (let i = 0; i < inputElement.length; i++)
    {
        if (inputElement[i].value === "")
        {
            inputElement[i].parentElement.querySelector(".error-message").innerText = 'Nhập lại tên môn học.'
        }
        else
        {
            inputElement[i].parentElement.querySelector(".error-message").innerText = ""
        }
    }
}

function addNew()
{
    validateInput()
    let formElement = document.querySelector(".form")
    let errorElement = formElement.querySelectorAll(".error-message")
    console.log(errorElement)
    let arrErrorElement = []
    for (let i = 0; i < errorElement.length; i++)
    {
        console.log(errorElement[i].innerText)
        arrErrorElement.push(errorElement[i].innerText)
        console.log(arrErrorElement)
    }
    let checkErrorElement = arrErrorElement.every(value => value === "")
    if (checkErrorElement)
    {
        console.log("OK")
        let name = document.getElementById("name").value
        let ListSubject = localStorage.getItem("List-subject") ? JSON.parse(localStorage.getItem("List-subject")) : []
        ListSubject.push({
            name: name,
        })
        localStorage.setItem("List-subject", JSON.stringify(ListSubject))
        render()
        resetInput()
    }
}

function render()
{
    let ListSubject = localStorage.getItem("List-subject") ? JSON.parse(localStorage.getItem("List-subject")) : []
    let subject = `<tr>
    <th>ID</th>
    <th>Tên môn học</th>
    <th>Hoạt động</th>
    </tr>`

    ListSubject.map((value, index) => {
        subject += `<tr>
        <td>${index + 1}</td>
        <td>${value.name}</td>
        <td>
            <button onclick="editSubject(${index})">Sửa tên môn học</button>
            <button onclick="deleteSubject(${index})">Xóa môn học</button>
        </td>
        </tr>`
    })
    document.getElementById("tableContent").innerHTML = subject
}

function editSubject(index)
{
    let ListSubject = localStorage.getItem("List-subject") ? JSON.parse(localStorage.getItem("List-subject")) : []
    document.getElementById("name").value = ListSubject[index].name
    document.getElementById("index").value = index

    document.getElementById("save").style.display = "none"
    document.getElementById("update").style.display = "inline-block"
}

function changeSubject()
{
    let ListSubject = localStorage.getItem("List-subject") ? JSON.parse(localStorage.getItem("List-subject")) : []
    let index = document.getElementById("index").value
    ListSubject[index]={
        name: document.getElementById("name").value,
    }
    localStorage.setItem("List-subject", JSON.stringify(ListSubject))

    document.getElementById("save").style.display = "inline-block"
    document.getElementById("update").style.display = "none"

    render()
    resetInput()
}   

function deleteSubject(index)
{
    let ListSubject = localStorage.getItem("List-subject") ? JSON.parse(localStorage.getItem("List-subject")) : []
    if (confirm("Bạn có chắc chắn muốn xóa môn học không?"))
    {
        ListSubject.splice(index, 1)
    }
    
    localStorage.setItem("List-subject", JSON.stringify(ListSubject))
    render()
}
```
**function resetInput()**
- document.getElementById() trả về phần tử của id được chỉ định.

**function validateInput()**
- function validateInput() kiểm tra chuỗi nhập vào thông qua <input id="name" type="text" class="form-input"> có phải chuỗi rỗng hay không. 
- .querySelector là một phương thức của Document Object, có tác dụng lấy một element trong DOM thoả mãn quy tắc CSS selectors chỉ định.
- .querySelectorAll là một phương thức của Document Object, có tác dụng lấy toàn bộ các element trong DOM thoả mãn quy tắc CSS selectors chỉ định.

**function addNew()**
- arrErrorElement.push thêm phần tử mới vào cuối mảng arrErrorElement, hàm trả về chiều dài của mảng mới.
- localStorage: lưu trữ dữ liệu vô thời hạn, dữ liệu sẽ không bị xóa khi trình duyệt đóng lại.
- localStorage.setItem("List-subject", JSON.stringify(ListSubject)): lưu mảng vào localStorage và mã hóa mảng: JSON.stringify.
- let ListSubject = localStorage.getItem("List-subject") ? JSON.parse(localStorage.getItem("List-subject")) : []: Kiểm tra trong localStorage đã có List-subject hay chưa. Nếu có thì lấy dữ liệu, khi lấy dữ liệu cần giải mã: JSON.parse. Nếu chưa có thì cho dữ liệu thành mảng rỗng.

**function render()**
- .map của mảng tạo ra một mảng mới chứa kết quả của việc gọi một hàm được cung cấp trên mọi phần tử trong mảng gọi.
- subject +=: nối dữ liệu
- innerHTML trong JavaScript là một thuộc tính của Element Object, có tác dụng lấy các câu lệnh HTML chứa trong một Element chỉ định.

**function editSubject(index)**
- document.getElementById("name").value = ListSubject[index].name: truyền dữ liệu đã nhập vào form.
- document.getElementById("save").style.display = "inline-block"; document.getElementById("update").style.display = "none": Ẩn các nút

**function changeSubject()**
- let index = document.getElementById("index").value: Xác định id trong form
- ListSubject[index]={name: document.getElementById("name").value,}: cập nhật dữ liệu.
- localStorage.setItem("List-subject", JSON.stringify(ListSubject)): đẩy lại dữ liệu vào localStorage.

**function deleteSubject(index)**
- .splice sẽ thay đổi các phần tử trong mảng bằng cách xóa bỏ hoặc thay thế các phần tử hiện có, hoặc thêm phần tử mới vào vị trí xác định.

## Kết quả
![](https://hackmd.io/_uploads/HJ5HELe-6.png)

![](https://hackmd.io/_uploads/SJP3EUeW6.png)

![](https://hackmd.io/_uploads/r1VT4Ulb6.png)



# **LẬP TRÌNH PHP**
Lập trình website theo đề bài: website có chức năng thêm, đọc, sửa, xóa (CRUD) các môn học bằng PHP.

## database subjects.sql
```
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";

CREATE TABLE `subjects` (
  `subject_id` int(11) NOT NULL,
  `subject_name` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

INSERT INTO `subjects` (`subject_id`, `subject_name`) VALUES

ALTER TABLE `subjects`
  ADD PRIMARY KEY (`subject_id`);

ALTER TABLE `subjects`
  MODIFY `subject_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=1;
COMMIT;

ALTER TABLE `subjects` AUTO_INCREMENT=1;
```

Tạo database subjects.sql trên phpmyadmin sau đó xuất database.
![](https://hackmd.io/_uploads/SyfQFxWZa.png)


## file connect.php
```
<?php
    try {
        $conn = new PDO("mysql:host=localhost; dbname=crudphp; charset=utf8", "root", "");
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    } catch (PDOException $e) {
        echo "Dữ liệu lỗi!". $e->getMessage();
    }
?>
```
- PDO (PHP Data Object) là các API có sẵn của PHP cho phép người lập trình có thể kết nối để làm việc với cơ sở dữ liệu.
- host=localhost: máy chủ
- dbname=crudphp: cơ sở dữ liệu
- "root": user 
- "": password
- try{}catch: xử lí ngoại lệ

## file read.php
```
<?php
    require_once "connect.php";

    // Câu lệnh SQL Select
    $sql = "SELECT subject_id, subject_name FROM subjects s";

    // Chuẩn bị
    $stmt = $conn->prepare($sql);
    // Thực thi
    $stmt->execute();
    // Lấy dữ liệu
    $subjects = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>DANH SÁCH MÔN HỌC</title>
</head>
<body>
    <table border="1">
        <tr>
            <th>ID</th>
            <th>TÊN MÔN HỌC</th>
            <th><a href="create.php">Thêm môn học</a></th>
        </tr>

        <?php foreach($subjects as $s): ?>
            <tr>
                <td><?= $s['subject_id']?></td>
                <td><?= $s['subject_name']?></td>

                <td><a href="update.php?subject_id=<?=$s['subject_id']?>">Sửa tên môn học</a></td>
                <td><a onclick="return confirm('Bạn có chắc chắn muốn xóa không?')" href="delete.php?subject_id=<?=$s['subject_id']?>">Xóa môn học</a></td>
            </tr>
        <?php endforeach ?>
    <table>
</body>
</html>
```
- require_once trong PHP là một hàm dùng để nạp một file PHP vào trong script hiện tại. Nó khác với hàm require chính là nó chỉ nạp file đó một lần duy nhất, nếu file đó đã được nạp trước đó thì nó sẽ không nạp lại.

## file create.php
```
<?php
    require_once "connect.php";

    if ($_SERVER['REQUEST_METHOD'] == "POST")
    {
        $subject_name = $_POST['subject_name'];

        // SQL INSERT
        $sql = "INSERT INTO subjects(subject_id, subject_name) VALUES
        ('', '$subject_name')";

        $stmt = $conn->prepare($sql);
        $stmt->execute();
        setcookie("message", "Thêm dữ liệu thành công!", time()+1);
        header("location: read.php");
        die;
    }

    // Câu lệnh SQL Select
    $sql = "SELECT subject_id, subject_name FROM subjects s";

    // Chuẩn bị
    $stmt = $conn->prepare($sql);
    // Thực thi
    $stmt->execute();
    // Lấy dữ liệu
    $subjects = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Thêm môn học</title>
</head>
<body>
    <form action="" method="POST" enctype="multipart/form-data">
        Tên môn học: <input type="text" name="subject_name" id="">
        <br><br>
        <button type="submit">Thêm</button>
        <a href="read.php">Danh sách</a>
    </form>
</body>
</html>
```
- Phương thức GET là phương thức gửi dữ liệu thông qua đường dẫn URL nằm trên thanh địa chỉ của Browser. Server sẽ nhận đường dẫn đó và phân tích trả về kết quả. Server sẽ phân tích tất cả những thông tin đằng sau dấu hỏi (?) chính là phần dữ liệu mà Client gửi lên.
- Phương thức POST có tính bảo mật hơn vì dữ liệu gửi phải thông qua một form HTML nên nó bị ẩn, nghĩa là chúng ta không thể thấy các giá trị đó được. POST sẽ gửi dữ liệu qua một cái form HTML và các giá trị sẽ được định nghĩa trong các input gồm các kiểu (textbox, radio, checkbox, password, textarea, hidden) và được nhận dang thông qua tên (name) của các input đó.
- subject_id sử dụng phương thức GET, subject_name sử dụng phương thức POST.
- Câu lệnh INSERT INTO được sử dụng để chèn bản ghi mới vào một bảng.
- Câu lệnh SELECT được sử dụng để chọn dữ liệu từ database.

## file update.php
```
<?php
    require_once "connect.php";

    if ($_SERVER['REQUEST_METHOD'] == "POST")
    {
        $subject_name = $_POST['subject_name'];

        $subject_id = $_GET['subject_id'];

        // SQL UPDATE
        $sql = "UPDATE subjects SET subject_name='$subject_name' WHERE subject_id=$subject_id";

        $stmt = $conn->prepare($sql);
        $stmt->execute();
        header("location: read.php");
        die;
    }

    // Câu lệnh SQL Select
    $sql = "SELECT subject_id, subject_name FROM subjects s";

    // Chuẩn bị
    $stmt = $conn->prepare($sql);
    // Thực thi
    $stmt->execute();
    // Lấy dữ liệu
    $subjects = $stmt->fetchAll(PDO::FETCH_ASSOC);

    // Lấy subject_id trên thanh URL
    $subject_id = $_GET['subject_id'];
    // Câu lệnh SQL với điều kiện subject_id
    $sql = "SELECT * FROM subjects WHERE subject_id=$subject_id";
    $stmt = $conn->prepare($sql);
    $stmt->execute();
    $subjects = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Cập nhật tên môn học</title>
</head>
<body>
    <form action="" method="POST" enctype="multipart/form-data">
        <input type="hidden" name="subject_id" value="<?= $subjects[$subject_id]?>">
        Tiêu đề: <input type="text" name="subject_name" id="">
        <br><br>
        <button type="submit">Cập nhật</button>
        <a href="read.php">Danh sách</a>
    </form>
</body>
</html>
```
- Câu lệnh UPDATE được sử dụng để sửa đổi các bản ghi hiện có trong một bảng.

## file delete.php
```
<?php
    require_once "connect.php";

    // Lấy subject_id 
    $subject_id = $_GET['subject_id'];
    // SQL delete
    $sql = "DELETE FROM subjects WHERE subject_id=$subject_id";
    $stmt = $conn->prepare($sql);
    $stmt->execute();

    header("location: read.php");
    die;
?>
```
- Câu lệnh DELETE được sử dụng để xóa các bản ghi hiện có trong một bảng.


## Kết quả
![](https://hackmd.io/_uploads/H1Q1tl-b6.png)

![](https://hackmd.io/_uploads/Bka1FeW-a.png)

![](https://hackmd.io/_uploads/HJLxFxbZa.png)
