簡易掲示板を作りたい、node.js+expressで ⑥/nodebbs/msgで更新する

スポンサーリンク
スポンサーリンク

更新

更新機能をつけたい。どういう感じがいいんだろうなーと考えて、編集ボタンを押すと投稿された文章が編集できるように変わって、更新ボタンを押すとそのまま更新されるのがかっこよさめじゃないかと思った。そういう感じにできるように頑張る。

スポンサーリンク

ボタンを付ける

<p id="${row['id']}">${row['contents']['msg']}</p>
<p><button type="button" id="edit-${row['id']}" onclick="editbtn()">編集</button>
名前: ${row['contents']['name']} 日時: ${row['contents']['dt']}
<button type="button" id="del-${row['id']}" onclick="delbtn()">削除</button></p>
<hr>

表示のとこに新たにボタンを作った。後々のためにてきとーにidもくっつけておく。これを押すとまずは編集できるようにしたい。

スポンサーリンク

ボタンを押すと編集できるようにする

function editbtn() {
            let id = event.target.id.slice(5)
            let p = document.getElementById(id)
            let msg = p.innerText
            let textarea = document.createElement('textarea')
            textarea.value = msg
            textarea.id = id
            p.replaceWith(textarea)

            let btn = document.getElementById('edit-' + id)
            btn.innerText = '更新'
            btn.setAttribute('onclick', 'update()');
        }

冗長かなぁ。でもこうしか思いつかん。idで<p>タグの内容を色々取得して、新たに<textarea>の要素を作りreplaceWithで置き換えた。

Element: replaceWith() メソッド - Web API | MDN
Element.replaceWith() メソッドは、この Element を親の子リストの中で一連の Node オブジェクトまたは文字列に置換します。文字列は Text ノードと等価なノードとして挿入されます。

そんでボタンの方は、更新ボタンになるようにテキストとonclickの内容を変えている。

Element: setAttribute() メソッド - Web API | MDN
指定された要素の属性の値を設定します。属性が既に存在する場合は値が更新され、そうでない場合は指定された名前と値で新しい属性が追加されます。
スポンサーリンク

ボタンを押すと更新処理する

function update() {
            let id = event.target.id.slice(5)
            let textarea = document.getElementById(id)
            let msg = textarea.value
            let data = {
                'msg': msg
            }
            fetch('https://dalomo.net/nodebbs/msg/' + id, {
                method: 'PUT',
                body: JSON.stringify(data),
                headers: {
                    'Content-Type': 'application/json'
                }
            })
                .then(res => {
                    let p = document.createElement('p')
                    p.id = id
                    p.innerText = msg
                    textarea.replaceWith(p)
                })
        }

これもIntelliSenseさんが怒涛の勢いで作ってくれた…。

testareaに入力された値をオブジェクトにして、fetchでPUTメソッドを使い、bodyに更新内容をstringifyして送信した。headersはまぁ必要なんだろうこれ。こことか読むとこうすることによってサーバー側で受け取りやすくなってるのかな。で、レスポンス返ってきたら、textareaからpタグに戻して終わり。これはクライアントサイドなので、あとはサーバーサイドを作る。

スポンサーリンク

サーバー側のデータを更新する

app.put('/nodebbs/msg/:id', (req, res) => {
  const id = req.params.id
  const obj = JSON.parse('[' + fs.readFileSync('log.json', 'utf8') + ']')
  const newObj = obj.map(item => {
    if (item.id == id) {
      item.contents.msg = req.body['msg']
      item.contents.dt = (new Date()).toJSON()
    }
    return item
  })
  fs.writeFileSync('log.json', JSON.stringify(newObj).slice(1).slice(0, -1), 'utf8')
  res.end()
})

これも(ry マジですごいよね。考えることがほぼないよ。

まぁログを読み込んで、obj.mapでオブジェクトの要素をなめて、idが一致したらその内容を書き換える。ついでに日付も変わる。このmap関数っていうのがすごい便利なのね。for文とかでやるところだと思うんだけどIntelliSenseさん様々だわ。

Array.prototype.map() - JavaScript | MDN
map() は Array インスタンスのメソッドで、与えられた関数を配列のすべての要素に対して呼び出し、その結果からなる新しい配列を生成します。

あとは編集後のデータをlog.jsonに書き戻すだけ。すごーい、あっという間にできちゃった。

nodebbs - dalomo

とりあえず、基本的な機能を持つ掲示板を作れた。セキュリティ等加味してないのでちょっとアレですが嬉しいねぇ。

コメント

タイトルとURLをコピーしました