글 수정 시에 저자도 수정할 수 있도록 하기 위해선, 글 생성 시와 유사하게 구현하면 된다.
우선 author table을 불러오는 query를 실행하고, UI를 구성하는 form에도 template 모듈의 authorSelect함수를 통해 저자를 선택하는 콤보박스를 추가한다.
else if(pathname === '/update'){
db.query(`SELECT * FROM topic`, function(error, topics){
if(error) {
throw error;
}
db.query(`SELECT * FROM topic WHERE id=?`,[queryData.id], function(error2, topic){
if(error2){
throw error2;
}
//저자 table 불러오기
db.query('select * from author;', function(error2, authors) {
var list = template.list(topics);
var html = template.HTML(topic[0].title, list,
`
<form action="/update_process" method="post">
<input type="hidden" name="id" value="${topic[0].id}">
<p><input type="text" name="title" placeholder="title" value="${topic[0].title}"></p>
<p>
<textarea name="description" placeholder="description">${topic[0].description}</textarea>
</p>
<p>
${template.authorSelect(authors)}
</p>
<p>
<input type="submit">
</p>
</form>
`,
`<a href="/create">create</a> <a href="/update?id=${topic[0].id}">update</a>`
);
response.writeHead(200);
response.end(html);
});
});
});
하지만 여기서 주의해야할 것은,
글 생성 시와는 다르게 글 수정 시엔 콤보박스에 기존에 설정되어있던 저자가 나타나야 한다는 점이다.
이를 위해서 콤보박스를 생성하는 template 모듈의 authorSelect 함수의 인자를 추가해야 한다.
<template.js>
authorSelect:function(authors, author_id){
var tag = '';
var i = 0;
while(i < authors.length) {
var selected='';
if(author_id === authors[i].id) {
selected = ' selected';
}
tag += `<option value="${authors[i].id}"${selected}>${authors[i].name}</option>`;
i++;
}
return `
<select name="author">
${tag}
</select>
`
}
authorSelect에서 author_id
라는 두번째 인자를 추가한 뒤,
author table에 모든 데이터를 담고 있는 배열인 authors를 순회하는 반복문 내에서,
author_id와 동일한 id를 가지는 배열요소를 찾아내는 조건문을 구현한다.
selected라는 변수에 빈 string을 초기화 해준 뒤,
만약 함수 호출 시 두번째로 전달된 인자값(author_id)가 현재 순회중인 배열 요소의 id와 동일하다면, selected 변수에 ' selected'라는 string이 입력되도록 구현한다.
콤보박스의 옵션 태그들을 축적하는 tag 변수에서, option 태그 내에 selected 변수를 추가하여, 조건문이 참이되는 요소의 경우, option 태그에 selected
라는 속성이 추가되도록 설정한다.
selected 속성 : 콤보박스 옵션들 중 기본으로 선택되도록 설정하는 속성
즉, selected 속성이 추가된 option은 콤보박스에서 가장 처음으로 나타나게 되는 것이다.
따라서, 기존 form에서 authorSelect 함수를 호출할때 authors 배열 뿐만 아니라 두번째 인자로 topic[0].author_id
(현재 수정하고자 선택된 글의 저자id)를 담아서 호출하면, 현재 글의 저자를 콤보박스의 기본값으로 설정할 수 있다.
<최종 html form>
<form action="/update_process" method="post">
<input type="hidden" name="id" value="${topic[0].id}">
<p><input type="text" name="title" placeholder="title" value="${topic[0].title}"></p>
<p>
<textarea name="description" placeholder="description">${topic[0].description}</textarea>
</p>
<p>
${template.authorSelect(authors, topic[0].author_id)}
</p>
<p>
<input type="submit">
</p>
</form>
글 Nodejs의 저자가 duru일 때, 글 수정 UI에서 콤보박스는 duru를 기본값으로 갖고, 해당 페이지의 소스코드에서도 <select>
태그 내의 <option>
태그들 중, duru에 selected
속성이 적용된 것을 확인할 수 있다.
글 수정 페이지에서 작성한 form이 전송되는 웹서버 update_process에서는 저자정보를 처리하기 위해 다음과 같은 변경만 하면 된다.
데이터를 다 모아 post 변수에 파싱하여 입력한 뒤에 실행할 query에서
기존에는 author_id를 임의값 1로 설정하여 실행하였다.
db.query('UPDATE topic SET title=?, description=?, author_id=1 WHERE id=?', [post.title, post.description, post.author, post.id], function(error, result) {}
여기서 author_id값 또한 사용자의 입력에 따라 설정하기 위해 ?
로 대체한 뒤, ?의 대체값을 나열하는 두번째 인자 배열의 세번째 자리에 post.author
를 추가하면 된다.
//update_process 경로의 구현 코드
var body = '';
request.on('data', function(data){
body = body + data;
});
request.on('end', function(){
var post = qs.parse(body);
//DB쿼리 실행
db.query('UPDATE topic SET title=?, description=?, author_id=? WHERE id=?', [post.title, post.description, post.author, post.id], function(error, result) {
response.writeHead(302, {Location: `/?id=${post.id}`});
response.end();
})
});