jQuery 基本その4 検索フォーム

今日は基礎的な検索フォームについて
書こうと思います。

# 基本形
まず基本形として
HMTL要素を書き換えるコードを例として書きます。

①submitのidからクリックアクションが会ったらイベントが発火
②keywordのidから入力要素取得
③resultのidへtextを入力内容に変更(仮)

という手順です。

使用するHTMLは

```html:html
<body>
    <div class="form-group">
      <input type='text' id="keyword" class="form-control" placeholder="好きなフルーツを入力してください">
      <button type="button" id="submit" class="btn">検索</button>
    </div>
    <p id="result"></p>
  </body>
```

このような形を使用します。

まずコードの雛形について説明していきます。

```js:基本形
$(function() {
  $("#submit").on("click", function() { //①submitのidからクリックアクションが会ったらイベントが発火
    let input = $("#keyword").val(); //②keywordのidから入力要素取得
    $("#result").text(input); //③resultのidへtextを入力内容に変更(仮)
  });
});
```
## 入力内容と同一のものを検索

まずeach構文で配列の全ての要素を引っ張ってきます。

```js:jQuery
$.each(fruits, function(i, fruit) {
    // 配列の要素fruitと入力した値が一致するかどうかの処理を書く
    // 一致したらループ抜ける
});
```

```js:jQUery
var fruits = ['リンゴ', 'バナナ', 〜〜];

$(function() {
  $("#submit").on("click", function() {
    let input = $("#keyword").val();
    $.each(fruits, function(i, fruit) { //each構文を設定
      if (input === fruit) { //if構文で入力内容と同一のものを条件に
        $("#result").text(input); //text内容入力内容に変更
        return false; //一致するものを確認したらRubyで言うbreak文で終わります。
      } 
    });
  });
});
```

## 一致するものがなかった時
例外文の場合の記述はこうです。

```js:jQUery
//(省略)
return false;
      } else {
        $("#result").text("一致する果物はありませんでした。");
      }
//(省略)
```

## 一部の言葉で検索
「パイ」と検索したら「パインとパイナップル」が一致するので
この2つのフルーツが表示されるようにしましょう。
このように単語の前方と一致する単語を検索することを前方一致といいます。
前方一致で検索をするには、正規表現を使う必要があります。

また複数の検索結果の出力になるので
下記のようなhmtlの設定もした方がいいです。

```html:hmtl
<ul id="list"></ul>
```

基本的な構文はこちら

```js:jQuery
// 正規表現オブジェクトに変換
let reg = new RegExp("前方一致");

// matchメソッドで一致したらtrueかfalseを戻す
match(reg);
```

例文を作ってみるとこうです。
三つのコードに分けて記述されています。
①変数listにidがlistを設定
②appendList関数を設定
③submitイベントを設定
という内容です。

```js:jQuery
$(function() {
  let list = $("#list"); //①変数listにidがlistを設定

  function appendList(word) { //②appendList関数を設定
    let item = $('<li class="list">').append(word); //引数wordにlistクラスを追加
    list.append(item); //変数listにitemを追加
  }

  $("#submit").on("click", function() { //③submitイベントを設定
    let input = $("#keyword").val(); //input内容を取得
    let reg = new RegExp("^" + input); //正規表現での前方一致検索

    $(".list").remove(); //listクラスの削除

    $.each(fruits, function(i, fruit) { //each構文の設定
      if (fruit.match(reg)) { //fruitより一致内容検索
        appendList(fruit); //一致した内容を②に飛ばします。
      }
    });

    if ($(".list").length === 0) { //一致する内容がなかった場合
      appendList("一致する果物はありませんでした");
    }
  });
});
```

## 複数の言葉で検索

複数の言葉でも検索できるようにしましょう。
「パ リ」と検索された場合、「パイン, パイナップル, リンゴ, パリ」が一致するので
これら4つが表示されるようにします。

加えた記述主に
④各要素を正規表現で検索の仕様変更。
⑤複数の検索ワードを検索。

です。


完成形はこちら

```js:jQuery
var fruits = ['リンゴ', 'バナナ', 〜〜];

$(function() {
  let list = $("#list");

  function appendList(word) {
    let item = $('<li class="list">').append(word);
    list.append(item);
  }

  function editElement(element) {
    let result = "^" + element;
    return result;
  }

  $("#submit").on("click", function() {
    let input = $("#keyword").val();
    let inputs = input.split(" "); 
    let newInputs = inputs.map(editElement); 
    let reg = RegExp(newInputs.join("|"));

    $(".list").remove();

    $.each(fruits, function(i, fruit) {
      if (fruit.match(reg)) {
        appendList(fruit);
      }
    });

    if ($(".list").length === 0) {
      appendList("一致する果物はありませんでした");
    }
  });
});
```

加えた内容だけ表示すると

```js:jQuery

//(省略)

  function appendList(word) {
    let item = $('<li class="list">').append(word);
    list.append(item);
  }

  function editElement(element) { //④各要素を正規表現で検索の仕様にします。
    let result = "^" + element;
    return result;
  }

  $("#submit").on("click", function() { //⑤複数の検索ワードを検索します。
    let input = $("#keyword").val();
    let inputs = input.split(" "); //入力内容から配列を作成,引数に設定した空欄で分けます。
    let newInputs = inputs.map(editElement); //mapを使って要素を加工した新しい配列を作成します。
    let reg = RegExp(newInputs.join("|")); //joinを使って|で配列の要素をつないだ正規表現を作成します。

    $(".list").remove();

//(省略)
```

### splitを使って文字列から配列を作成する
split()
split()は、文字列を複数の部分文字列に区切り、文字列の配列に分割します。引数には文字列を区切るための文字を指定します。

```js:jQuery
let inputs = input.split(" ");
```

### mapを使って要素を加工した新しい配列を作成する
map()
map()は、配列から要素を1つずつ取り出し、引数に与えられた関数の処理を行った結果から新しい配列を作ります。

```js:jQuery
let newInputs = inputs.map(editElement);
```

### joinを使って|で配列の要素をつないだ正規表現を作成する
join()
join()は、配列のすべての要素をつないだ文字列を作成します。
引数に文字列を渡すと、その文字列で文字と文字をつなげます。

```js:jQuery
let reg = RegExp(newInputs.join("|"));
```

複数の言葉で正規表現を使用するには|を使って言葉を繋げます。
複数の言葉が要素の配列newInputsの要素を|でつなぐことで複数検索ができるようにします。

join()の引数に|を渡すことでnewInputsの要素を|でつないでいます。
その結果をRegExpの引数に渡すことで正規表現を作成しています。