前面几节显示的列表,看不到事项创建时间,完成时间,数据显示比较少。本节增加表格显示这些结构化数据
{
"itemName": "1111",
"createTime": "2022-11-19 22:06:15",
"completeTime": "2022-11-19 22:06:29",
"todoStatus": "已完成"
}
[
{
"itemName": "1111",
"createTime": "2022-11-19 22:06:15",
"completeTime": "2022-11-19 22:06:29",
"todoStatus": "已完成"
},
{
"itemName": "en1111",
"createTime": "2022-11-19 22:06:20",
"completeTime": "2022-11-19 22:06:33",
"todoStatus": "已完成"
}
]
{
"code": 1,
"data": [
{
"itemName": "1111",
"createTime": "2022-11-19 22:06:15",
"completeTime": "2022-11-19 22:06:29",
"todoStatus": "已完成"
},
{
"itemName": "en1111",
"createTime": "2022-11-19 22:06:20",
"completeTime": "2022-11-19 22:06:33",
"todoStatus": "已完成"
}
],
"msg": "查询成功"
}
<table id="todo_table" cellpadding="0" cellspacing="0" border="1">
<tr id ="todo_header">
<th>待办事项th>
<th>创建时间th>
<th>完成时间th>
<th>是否已完成th>
<th>操作th>
tr>
table>
function initUlData(result) {
if (result.code == '0') {
alert(result.msg);
} else {
if (result.data == null) {
alert('服务器返回数据为空');
return ;
}
var todoHeader = $('#todo_header');
$('#todo_table').empty();
$('#todo_table').append(todoHeader);
result.data.forEach(item => {
// $('#todo_ul').append( $('').html(a));
var tr = $(' ');
tr.append($(' ').html(item.itemName));
tr.append($(' ').html(item.createTime));
tr.append($(' ').html(item.completeTime));
tr.append($(' ').html(item.todoStatus));
var delButton = $('');
if (item.todoStatus = '已完成') {
delButton[0].disabled = true;
} else {
delButton.on('click', function(){
var tdNodes = this.parentNode.childNodes;
if (tdNodes.length > 1) {
complete(tdNodes[0].textContent);
}
});
}
tr.append(delButton);
$('#todo_table').append(tr);
});
focusItemText();
}
}
2.1 创建表格行
var tr = $(' ');
2.2 创建单元格,填充单元格html数据,再添加至行中,最后一个单元格放入按钮
tr.append($(' ').html(item.itemName));
tr.append($(' ').html(item.createTime));
tr.append($(' ').html(item.completeTime));
tr.append($(' ').html(item.todoStatus));
var delButton = $('');
tr.append(delButton);
2.3 如果该待办事项已完成,按钮设置禁用
if (item.todoStatus = '已完成') {
delButton[0].disabled = true;
}
2.4 表格添加行数据
$('#todo_table').append(tr);
待办列表
待办列表
待办事项
创建时间
完成时间
是否已完成
操作
后端返回的数据都在 doQuery 接口中封装的,只需要修改该方法
function doQuery(response) {
db.query('select item_name,create_time,complete_time,' +
'case todo_status when 0 then \'未完成\' when 1 then \'已完成\' end as todo_status from t_todo_list', (err, result) => {
if (err) {
console.log(err);
var data = buildData(CODE_ERROR, [], '查询数据库失败');
sendMsg(response, JSON.stringify(data));
return;
}
var itemList = [];
for (var i in result) {
let item = {
'itemName':'',
'createTime':'',
'completeTime':'',
'todoStatus':''
}
item.itemName = result[i].item_name;
item.createTime = formatDate(result[i].create_time);
item.completeTime = formatDate(result[i].complete_time);
item.todoStatus = result[i].todo_status;
itemList.push(item);
}
var data = buildData(CODE_SUCCESS, itemList, '查询成功');
sendMsg(response, JSON.stringify(data));
});
}
select item_name,create_time,complete_time, case todo_status when 0 then '未完成' when 1 then '已完成' end as todo_status from t_todo_list
let item = {
'itemName':'',
'createTime':'',
'completeTime':'',
'todoStatus':''
}
function formatDate(date) {
if (date == null) {
return "";
}
return silly.format(date, 'YYYY-MM-DD HH:mm:ss');
}
调试窗口 中第一行显示的是未格式化之前的 date
完整的 server.js
const http = require('http');
const fs = require('fs');
const parse = require('url').parse;
const mysql = require('mysql');
const silly = require('silly-datetime');
const db = mysql.createPool({
host: "127.0.0.1",
port: 3306,
user: 'root',
password: 'shootercheng',
database: "test"
});
const hostname = '127.0.0.1';
const port = 3000;
const CODE_ERROR = 0;
const CODE_SUCCESS = 1;
function send404(response) {
response.writeHead(404, {'Content-Type': 'text/plain'});
response.write('Error 404: resource not found.');
response.end();
}
function sendMsg(response, msg) {
response.writeHead(200, {'Content-Type': 'application/json;charset=UTF-8'});
response.write(msg);
response.end();
}
function readFile(response, filePath) {
fs.readFile(filePath, (err, data) => {
if (err) {
return send404(response);
}
var html = data.toString();
// html = html.replace('%', Array.from(todoSet).join('- '));
response.writeHead(200, {'Content-Type': 'text/html'});
response.end(html);
});
}
function findItemData(urlParse) {
if (urlParse.query.length > 0) {
var queryArray = urlParse.query.split('=');
if (queryArray.length >= 2) {
return decodeURI(queryArray[1]);
}
}
return '';
}
function buildData(code, data, msg) {
// 返回数据
let retData = {
'code':'',
'data': [],
'msg':''
}
retData.code = code;
retData.data = data;
retData.msg = msg;
return retData;
}
/**
* 获取当前时间
* @returns
*/
function currentTime() {
return silly.format(new Date(), 'YYYY-MM-DD HH:mm:ss');
}
/**
* 格式日期
* @param {*} date
* @returns
*/
function formatDate(date) {
if (date == null) {
return "";
}
return silly.format(date, 'YYYY-MM-DD HH:mm:ss');
}
/**
* 查询待办数据,并且输出到response
* @param {*} response
*/
function doQuery(response) {
db.query('select item_name,create_time,complete_time,' +
'case todo_status when 0 then \'未完成\' when 1 then \'已完成\' end as todo_status from t_todo_list', (err, result) => {
if (err) {
console.log(err);
var data = buildData(CODE_ERROR, [], '查询数据库失败');
sendMsg(response, JSON.stringify(data));
return;
}
var itemList = [];
for (var i in result) {
let item = {
'itemName':'',
'createTime':'',
'completeTime':'',
'todoStatus':''
}
item.itemName = result[i].item_name;
item.createTime = formatDate(result[i].create_time);
item.completeTime = formatDate(result[i].complete_time);
item.todoStatus = result[i].todo_status;
itemList.push(item);
}
var data = buildData(CODE_SUCCESS, itemList, '查询成功');
sendMsg(response, JSON.stringify(data));
});
}
/**
* 添加待办事项
* @param {*} response
* @param {*} itemData
*/
function doAdd(response, itemData) {
db.query('select count(*) as num from t_todo_list where item_name = ? and todo_status = ?', [itemData,'0'], (err, result) => {
if (err) {
console.log(err);
var data = buildData(CODE_ERROR, [], '查询数据库失败');
sendMsg(response, JSON.stringify(data));
return;
}
if (result[0].num > 0) {
var data = buildData(CODE_ERROR, [], itemData + '-待办事项已存在');
sendMsg(response, JSON.stringify(data));
return;
}
db.query('insert into t_todo_list(item_name, create_time, todo_status) values(?, ?, ?)', [itemData, currentTime(), '0'], (err, result) => {
if (err) {
console.log(err);
var data = buildData(CODE_ERROR, [], itemData + '-待办事项添加到数据库失败');
sendMsg(response, JSON.stringify(data));
return;
}
doQuery(response);
});
});
}
/**
* 完成待办事项
* @param {*} response
* @param {*} itemData
*/
function doCompelete(response, itemData) {
db.query('select count(*) as num from t_todo_list where item_name = ? and todo_status = ?', [itemData, '0'], (err, result) => {
if (err) {
console.log(err);
var data = buildData(CODE_ERROR, [], '查询数据库失败');
sendMsg(response, JSON.stringify(data));
return;
}
if (result[0].num == 0) {
var data = buildData(CODE_ERROR, [], itemData + '-待办事项不存在');
sendMsg(response, JSON.stringify(data));
return;
}
db.query('update t_todo_list set complete_time = ?, todo_status = ? where item_name = ?', [currentTime(), '1', itemData], (err, result) => {
if (err) {
console.log(err);
var data = buildData(CODE_ERROR, [], itemData + '-更新待办事项失败');
sendMsg(response, JSON.stringify(data));
return;
}
doQuery(response);
});
});
}
const server = http.createServer((request, response) => {
var urlParse = parse(request.url);
var urlPath = urlParse.pathname;
var itemData;
if (urlPath == '/add' || urlPath == '/complete') {
itemData = findItemData(urlParse);
if (itemData.length == 0) {
var data = buildData(CODE_ERROR, [], '输入数据有误');
return sendMsg(response, JSON.stringify(data));
}
}
switch (urlPath) {
case '/':
var filePath = 'public/index.html';
var absPath = './' + filePath;
readFile(response, absPath);
break;
case '/query':
doQuery(response);
break;
case '/add':
doAdd(response, itemData);
break;
case '/complete':
doCompelete(response, itemData);
break;
}
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`)
})
打开浏览器开发者工具,点击source, 点击代码行数加上断点
刷新页面,按F10 可以看到表格一行行绘制
Gitee代码仓库: https://gitee.com/3281328128/todo_list/tree/mysql/