0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Node.jsで簡易なWebシステムの構築②

Posted at

#目的
Node.jsを用いて簡易なWebシステムを構築する。Node.jsで簡易なWebシステムの構築①のアプリの拡張で、今回はデータの登録を可能にする。

#環境条件
Node.jsで簡易なWebシステムの構築①で作業した環境をそのまま利用。

#構築手順

ec2-userでログイン

# rootユーザにスイッチ
sudo su - 

##1.基本的な環境設定

#/opt/nodejsのディレクトリに移動
cd /opt/nodejs

express-generatorを用いてアプリケーションのベースを構築。

#expressのインストール
npm install express --save

npm WARN saveError ENOENT: no such file or directory, open '/opt/nodejs/package.json'
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN enoent ENOENT: no such file or directory, open '/opt/nodejs/package.json'
npm WARN nodejs No description
npm WARN nodejs No repository field.
npm WARN nodejs No README data
npm WARN nodejs No license field.

  • express@4.17.1
    added 50 packages from 37 contributors and audited 50 packages in 2.319s
    found 0 vulnerabilities
#express-generatorのインストール
npm install -g express-generator

npm WARN deprecated mkdirp@0.5.1: Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)
/usr/local/bin/express -> /usr/local/lib/node_modules/express-generator/bin/express-cli.js

  • express-generator@4.16.1
    added 10 packages from 13 contributors in 0.715s
#myapp2という名前でアプリケーションのベースを構築
express -e myapp2

warning: option --ejs' has been renamed to --view=ejs'

create : myapp2/
create : myapp2/public/
create : myapp2/public/javascripts/
create : myapp2/public/images/
create : myapp2/public/stylesheets/
create : myapp2/public/stylesheets/style.css
create : myapp2/routes/
create : myapp2/routes/index.js
create : myapp2/routes/users.js
create : myapp2/views/
create : myapp2/views/error.ejs
create : myapp2/views/index.ejs
create : myapp2/app.js
create : myapp2/package.json
create : myapp2/bin/
create : myapp2/bin/www

change directory:
$ cd myapp2

install dependencies:
$ npm install

run the app:
$ DEBUG=myapp2:* npm start

#myapp2ディレクトリに移動
cd myapp2/
#npmパッケージのインストール
npm install

npm notice created a lockfile as package-lock.json. You should commit this file.
added 54 packages from 38 contributors and audited 55 packages in 2.187s
found 0 vulnerabilities

#mysql関連ライブラリとexpress-validatorのインストール
npm install --save mysql express-validator

##2.アプリケーションの開発
今回のアプリケーションは、http://ホスト名:3000にアクセスすると[Node.jsで簡易なWebシステムの構築①](https://qiita.com/MARTOON/items/3a7a4cbd161d07c0ff20)と同様に商品(果物)リストが表示され、その画面上にボタンを追加し、当該ボタンから商品登録画面に遷移し、登録が完了すると、登録後の情報を元の画面を更新して表示するという仕様とする。遷移先のURLはhttp://ホスト名:3000/insertとする。
express-generatorで生成された各種ファイルに対し、追記や変更、ファイル追加を実施することで構築している。

  • 追記・変更したもの
    • public/stylesheets/style.css
    • routes/index.js
    • views/index.ejs
  • 追加したもの
    • views/insert.ejs

####routes/index.js

// 必要なライブラリの呼び出し
const express = require('express');
const router = express.Router();
const mysql = require('mysql');
const { check, validationResult } = require('express-validator/check');

// mysql接続用の設定定義
const mysql_setting = {
    host: 'localhost',
    user: 'root',
    password: 'password',
    database: 'myappdb'
}

// http://<hostname>:3000にアクセスがきた際のレスポンス
router.get('/', function(req, res, next) {
  // DBコネクションの生成
  const connection = mysql.createConnection(mysql_setting);
  connection.connect();
  // SQLの実行と結果の取得とindex.ejsへの伝達 
  connection.query('select * from myapptbl1', function (err, results, fields) {
        if (err) throw err
        res.render('index', { content: results })
    });
  // DBコネクションの破棄
  connection.end();
});

// http://<hostname>:3000/insertにアクセスがきた際のレスポンス(insert.ejs)
router.get('/insert', function (req, res, next) {
  const data = {
      errorMessage: ''
  }
  res.render('./insert', data);
});

// http://<hostname>:3000/insertへアクセスが来た際のレスポンス
// web画面上で入力された値が空になっていないかを確認し、エラーメッセージを表示
router.post('/insert', [check('name').not().isEmpty().trim().escape().withMessage('名前を入力して下さい'),check('price').not().isEmpty().trim().escape().withMessage('値段を入力して下さい'),], (req, res, next) => {
  const errors = validationResult(req);
  // 値が空の場合
  if (!errors.isEmpty()) {
     const errors_array = errors.array();
     res.render('./insert', {
       errorMessage: errors_array,
     })
  } else {
  // 値が入力されている場合
     // 画面上で入力された値を変数として定義
     const name = req.body.name;
     const price = req.body.price;
     // SQL用に配列の作成と変数の入力
     const post = { 'name': name, 'price': price };
     // DBコネクションの生成
     const connection = mysql.createConnection(mysql_setting);
     connection.connect();
     // プレースホルダを用いてSQLを発行し、データを登録する
     connection.query('INSERT INTO myapptbl1 SET ?', post, function (error, results, fields) {
       if (error) throw error;
       // http://<ホスト名>:3000にリダイレクト(Insert後のデータを出力)
       res.redirect('./');
       console.log('ID:', results.insertId);
     });
     // DBコネクションの破棄 
     connection.end();
  }
})

module.exports = router;

以下、ejsファイルは大したこと書いてないので、細かい説明は割愛

####views/index.ejs

<!DOCTYPE html>
<html>
<head>
  <link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
  <table>
   <thead>
    <tr>
      <th scope="col">id</th>
      <th scope="col">name</th>
      <th scope="col">price</th>
    </tr>
   </thead>
    <% for(let i in content) { %>
    <tr>
      <% let obj = content[i]; %>
      <th>
        <%= obj.id %>
      </th>
      <th>
        <%= obj.name %>
      </th>
      <th>
        <%= obj.price %>
      </th>
    </tr>
    <% } %>
  </table>
  <p class="bottom_space"></p>
  <button class="b1" onclick="location.href='./insert'">商品登録画面</button>
</body>
</html>

####views/insert.ejs

<!DOCTYPE html>
<html>
<head>
    <link rel='stylesheet' href='/stylesheets/style.css' />
</head>
 
<body>
    <p class="p1">商品を登録してください</p>
    <form action="/insert" method="post">
        <input type="text" name="name" value="名前">
        <input type="text" name="price" value="値段">
        <button class="b2">登録</button>
    </form>
 
    <% if(errorMessage) { %>
    <ul>
        <% for (let n in errorMessage) { %>
        <li>
            <%= errorMessage[n].msg %>
        </li>
        <% } %>
    </ul>
    <% } %>
</body>
</html>

最低限の見栄えのために以下追記
(aタグまではデフォルト)

####public/stylesheets/style.css

body {
  padding: 50px;
  font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
}

a {
  color: #00B7FF;
}

table, tr, th {
  border-collapse: collapse;
  border:1px solid;
  font-size: 30px;
}

th {
  width:  400px;
  height:  50px;
}

table thead tr th {
  color: #fff;
  background: #000000;
}

.bottom_space {
  margin-bottom: 1em;
}

.b1 {
  width: 1204px;
  height:  50px;
  font-size: 30px;
}

.b2 {
  width:  400px;
  height:  50px;
  font-size: 30px;
}

.p1 {
  font-size: 50px;
}

input {
  width:  400px;
  height:  50px;
  font-size: 30px;
}

##3.画面イメージ

###http://<ホスト名>:3000

image.png

###http://<ホスト名>:3000/insert

image.png

###値の入力

image.png

###登録後のリダイレクト

image.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?