前面把前端功能做好以後,接下來要把狀態(JSON)儲存到資料庫
從 UI 拿出資料
$('.btn-save').click(() => {
let todos = [];
$('.todo').each((i, element) => {
const input = $(element).find('.check-todo');
const lable = $(element).find('.todo__content')
todos.push({
id: input.attr('id'.replace('todo-', '')),
content: lable.text(),
isDone: $(element).hasClass('checked')
})
})
console.log(JSON.stringify(todos));
})
PHP 的 API : 需要一個簡單的 API 來儲存和拿資料
add_todo.php
<?php
require_once 'conn.php';
header('Content-type:application/json;charset=utf-8');
header('Access-Control-Allow-Origin: *');
if (empty($_POST['todo'])) {
$json = array(
"ok" => false,
"message" => "Please input missing fields",
);
$response = json_encode($json);
echo $response;
die();
}
$todo = $_POST['todo'];
$sql = "INSERT INTO todos(todo) VALUES(?)";
$stmt = $conn->prepare($sql);
$stmt->bind_param('s', $todo);
$result = $stmt->execute();
if (!$result) {
$json = array(
"ok" => false,
"message" => $conn->error,
);
$response = json_encode($json);
echo $response;
die();
}
$json = array(
"ok" => true,
"message" => "success",
"id" => $conn->insert_id, // 拿到剛剛新增的 id
);
$response = json_encode($json);
echo $response;
js 那邊的 save 按鈕多加 AJAX
const data = JSON.stringify(todos)
$.ajax({
type: 'POST',
url: 'http://localhost/week12_hw2/add_todo.php',
data: {
todo: data
},
success: function (res) {
const respId = res.id
window.location = 'index.html?id=' + respId
},
error: function () {
alert('Erro QQ')
}
})
測試一下,資料確實寫入
程式裡小註記 :
- 拿到最新 id
insert_id,insert_id 與特定鏈接關聯,它返回的是特定連接上一次執行 INSERT 操作的 id。
之前有使用@@IDENTITY
來抓最新 idSELECT * FROM table WHERE id = @@IDENTITY
,IDENTITY 代表的是一個函數,如果多個處理器的服務器上的多行插入一起使用時,@@IDENTITY
可能會給出錯誤的答案!
如何拿 url 的id
可以搜尋 URLSearchParams,可以幫忙解析 URL,但...它不能解析完整的 URL 。它會刪除 ? 之後的字,所以另外再搜尋 js parse query string
,然後去看 stack overflow 別人提供的一些方法搭配使用。
所以先用找到的方法,把它 console.log 出來
console.log(window.location.search);
得到
再用 URLSearchParams ,就可以拿到 id 了
var searchParams = new URLSearchParams(window.location.search);
const todoId = searchParams.get('id');
如果有 id 那就去拿資料
if (todoId) {
$.getJSON('http://localhost/week12_hw2/get_todo.php?id=' + todoId, function (data) {
todos = JSON.parse(data.data.todo)
render()
});
}
使用 .prop()
取該元素的屬性 checked 的值,取得布林值 true 或 false。
jQuery .attr() vs .prop()
if (todo.isDone) {
$('#todo-' + todo.id).prop('checked', true)
}
get_todo.php
<?php
require_once 'conn.php';
header('Content-type:application/json;charset=utf-8');
header('Access-Control-Allow-Origin: *');
if (empty($_GET['id'])) {
$json = array(
"ok" => false,
"message" => "Please add id in url",
);
$response = json_encode($json);
echo $response;
die();
}
$id = intval($_GET['id']); // 轉成數字
$sql = "SELECT id, todo FROM todos WHERE id = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param('i', $id);
$result = $stmt->execute();
if (!$result) {
$json = array(
"ok" => false,
"message" => $conn->error,
);
$response = json_encode($json);
echo $response;
die();
}
$result = $stmt->get_result();
$row = $result->fetch_assoc();
$json = array(
"ok" => true,
"data" => array(
"id" => $row["id"],
"todo" => $row["todo"],
),
);
$response = json_encode($json);
echo $response;
新增 todo 的 id 是要最後 todo 的下一個
if (todos.length === 0) return //
id = todos[todos.length - 1].id + 1 //
這樣大致上就完成 Todo list 了