---
# System prepended metadata

title: Web Programming Product Price

---

# Web Programming Product Price

:::spoiler HTML
```html
<!DOCTYPE html>
<html>
<head>
    <title>Product Price Change Inquiry</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="stylesheets/style.css">
</head>
<body>
    <h1>Product Price Change Inquiry</h1>
    <h2>Enter the price of the product</h2>
    <form action="/api/submit" method="POST" id="inputForm">
        <label for="date">Date:</label>
        <input required type="date" id="date" name="date">
        <br><br>
        <label for="product">&nbsp&nbsp&nbspName:</label>
        <input required type="text" id="product" name="product">
        <br><br>
        <label for="price">&nbsp&nbsp&nbsp&nbspPrice:</label>
        <input required type="number" id="price" name="price">
        <br><br>
        <input type="submit" value="Submit">
    </form>
    
    <h2>Search</h2>
    <form action="/api/search" method="POST" id="searchForm">
        <label for="search">Keyword:</label>
        <input type="text" id="keyword" name="keyword">
        <input type="submit" value="Search">
    </form>
    
    <h3>Product Price Change</h3>
    <table id="priceTable">
        
    </table>
    <script src="javascripts/script.js"></script>
</body>
</html>
```
:::

:::spoiler CSS
```css
body {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  margin: 0;
  padding: 0;
  font-family: Arial, sans-serif;
}

h1,
h2,
h3 {
  margin-top: 20px;
  margin-bottom: 10px;
}

form {
  margin-bottom: 20px;
}

input[type="submit"] {
  margin-top: 10px;
}

#priceTable {
  width: 80%;
  margin: 0 auto;
  border-collapse: collapse;
}

#priceTable th,
#priceTable td {
  padding: 8px;
  border: 1px solid black;
}
```
:::

Use JS to render the table
:::spoiler JavaScript
```javascript
document.getElementById("inputForm").addEventListener("submit", async function (event) {
    event.preventDefault();

    const formData = new FormData(event.target);
    const date = formData.get('date');
    const product = formData.get('product');
    const price = formData.get('price');

    console.log(date, product, price)
    const res = await fetch('http://localhost:3001/api/submit', { method: 'POST', body: JSON.stringify({ date, product, price }), headers: { 'Content-Type': 'application/json' } });
    // const data = await res.json()

    // var newRow = document.createElement("tr");
    // newRow.innerHTML = "<td>" + date + "</td><td>" + product + "</td><td>" + price + "</td>";

    // var table = document.getElementById("priceTable");
    // table.appendChild(newRow);

    document.getElementById("date").value = "";
    document.getElementById("product").value = "";
    document.getElementById("price").value = "";
    alert("Submit successfully!");
});

document.getElementById("searchForm").addEventListener("submit", async function (event) {
    event.preventDefault();

    const formData = new FormData(event.target);
    const searchKeyword = formData.get('keyword');

    const res = await fetch('http://localhost:3001/api/search', { method: 'POST', body: JSON.stringify({ keyword: searchKeyword }), headers: { 'Content-Type': 'application/json' } });
    
    const data = await res.json()

    var table = document.getElementById("priceTable");
    table.innerHTML = "<tr><th>日期</th><th>品項</th><th>價格</th></tr>";

    for (var i = 0; i < data.length; i++) {
        var newRow = document.createElement("tr");
        newRow.innerHTML = "<td>" + data[i].date + "</td><td>" + data[i].product + "</td><td>" + data[i].price + "</td>";
        table.appendChild(newRow);
    }
    document.getElementById("keyword").value = "";
});
```
:::

:::spoiler API
```javascript
const express = require('express');
const app = express.Router();
const bodyParser = require('body-parser');
const sqlite = require('sqlite3').verbose();

db = new sqlite.Database("database/database.db", sqlite.OPEN_READWRITE, (err) => {
    if (err) {
        console.error(err.message);
    }
    console.log('Connected to the database.');
});

sql = `CREATE TABLE IF NOT EXISTS items (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    date TEXT,
    product TEXT,
    price REAL
)`

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

app.use("/public", express.static(__dirname + '/public'));

app.get("/", (req, res) => {
    res.sendFile(__dirname + "/index.html");
});

app.post('/submit', (req, res) => {
    const date = req.body.date;
    const product = req.body.product;
    const price = req.body.price;

    db.run('INSERT INTO items (date, product, price) VALUES (?, ?, ?)', [date, product, price], (err) => {
        if (err) {
            console.error(err);
            return res.status(500).send('Internal Server Error');
        }
    });
    res.redirect('/');
    return res.status(200);
});

app.post('/search', (req, res) => {
    const keyword = req.body.keyword;
    console.log(keyword);
    db.all('SELECT * FROM items WHERE product LIKE ?', ['%' + keyword + '%'], (err, rows) => {
        if (err) {
            console.error(err);
            res.status(500).send('Internal Server Error');
        } else {
            res.send(rows);
        }
    });
});

module.exports = app;
```
:::