NodeJs actual combat - to-do list (3) - front-end page filling to-do data

Why fill the pending data at the front end?

The page data in Section 2 is filled in the background, so there is a problem. Every time the to-do list changes, you need to return to the page again, resulting in returning to the entire page every time you update the to-do list

How to populate pending data on the front end?

What you need to know

  1. ajax send http request
  2. Add, delete, modify and check jQuery operation DOM elements

page modification

    • The tag adds an id, which is required for subsequent operations on the DOM
<ul id="todo_ul"></ul>
  1. When the page is initialized, use ajax to send a request to get the pending data of the backend service
        function init() {
    
    
            $.ajax({
    
    
                url: "/query",
                method: 'GET',
                success: function(result) {
    
    
                    initUlData(result);
                }
            });
        }
  1. The server returns the result data, and the front-end page draws and fills the pending data
        function initUlData(result) {
    
    
            if (result.code == '0') {
    
    
                alert(result.msg);
            } else {
    
    
                $('#todo_ul').empty();
                if (result.data == null) {
    
    
                    alert('服务器返回数据为空');
                    return ;
                }
                result.data.forEach(a => {
    
    
                    $('#todo_ul').append( $('<li></li>').html(a));
                });
            }
        }
  1. The init() method is called when the page is initialized
$(function() {
    
    
   init();
}
  1. full index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>待办列表</title>
    <script type="text/javascript" src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
    <script type="text/javascript">
        $(function() {
      
      
            init();
            $("#add").on('click', function(){
      
      
                add();
            });
            $("#complete").on('click', function(){
      
      
                complete();
            });
        });

        
        function init() {
      
      
            $.ajax({
      
      
                url: "/query",
                method: 'GET',
                success: function(result) {
      
      
                    initUlData(result);
                }
            });
        }

        function add() {
      
      
            var item = $("#item_text").val().trim();
            if (item.length == 0) {
      
      
                alert('输入数据不能为空');
            }
            $.ajax({
      
      
                url: "/add",
                method: 'GET',
                data: {
      
      
                    item: item
                },
                success: function(result) {
      
      
                    initUlData(result);
                }
            });
        }

        function complete() {
      
      
            var item = $("#item_text").val().trim();
            if (item.length == 0) {
      
      
                alert('输入数据不能为空');
            }
            $.ajax({
      
      
                url: "/complete",
                method: 'GET',
                data: {
      
      
                    item: item
                },
                success: function(result) {
      
      
                    initUlData(result);
                }
            });
        }

        function initUlData(result) {
      
      
            if (result.code == '0') {
      
      
                alert(result.msg);
            } else {
      
      
                $('#todo_ul').empty();
                if (result.data == null) {
      
      
                    alert('服务器返回数据为空');
                    return ;
                }
                result.data.forEach(a => {
      
      
                    $('#todo_ul').append( $('<li></li>').html(a));
                });
                focusItemText();
            }
        }

        function focusItemText() {
      
      
            $('#item_text').val('');
            $('#item_text').focus();
        }
    </script>
</head>
<body>
    <h1>待办列表</h1>
    <form method="post" >
        <p><input id="item_text" type="text" name="item" /></p>
        <p><input id="add" type="button" value="添加" /></p>
        <p><input id="complete" type="button" value="完成" /></p>
    </form>
    <ul id="todo_ul"></ul>
</body>
</html>

Backend service encapsulates data return

The back-end service uses json data to return to the front-end. The json structure is clear, and it is more convenient for the front-end to parse the json.

server.js modification

  1. Add an object to store the returned data
let retData = {
    
    
	'code':'',
	'data': [],
	'msg':''
}

How to turn an object into a string?
Open the browser developer tool console and try
insert image description here
2. Add the server output json method

function sendMsg(response, msg) {
    
    
	response.writeHead(200, {
    
    'Content-Type': 'application/json;charset=UTF-8'});
    response.write(msg);
    response.end();
}

Note: You need to specify the Content-Type as application/json

  1. Modify the readFile logic, no need to fill in the data, refresh to return to the page
function readFile(response, filePath) {
    
    
	fs.readFile(filePath, (err, data) => {
    
    
		if (err) {
    
    
			return send404(response);
		}
		var html = data.toString();
		response.writeHead(200, {
    
    'Content-Type': 'text/html'});
		response.end(html);
	});
}
  1. Add /query, / execution logic method
const server = http.createServer((request, response) => {
    
    
	var urlParse = parse(request.url);
	var urlPath = urlParse.pathname;
	switch (urlPath) {
    
    
		case '/':
			var filePath = 'public/index.html';
    		var absPath = './' + filePath;
			readFile(response, absPath);
			break;
		case '/query':
			sendMsg();
			break;
		case '/add':
			sendMsg();
			break;
		case '/complete':
			sendMsg();
			break;
	}
	
});

The server is modified to only load the HTML page when reading the home page, and return json data when accessing other addresses

  1. Complete server.js code
const http = require('http');
const fs = require('fs');
const parse = require('url').parse;

const hostname = '127.0.0.1';
const port = 3000;

const CODE_ERROR = 0;
const CODE_SUCCESS = 1;

var todoSet = new Set();

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('</li><li>'));
		response.writeHead(200, {
    
    'Content-Type': 'text/html'});
		response.end(html);
	});
}

function add(itemData) {
    
    
	todoSet.add(itemData);
}

function complete(itemData) {
    
    
	// 判断待办事项是否已添加
	if (!todoSet.has(itemData)) {
    
    
		return itemData + '-待办事项不存在';
	}
	if (todoSet.delete(itemData)) {
    
    
		return true;
	}
	return itemData + '-待办事项删除失败';
}

function findItemData(urlParse) {
    
    
	if (urlParse.query.length > 0) {
    
    
		var queryArray = urlParse.query.split('=');
		if (queryArray.length >= 2) {
    
    
			return queryArray[1];
		}
	}
	return '';
}

function buildData(code, data, msg) {
    
    
    // 返回数据
	let retData = {
    
    
		'code':'',
		'data': [],
		'msg':''
	}
	retData.code = code;
	retData.data = data;
	retData.msg = msg;
	return retData;
}

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':
			var data = buildData(CODE_SUCCESS, Array.from(todoSet), '页面初始化');
			sendMsg(response, JSON.stringify(data));
			break;
		case '/add':
			add(itemData);
			var data = buildData(CODE_SUCCESS, Array.from(todoSet), '添加成功');
			sendMsg(response, JSON.stringify(data));
			break;
		case '/complete':
			var res = complete(itemData)
			if (res == true) {
    
    
				var data = buildData(CODE_SUCCESS, Array.from(todoSet), '待办已完成');
				return sendMsg(response, JSON.stringify(data)); 
			}
			var data = buildData(CODE_ERROR, [], res);
			sendMsg(response, JSON.stringify(data));
			break;
	}
});

server.listen(port, hostname, () => {
    
    
	console.log(`Server running at http://${
      
      hostname}:${
      
      port}/`)
})

renderings

Execute node server.js to start the service

F:\Github\Nodejs\todolist>node server.js
Server running at http://127.0.0.1:3000/

initialization page

insert image description here

Add to-do

  1. add 111
  2. add en111
  3. Added Chinese 111
    insert image description here
    and found a small problem, the Chinese characters are garbled, follow-up processing

Complete to-dos

  1. complete 111
  2. Completion of Chinese 111
    insert image description here

Guess you like

Origin blog.csdn.net/modelmd/article/details/127916265