【JavaScript】正規表現を使ってみたりパスワードを画面上に表示させたりする

こんにちは。
株式会社クラスアクト インフラストラクチャ事業部の大塚です。

前回、JavaScriptの勉強の一環でユーザ/パスワードを入力するフォームでデータが入っていない場合の警告ダイアログを表示する方法を学びました。

https://qiita.com/ohtsuka-shota/items/a5a3fcedc7734879e2bd

これだけでも勉強になったのですが、ダイアログを出さないまでも入力を求めるようにするくらいであればHTMLのrequiredでも出来たりします。
そこでもう少しJavaScriptの利便性を確認するために、入力された文字列が英語かどうかを確認するためのコードの書き方や●●という風に隠されているパスワードをどうやって表示させるのかを勉強してみました。

# 実装した画面
パスワードの目の部分が雑ですが、こんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/f229834c-ab57-5795-081a-ce0b53be35a3.png)

目のアイコンは以下のサイト様を参考にローカルにダウンロードしました。
※ここだけの話ですが、パスワードの入力フォームところによくある目のアイコンのやつっててっきりHTMLのなんかで簡単に実装できるものだと思っていたのですが、アイコンとか準備しないといけないんですね？？

https://begi-tech.com/article/java/chrome-password-appear-eye

このようにユーザ/パスワードどちらかが日本語で入力されていると英字で入力しろとダイアログが表示されるようになります。
また、目の部分を押下するとユーザが入力したパスワードがWeb上で確認できるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/bf97c861-34a7-ecec-481c-70fe86b21bc1.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/6474f17f-a3da-101b-d675-ccf122221500.png)


# コード
## HTML
```test.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>formのテスト</title>
    <link rel="stylesheet" href="style.css">
    <script src="script.js" defer></script>
</head>

<body>
    <form action="" method="post" class="sign-up-group" id="sign-up-form">
        <div id="sign-up-icon">
            <img src="contact_user_add_user_new_user_icon_250756.png">
        </div>
        <h1 id="sign-up-title">Please Sign-up</h1>
        <div class="sign-up-form">
            <input type="text" id="username" autocomplete="on" placeholder="Username" class="sign-up-content">
        </div>
        <div class="sign-up-form">
            <div class="password-container">
                <input type="password" id="password" autocomplete="off" placeholder="Password" class="sign-up-content">
                <img id="show-password-icon" src="C:\Users\ohtsu\Documents\HTML_dev\form-js02\目のアイコン8.jpeg" alt="Show Password" onclick="togglePasswordVisibility()" style="cursor: pointer;"> 
            </div>
        </div>        
        <div id="submit-form">
            <button id="sign-up-button" type="submit">Sign-up</button>
        </div>
    </form>
</body>

</html> 
```
- パスワードの入力フォーム部分を少し変えています。目のアイコンを読み込ませています。個人的にはonclickがimgにも使用できるのが驚きでした。buttonに使えるのはDjangoの方で実装したことがあるのでわかっていたのですが、、、！
    - alt="Show Password"
    画像が読み込まれなかったときに、代替として表示する文字列を記述する。
    - onclick="togglePasswordVisibility()"
    アイコンがクリックされると実行される関数を示す。この関数は今回の場合JavaScriptのファイルに記述されています。HTMLにべた書きも出来ます。
    - style="cursor: pointer;"
    これはこのHTMLをWebブラウザを通して見ている人に対して「これは押せるヤツやで～」ということを教えているものです。これがあるとアイコン上にポインタを持っていくと、人の手が指をさしているようなものに変わります。CSS側で設定をすることも可能なようです。

## CSS
```style.css
#sign-up-icon {
    text-align: center;
}

#sign-up-title{
    text-align: center;
    font-family: serif;
}

.sign-up-group {
    width: fit-content;
    margin: auto;
    padding: 3%;
}

.sign-up-form {
    padding-top: 3%;
    width: fit-content;
    margin:auto;
}

.sign-up-content {
    border-radius: 4px;
    font-family: serif;
}

#submit-form{
    text-align: center;
    padding-top: 5%;
}

#sign-up-button {
    color: white;
    background-color: blue;   
    width: 77%;
    border-radius: 4px;
    font-family: serif;
}

#sign-up-button:hover {
    background-color: midnightblue;
}

.password-container {
    position: relative;
}

#show-password-icon {
    position: absolute;
    right: 10px;
    top: 50%;
    transform: translateY(-50%);
}
```
- position: relative;　position: absolute;
以下のサイトがわかりやすいかなと個人的に思いました。基本的にセットで使用することが多いようです。relativeで基準点を決めてabsoluteでそこからどう動かすか、みたいなことなのだろうなと。。。
今回の場合、親要素がdivのpassword-containerで子要素がimgのshow-password-iconになるということですね。
> 親要素にposition: relative; を適用すると、position: absolute; を適用した子要素を動かす際の基準点が親要素になります。

https://zero-plus.io/media/css-position-absolute/

## JavaScript
```script.js
document.addEventListener('DOMContentLoaded', function () {
    document.getElementById('sign-up-form').addEventListener('submit', function (event) {
        var username = document.getElementById('username').value.trim();
        var password = document.getElementById('password').value.trim();

        if (username === '' || password === '') {
            alert('すべての必須フィールドに入力してください。');
            event.preventDefault(); 
        } else if (!/^[a-zA-Z]+$/.test(username) || !/^[a-zA-Z]+$/.test(password)) {
            alert('全ての項目は英字のみを含む必要があります。');
            event.preventDefault();
        }
    });
});

function togglePasswordVisibility() {
    var passwordInput = document.getElementById('password');

    if (passwordInput.type === 'password') {
        passwordInput.type = 'text';
    } else {
        passwordInput.type = 'password';
    }
}

```
 - \!\/\^\[a-zA-Z\]\+\\$\/.test(username) || \!\/\^\[a-zA-Z\]\+\\$\/.test(password)
JavaScriptにはtestというメソッドがあるらしい。
testの前の"\^\[a-zA-Z\]\+\\$\"が正規表現であり、この正規表現にusernameがマッチするかどうかを確認してtrue/falseをreturnする様子。正規表現の前に"!"があることから意味が逆となり「アルファベットを含まないと…」という状態になります。つまり"usernameとpasswordのいずれかにアルファベットを含まないと、以下のalertを出します"という条件を示します。
 
 > testは正規表現のパターンから呼び出し、引数にチェックする文字列を指定します。

 https://www.sejuku.net/blog/58332

 - var passwordInput = document.getElementById('password');
passwordInputという変数にHTMLでIDが"password"となっているものを格納しています。今回はHTMLの"\<input type="password" id="password" autocomplete="off" placeholder="Password" class="sign-up-content"\>"を示します。
- if (passwordInput.type === 'password') {
passwordInput.type = 'text';
上記で変数passwordInputに格納したHTMLのtypeが"password"だった場合、textに置き換えるということを示します。
つまりボタンを押すとHTMLが以下のように変わるということですね。typeがtextだと、今回の場合ユーザ名を入力するところと同じようにWebブラウザでデフォルトで表示されるようになります。
なるほど、、、こうやって表示させていたのか・・・！
```html
目のアイコン押下前
<input type="password" id="password" autocomplete="off" placeholder="Password" class="sign-up-content">

目のアイコン押下後
<input type="text" id="password" autocomplete="off" placeholder="Password" class="sign-up-content">
```