簡易的な送信フォームをDOM操作してみよう

Javascript

こんにちはkazutoです。今回は送信フォームをJavaScriptを使ってDOM操作をしてみましょう。

事前準備

まずは事前準備を行いましょう。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="style.css">
  <script src="form.js"defer></script>
</head>
<body>
  <h1>SubmitEvent</h1>
  <main>
    <div class="inputBox">
      <form id="SubmitEventForm">
        <label><input type="text"></label>
      </form> 
    </div>
  </main>
</body>
</html>
body{
  background-color: #222222;
  color: white;
  font-family: cursive;
}
main{
  width: 800px;
  height: 500px;
  margin: auto;
  text-align: center;
}
.aqua{
  color: aqua;
}
.greenyellow{
  color: greenyellow;
}
.darkgrey{
  color: darkgrey;
}
.white{
  color: white;
}
.red{
  color: red;
}
p{
  font-size: 30px;
}
h1{
  text-align: center;
  font-size: 50px;
}
.inputBox{
  width: 100%;
  height: 50px;
  margin: 0 auto ;
}
.SubmitEventForm{
  width: 100px;
  height: 500px;
  margin: auto;
  background-color: darkcyan;
}
input[type="text"]{
  width: 250px;
  border-radius: 30px;
  background-color: #111111;
  border: 10px solid black;
  color: white;
  font-size: 20px;
  padding:2px 10px;
  font-family: cursive;
}

button[type="submit"]{
  height: 40px;
  width: 40px;
  border-radius: 30px;
  background-color: #111111;
  border: 10px solid black;
  color: white;
}

今回は、フォームが送信されたとき時にイベントが発火をするsubmitイベントを用いて、実装をしていきます。 

submitイベント

それでは、送信フォームをJavaScriptを用いて実装していきましょう。

  • ノードの取得
  • イベントを登録
  • イベント発火後の処理を実装してみよう。

ノードの取得

まずはノードを取得をしてみましょう。

const SubmitEventForm = document.querySelector("#SubmitEventForm")
const textFiled = document.querySelector('input[type="text"]')
const colors = ["aqua","greenyellow","darkgrey","white","red"]
let index =0
const colors = ["aqua","greenyellow","darkgrey","white","red"]
let index =0

上記の変数は、フォームから送信され、生成するHTML要素に「ランダムに色を変える」という動作を実現するために必要な変数・定数です。

const colors = ["aqua","greenyellow","darkgrey","white","red"]

定数colorsは、addメソッドで追加をするクラス名を管理をしています。

let index

変数indexは、フォームから生成されるテキストに対して番号を持たせるために定義しました。

変数・定数を定義した意図が理解できた所で、ノードを取得できたか、デバックをしてみましょう。

function forLogs(elements){
  elements.forEach(element => {
    console.log(element);
  });
}
forLogs([SubmitEventForm,textFiled])

無事、ノードを取得できたのが確認できたら、次のステップに進みましょう。

イベントを登録

ノードを取得できたら、実際にsubmitイベントを登録をしていきましょう。なお、定数SubmitEventFormにイベントを登録をしていきます。

SubmitEventForm.addEventListener("submit",function(e){
}

では実施にイベントが登録できたか、console.logを用いて確認をしてみましょう。

SubmitEventForm.addEventListener("submit",function(e){
console.log("test")
}

testという文字列が、出力をされているのでイベントが登録されているのが確認できました・・・・

勘が鋭い方は、もうお気づきになっていると思いますが、testという文字列は確かに出力がされています。しかし、出力されているのは一瞬ですよね❓
この謎の現象はHTML要素のデフォルトアクションのためです。デフォルトアクションとは、HTMLであらかじめ定められているものです。

 <form id="SubmitEventForm" action=""> </form> 

通常formタグは、action属性というフォームのデータの送信先を決める必要があります。しかし、今回はデータを送る必要がありません。値を空にした場合や、この属性自体を省略した場合は、自身にデータを送信します。要するにaction属性を設定をしなかった場合は、そのformタグがあるhtmlファイルにデータが送られるという事ですね。

なお、formを使ってデータを送信したい場合などは、

  • Ruby
  • php

などのサーバーサイド言語を用いる必要があります。

以下の理由でsubmitイベントのデバックした際にtestという文字列は一瞬で消えるような挙動になりました。
しかし「簡易的な送信フォームをDOM操作してみよう」では、formタグのデフォルトアクションでは、実装できません。なので「フォームを送信をする」というアクションをキャンセルする必要があります。

下記のソースコードを見てください

SubmitEventForm.addEventListener("submit",function(event){
  event.preventDefault()
  console.log("test");
})

新たにevent.preventDefault()という記述が追加をしました。preventDefaultメソッドとは、イベントをキャンセルをするメソッドです。

submitイベントはフォームが送信された際にイベントが発火をします。しかし、フォームが送信されてしまうと、formタグのデフォルトアクションのため、リロードされてしまい、結果的にデータが全て飛んでしまいます。

したがって、preventDefaultメソッドを用いてイベントをキャンセルをしています。

では実際にpreventDefaultメソッドを追加をした事によってtestという文字列はどのような挙動を取るのかを確認をしてみましょう。下記の画像をご覧ください。

[preventDefaultメソッドを用いていない場合]

[preventDefaultメソッドを追加した場合]

preventDefaultメソッドを追加した場合だと、Enterキーを押した回数分、testという文字列が出力がされているのが確認ができますね。デバックが成功したので次のステップに進みましょう。

イベント発火後の処理を実装してみよう

イベントが登録できた所でイベントが発火後の処理を実装していきましょう。

手順として

  • 入力したvalue値を持ったHTML要素を生成
  • mainタグにHTML要素挿入
  • HTML要素を取得して配列colorsからランダムでクラスを追加をする

という流れになります。

SubmitEventForm.addEventListener("submit",function(event){
  event.preventDefault()
  const p = `<p id = text${index}>${textFiled.value}</p>`
  textFiled.value = ``
  document.querySelector("main").insertAdjacentHTML('beforeend',p)
  document.querySelector(`#text${index}`).classList.add(colors[Math.floor(Math.random()*colors.length)])
  index++;
})
 const p = `<p id = text${index}>${textFiled.value}</p>`

こちらのソースコードは、テンプレートリテラルを用いてHTML要素を生成をし、最終的にmainタグに生成したHTML要素を挿入をします。

text${index}

とする事で、フォームで生成したHTML要素ごとに番号を持たせて、振り分ける事が可能です。実際にデベロッパーツールをのElmentツリーみて、どのような構造になっているか確認をしてみましょう。

indexの部分が番号に置き換わっているのが画像から分かりますね。今回は、変数indexの値によってノードを取得してクラスを追加をしていくので、indexがどのような役割を担っているのかは、把握をしておきましょう。

textFiled.value

textFiledのvalue(値)を取得をしています。要するにフォームで入力した内容を取得をしています。深くは考えなくとも大丈夫です。

 textFiled.value = ``

繰り返し送信できるようにイベントが発火したらtextFiledのvalueを空文字にしておきます。空文字にしなかった場合は、 前回、送信した内容が残った状態になります。

 document.querySelector("main").insertAdjacentHTML('beforeend',p)

こちらのソースコードは、mainタグを取得をし、insertAdjacentHTMLを用いて生成したHTML要素をmainタグの末尾に挿入をしています。

insertAdjacentHTMLとは、ノードを DOM ツリー内の指定された位置(第一引数で指定)に挿入をするメソッドです。HTML または XML としてパースした結果のノードをDOMに挿入します。DOMに挿入をする際にとても便利なメソッドですので、構文を確認をしてみましょう。

elment.insertAdjacentHTML(挿入したい位置,HTML要素、XML要素)

第一引数については

  • 'beforebegin'
    element の直前に挿入
  • 'afterbegin'
    element 内部の、最初の子要素の前に挿入
    'beforeend
    element 内部の、最後の子要素の後に挿入
  • 'afterend
    element の直後に挿入

と色んな位置に挿入をする事ができます。今回の場合は、beforeendなので、mainタグの末尾に挿入をしています。

 document.querySelector(`#text${index}`).classList.add(colors[Math.floor(Math.random()*colors.length)])

生成したHTML要素を取得をし、addメソッドを用いて、配列colorsの中からランダムでクラスを取り出し、追加をしています。配列を用意してランダムでクラスを取り出す事で、生成したHTML要素を「ランダムに色を変える」を実現をしています。

 index++

indexに+1をしています。submitイベントが発火するごとに+1をする事によってid名に変化を持たせていて、結果的にaddメソッドでクラスを追加をする際にHTML要素を番号で、判別をしてクラスを追加できます。

以上で、「簡易的な送信フォームをDOM操作してみよう」実装が終わりです。完成版のソースコードを貼り付けおきます。

const SubmitEventForm = document.querySelector("#SubmitEventForm")
const textFiled = document.querySelector('input[type="text"]')
const colors = ["aqua","greenyellow","darkgrey","white","red"]
let index = 0
function submitEvent(event){
    event.preventDefault()
    const p = `<p id = text${index}>${textFiled.value}</p>`
    textFiled.value = ``
    document.querySelector("main").insertAdjacentHTML('beforeend',p)
    document.querySelector(`#text${index}`).classList.add(colors[Math.floor(Math.random()*colors.length)])
    index++;
}
SubmitEventForm.addEventListener("submit",submitEvent)  

まとめ:簡易的な送信フォームをDOM操作してみよう

今回はsubmitイベントを用いて送信フォームをDOM操作してみました。フォームに関して、サーバーとのやり取りがあり、サーバーサイドのプログラミング言語を触った事がない方からすると、とっつきにくい内容ですが、web開発を行う上でフォームを操作する知識は必須になるので、徐々に覚えていきましょう。

以上、kazutoでした。