Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8839

node.jsとjQueryを使ってユーザー新規登録モーダルとログインモーダルを作ってみた

$
0
0

画面遷移をせずにユーザー新規登録機能を作ってみました。
そこまで大した出来ではないです。
(実は理想としていたものより少々乖離しています。)

node.jsやjQueryの導入はこちらでは省いています。
また、新規登録、ログインモーダル以外の要素もありません。ご了承ください。

node.jsのバージョンは v14.15.4です。
また、MySQLを使用しています。

1.必要なものをインストール

ターミナル
$ npm install express  //expressをインストールします
$ npm install mysql  //mysqlと接続できます
$ npm install express-session   //登録機能です
$ npm install bcrypt  //パスワードをハッシュ化してくれる機能です

これでインストールは以上です。

今回、ユーザー新規登録には、
username , email , password
の情報が必須となる設定にしています。

2.ルーティングのコードを書いていく

ディレクトリ構造は以下のようになっております
(node_modulesなどは省略しています。)

registation_app/
├ public/
│  ├ css/
│  │  └style.css/
│  ├ script.js/
│  └ validate.js/
├ views/
│  ├ log_in.ejs/
│  ├ sign_up.ejs/
│  ├ top.ejs/
│  └ uniq_error.ejs/
└ app.js/

app.js
// インストールしたものを適用させますconstexpress=require('express');constmysql=require('mysql');constsession=require('express-session');constapp=express();constbcrypt=require('bcrypt');app.use(express.static('public'));app.use(express.urlencoded({extended:false}));// DBと接続しますconstconnection=mysql.createConnection({host:'localhost',user:'root',password:'パスワードを入力',database:'DB名を入力'});// トップ画面のルーティングapp.get('/',(req,res)=>{res.render('top.ejs');});// 重複するメールアドレスがある場合の画面遷移app.get('/uniq_error',(req,res)=>{res.render('uniq_error.ejs');});// 新規登録のルーティングapp.post('/sign_up',(req,res,next)=>{constemail=req.body.email;connection.query('SELECT * FROM users WHERE email = ?',[email],(error,results)=>{if(results.length>0){res.render('uniq_error.ejs');}else{next();}});},(req,res)=>{bcrypt.hash(password,10,(error,hash)=>{connection.query('INSERT INTO users (username, email, password) VALUES (?, ?, ?)',[username,email,hash],(error,results)=>{req.session.userId=results.insertId;req.session.username=username;res.redirect('/');});});});// ログインのルーティングapp.post('/log_in',(req,res)=>{constemail=req.body.email;connection.query('SELECT * FROM users WHERE email = ?',[email],(error,results)=>{if(results.length>0){constplain=req.body.password;consthash=results[0].password;bcrypt.compare(plain,hash,(error,isEqual)=>{if(isEqual){req.session.userId=results[0].id;req.session.username=results[0].username;res.redirect('/');}else{res.redirect('/');}});}else{res.redirect('/');}});});// ログアウトのルーティングapp.get('/log_out',(req,res)=>{req.session.destroy(error=>{res.redirect('/');});});// ローカルホスト3000に接続app.listen(3000);});

3.トップ画面などのコーディング

top.ejs
<!DOCTYPE html><html><head><metacharset="utf-8"><title>registration_APP</title><linkrel="stylesheet"href="/css/style.css"><linkrel="stylesheet"href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css"><script src="https://code.jquery.com/jquery-3.5.1.min.js"></script><script type="text/javascript"src="script.js"></script><script type="text/javascript"src="validate.js"></script></head><body><header><divclass="header-wrapper"><ahref="/"class="header-logo-left">registration_APP</a><%if(locals.isLoggedIn){%><aclass="header-logo-right"href="/log_out">ログアウト</a><%}else{%><div><aclass="header-logo-right login-show">ログイン</a><aclass="header-logo-right signup-show">新規登録</a><%}%></div></div></header><%-include('sign_up');%><%-include('log_in');%></body></html>

<%- include('sign_up'); %>で新規登録モーダル
<%- include('log_in'); %>でログインモーダルを呼び出します。

ある特定のページでのみモーダルを出現させるのであればこの記述をする必要はありませんが、
複数のページでモーダルを出したい場合、このようにすると使いまわせるので便利です。

sign_up.ejs
//新規登録モーダル

<divclass="signup-modal-wrapper"id="signup-modal"><divclass="modal"><divid="signup-close-modal"><iclass="fa fa-2x fa-times"></i></div><divid="signup-form"><h2>新規登録</h2><formaction="/sign_up"method="post"id="sign_up-form"><pclass="error-message"id="sign_up-username-error-message"></p><inputclass="form-control"type="text"placeholder="ユーザー名"name="username"id="sign_up-username"><pclass="error-message"id="sign_up-email-error-message"></p><inputclass="form-control"type="text"placeholder="メールアドレス"name="email"id="sign_up-email"><pclass="error-message"id="sign_up-password-error-message"></p><inputclass="form-control"type="password"placeholder="パスワード"name="password"id="sign_up-password"><inputid="submit-btn"type="submit"value="登録する"></form></div></div></div>
log_in.ejs
//ログインモーダル

<divclass="login-modal-wrapper"id="login-modal"><divclass="modal"><divid="login-close-modal"><iclass="fa fa-2x fa-times"></i></div><divid="login-form"><h2>ログイン</h2><formaction="/log_in"method="post"><inputclass="form-control"type="text"placeholder="メールアドレス"name="email"><inputclass="form-control"type="password"placeholder="パスワード"name="password"><inputid="login-btn"type="submit"value="ログインする"></form></div></div></div>

これでトップ画面で二種類のモーダルをだせるようになりました。
(この段階では二種類のモーダルは現れた状態になっています。)
この後CSSを使ってモーダルを隠し、jQueryで表示させるアクションを作成します。

4.CSSをコーディング

CSSは全て書くととても長くなるので、必要最低限のところだけ
モーダルの大きさや文字の大きさ、背景色などはお好みで。

style.css
/* ヘッダーの『新規登録』『ログイン』部分 */.header-logo-right{display:inline;}.header-logo-right:hover{cursor:pointer;}/* モーダル部分 */.signup-modal-wrapper,.login-modal-wrapper{position:fixed;top:0;right:0;bottom:0;left:0;z-index:100;display:none;}.modal{position:absolute;top:20%;left:34%;background-color:#e6ecf0;padding:20px040px;border-radius:10px;width:450px;height:auto;text-align:center;}.fa-times{position:absolute;top:12px;right:12px;color:rgba(128,128,128,0.46);cursor:pointer;}#signup-form,#login-form{width:100%;}

これで新規登録、ログインボタンにカーソルを合わせるとポインタが変わります
さらにモーダル部分は隠れました。
それではjQueryを使ってモーダルが現れるように処理しましょう。

5.Jqueryをコーディング

script.js
$(function(){$('.signup-show').click(function(){$('#signup-modal').fadeIn();});$('#signup-close-modal').click(function(){$('#signup-modal').fadeOut();});});$(function(){$('.login-show').click(function(){$('#login-modal').fadeIn();});$('#login-close-modal').click(function(){$('#login-modal').fadeOut();});});

これで、『新規登録』を押すと『新規登録モーダル』が
『ログイン』を押すと『ログインモーダル』が出るようになりました。

これで、新規登録並びにログインモーダルが完成です。

・・・と言いたい所さんですが、このままだと空白でも登録ができてしまいます。
と言うわけでバリデーションをかけていきましょう

6.バリデーションをかける

今回はjQuery側でバリデーションチェックをします。
挙動としては、入力に問題がある場合、送信はできず問題箇所にエラー文が出るようにします。

validate.js
$(function(){$('#sign_up-form').submit(function(){varusernameValue=$('#sign_up-username').val();varemailValue=$('#sign_up-email').val();varpasswordValue=$('#sign_up-password').val();varerrorCount=0;if(usernameValue===""){$('#sign_up-username-error-message').text('ニックネームを入力してください');errorCount+=1;}else{$('#sign_up-username-error-message').text('');}if(emailValue===""){$('#sign_up-email-error-message').text('メールアドレスを入力してください');errorCount+=1;}elseif(!emailValue.match(/^[a-zA-Z0-9_.+-]+@([a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]*\.)+[a-zA-Z]{2,}$/)){$('#sign_up-email-error-message').text('メールアドレスが正しくありません');errorCount+=1;}else{$('#sign_up-email-error-message').text('');}if(passwordValue===""){$('#sign_up-password-error-message').text('パスワードを入力してください');errorCount+=1;}elseif(!passwordValue.match(/^(?=.*[a-zA-Z])(?=.*[0-9])[0-9a-zA-Z]{6,}$/)){$('#sign_up-password-error-message').text('パスワードは半角英数字6文字以上が必要です');errorCount+=1;}else{$('#sign_up-password-error-message').text('');}if(errorCount!==0){returnfalse;}});});

これでバリデーションチェックができます。
解説としてはerrorCountを0と最初に定義し、問題箇所1つにつきerrorCountが1上昇していきます。
そして最後、errorCountが0ではない場合送信できないように設定してあります。
そして全てのチェックが通ればerrorCountは0なので送信し、ユーザー登録できる。
と言う仕掛けになっております。

これにて完成です。
と思ったら間違えです。
このままだと同じメールアドレスが登録できてしまいます。

ここから先が私の作りたかったモーダルとの理想と実力の無さが出た場所でした。

7.実現したかった内容

ここで同じアドレスが登録されている場合にもerrorCountを1上昇させる処理をしたかったのですが、
ajax通信が何をやってもうまくいきませんでした。
jQuery単体では厳しいようで、PHPが必要なようです。
(jQueryだけでどうにかならないか色々勉強中です。)

仕方ないので、node.js側で同じメールアドレスがある場合は弾き、アラートを出す妥協案にしましたが、これまた失敗。
理由はnode.jsではalertメソッドが使えないようです。

8.苦し紛れに出した自分なりの答え

アラートが出せずにしばらく考え、出した結論が
『既に登録されているメールアドレスがあるため登録できませんでした』

と書かれたページへ遷移することでした。
コードで言うと、最初のapp.jsに既に記述してありますが、再び記述すると

javascript;app.js
app.post('/sign_up',(req,res,next)=>{constemail=req.body.email;connection.query('SELECT * FROM users WHERE email = ?',[email],(error,results)=>{if(results.length>0){res.render('uniq_error.ejs');}else{next();}});

こちらの部分になります。
これで重複するメールアドレスの場合はuniq_error.ejsに遷移します。

ちなみにuniq_error.ejsには
『既に登録されているメールアドレスがあるため登録できませんでした』
の文字しかありません。

9.終わりに

バリデーションチェックまでは苦戦しながらも進められたのですが、メールアドレスの重複チェックで躓き、数十時間もがき苦しみました。

まだまだ理解が足りない証拠ですね。とても悔しいです。
PHPの知識もそのうち入れたいと思います。


Viewing all articles
Browse latest Browse all 8839

Trending Articles