【もりけん塾 @JS課題14-15】form要素の値の取得、バリデーション、分割代入

JavaScript

現在、もりけん塾で
マークアップエンジニアの方がフロントエンドエンジニアになる為の課題に取り組んでいます。
今回は課題14-15の実装で学んだことをブログへまとめます

課題15

①ボタンをクリックしたらモーダルが表示
②モーダル内のにinput[type=”number”]input[type=”text”]input[type=”submit] を設置
(未入力の場合はアラートが発生)
input[type=”submit]をクリックするとリクエストがはしる
④入力された値はコンソールへ出力
⑤fetchを使用しJSONデータを取得する
(データ取得の間はくるくるさせる)
⑥取得したデータを加工し、ブラウザに表示

今回実装したコード

See the Pen Untitled by Sae (@Sae_codepen) on CodePen.

form要素の値の取得

モーダル内のinput[type=”number”]とinput[type=”text”]に入力された値を取得します

 <input type="text" name="name" id="name">
 <input type="number" name="number" id="number">

IDで要素を取得し、.valueとすることで値の取得ができました

  const inputName = document.getElementById("name").value;
  const inputNumber = document.getElementById("number").value;

バリデーション


バリデーションとは、入力されたデータが、あるいはプログラミング言語やマークアップ言語の記述が、規定された文法に即して、または要求された仕様にそって、適切に記述されているかどうかを検証することである。

https://www.sophia-it.com/content/%E3%83%90%E3%83%AA%E3%83%87%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3  

今回は、入力がなかった(空の)場合はリクエストができず
アラートが出る様なバリテーションをJavaScriptで実装しました

まず 最初のPRで実装したコードです↓

  const inputName = document.getElementById("name").value;
  const inputNumber = document.getElementById("number").value;
  
  if (inputName === "" || inputNumber === "") {
    alert("Name or number not entered. Please confirm.");
  } else {
    console.log(`Name: ${inputName}, Number: ${inputNumber}`);
  }

レビューで この実装だと inputNameに空白文字が入った場合に
バリデーションが通ってしまう点を教えて頂きました

試したこと①

空白文字が入れられた際の値を調査しました
typeofはString、Booleanはtrue、nullでもない…
lengthは1でした(もちろん空白文字が増えればその分増えました)

つまり[type=”text”]は 空白文字も 1文字としてカウントしてしまう…
(確かに お問い合わせフォームで名前を入力する時 苗字と名前の間にスペース空けたりするよな…)

試したこと②

調査したことを踏まえて、実装しなおしました

const replaceInputName = inputName.replace(/\s+/g, '');

  if (replaceInputName.length === 0 || inputNumber === "") {
    alert("Name or number not entered properly.Please confirm.");
  } else {
    console.log(`Name: ${replaceInputName}, Number: ${inputNumber}`);
  }

replaceと正規表現を使用し、空白文字を取り除きました(厳密に言うと置き換えた)

ですが今の状態だと、苗字と名前の間の空白なども含めて 全ての空白文字が 取り除かれてしまいます…
もりけん先生に レビューでtrimメソッドの存在を教えて頂きました

String.prototype.trim() - JavaScript | MDN
trim() メソッドは、文字列の両端からホワイトスペースを取り除き、元の文字列を変更せずに新しい文字列を返す。

試したこと③

教えて頂いたメソッドを使って再度実装しました

 const trimInputName = inputName.trim();

  if (trimInputName.length === 0 || inputNumber === "") {
    alert("Name or number not entered properly.Please confirm.");
  } else {
    console.log(`Name: ${trimInputName}, Number: ${inputNumber}`);
  }
});

trim()で両端の空白を取り除き(トリミングして)、変数へ格納し条件式をかきました

変数名について

trim()で空白を取り除いた値を、変数trimInputName へ格納しましたが、
もりけん先生から trimmedInputName がいいのでは..とレビュー頂きました
trim()した後の値を格納するので、過去形にする方が適切だと感じました!

制約検証

前項の通り、今回はJavaScriptでバリデーションを実装しましたが、
HTMLの制約検証を使用する方法も考えてみました

制約検証 - HTML: ハイパーテキストマークアップ言語 | MDN
ウェブフォームの作成は常に複雑な作業でした。フォーム自体をマークアップすること自体は簡単ですが、それぞれの入力欄が妥当で一貫しているかどうかをチェックすることはもっと難しく、問題をユーザーに伝えることは頭痛がするかもしれません。HTML5 では、フォームに新しい仕組みが導入されました。 要素に意味を持つ新しい型と、ク...
Validating HTML Forms using JavaScript and Constraint Validation API
The first and simplest phase of Validating HTML Forms is specifying which information is important and required. In every form, some

HTMLの属性で制約をすることができ、typerequiredpattern を使用しました

<input type="text" name="name" id="name" pattern=".*\S+.*" required>
<input type="number" name="number" id="number" required>

type

type属性を指定することで、指定したタイプに合わせて制御をしてくれる
今回のnumberであれば 数値しか入力できない様に 制御してくれる

required

入力を必須にしたいので使用しました

pattern

.*\S+.* は正規表現で 空白文字のみの入力を弾く様にしました
( 文字の中の空白は弾かれない )

requestBtn.addEventListener("click", (e) => {
  const inputName = document.getElementById("name");
  const inputNumber = document.getElementById("number");

  const returnName = inputName.validity.valid;
  const returnNumber = inputNumber.validity.valid;

  if ( returnName && returnNumber) {
    e.preventDefault();
    console.log(`Name: ${inputName.value}, Number: ${inputNumber.value}`);
  } 
});

validity / valid

validityプロパティはValidityStateオブジェクトを返し、
ValidityStateオブジェクト内には制約に対する検証結果をBooleanで格納しています

この中のvalidプロパティを使用しました
vaildプロパティは全ての制約検証をクリアした場合はtureが、
いずれかでも クリアしなかった場合はfalseが返ります

分割代入

今回、オブジェクトの分割代入を用いて一部実装しました

分割代入 ~ オブジェクト ~

以下の例を使用して、色々パターンの分割代入を試してみました

const member = {
  name: "山田",
  number: 1
}

オブジェクトのプロパティ(キー)から変数に割り当てることができます

const { name, number } = member;         // 右辺に取り出したいオブジェクトを指定する
console.log(name , number);  // output 山田  1

任意の変数名をつける

const { name: a, number: b } = member;         // プロパティ:任意の変数名
console.log(a, b);                         //output  山田  1

この場合、変数nameやnumberへアクセスするとReferenceErrorエラーになります

変数宣言を省略する

( . . . )を使用する

({name, number} = {name: "山田", number: 1}); 

デフォルト値と新しい変数の追加

const { name, number, age = 29 } = member;   
console.log(name,number,age);                       // 山田 1 29

memberオブジェクトに追加されるわけではない

プロパティ名を動的にする

function getMemberData(key) {
  const { [key]: value } = member;
  console.log(value);
}

getMemberData("name");
getMemberData("number");

今回の課題で 使用した様なオブジェクトがあった場合を 考えてみました

const responseData = {
  data: [
    {
      a: "bookmark",
      img: "img/1.png",
      alt: "画像1",
      text: "ブックマーク"
    },
    {
      a: "message",
      img: "img/2.png",
      alt: "画像2",
      text: "メッセージ"
    }
  ]
}

ネストされたプロパティを割り当てる

const { data: [{ a, img, alt, text }] } = responseData;
console.log(a, img, text, alt);

関数の引数

以下の様に、関数の実引数にオブジェクトを渡し 仮引数で分解して受け取ることができました

function createList({ data }) {
  const frag = document.createDocumentFragment();
  for (const { a, img, alt, text } of data) {
    const li = document.createElement("li");
    const anchor = document.createElement("a");
    const image = document.createElement("img");

    anchor.href = `/${a}.html`;
    image.src = img;
    image.alt = alt;

    frag.appendChild(li).appendChild(anchor).appendChild(image);
    anchor.insertAdjacentHTML("beforeend", text);
  };
  ul.appendChild(frag);
}

createList(responseData);

分割代入 - JavaScript | MDN
分割代入 (Destructuring assignment) 構文は、配列から値を取り出して、あるいはオブジェクトからプロパティを取り出して別個の変数に代入することを可能にする JavaScript の式です。
A practical guide to object destructuring in JavaScript
Learn JavaScript object destructuring with lots of examples and use-cases. I will be explaining destructuring from my project experiences with many tips.

まとめ

課題14 -15を通して、form要素の値の取得について学びました。
バリデーションも まだまだ学習不足なので 引き続き学習していきたいと思います。

また、今回の課題を行う前に 何度か他の塾生さんの課題を レビューさせて頂きました。
学んだ点を自分で調べ 自分のコードに落とし込むことができ、より課題に向き合えたと感じました。
引き続き、課題もレビューも頑張りたいです


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