LoginSignup
16
15

More than 5 years have passed since last update.

一定時間入力が無い場合にのみ動作するフォームの作成

Last updated at Posted at 2016-04-27

 入力フォームにサジェスト機能を追加したい

googleの検索窓のように、フォームに文字入力した場合、検索結果をサーバーから取得し、結果一覧をサジェストとしてフォームに表示するような実装を行いたい。

すでにフロント側でサジェストとして表示する一覧のデータを持っているなら良いのですが、文字を1文字入力するたびに、サーバーにGETリクエストを投げるのはすごいイヤなわけです。外部APIと連携していれば、Rate Limitに達する可能性もあります。
かといって、エンターキーやボタンを押した際にサジェストを表示するのも、サジェストの意味あるの?という気がします。

そこで、最後の文字入力から1秒経過した場合に、サーバーにGETリクエストを投げる、という実装をしてみたいと思います。文字を入力した後、1秒以内に文字がタイプされた場合は、またタイマーがリセットされる、という仕組みです。

コード

AngularJSを用いて書いてみました。実際の実行例はこちらから(http://jsfiddle.net/ADukg/8059/)
文字を入力して少し経つと、「サジェストの結果」に文字が出てきます。
また、連続して文字を入力した場合は、サジェストの結果に反映されません。

form.html
<div ng-controller="MyCtrl">
  <form name="timeForm">
    <input type="text" name="firstName" ng-model="formString">
    <p>
    サジェストの結果:  {{showString}}
    </p>
  </form>
</div>
main.js
var myApp = angular.module('myApp',[]);

function MyCtrl($scope) {
  // 処理待ち用のキュー
  $scope.searchQueue = [];
  $scope.showString = '';

  // 文字入力があるたびに、waitAndGo関数を実行
  $scope.$watch('formString', function() {
    waitAndGo($scope.formString);
    });

  // 一定時間文字入力が無い場合は処理を実行
  function waitAndGo(searchQuery){
    // 処理待ちのイベントが無いか確認し、ある場合は全て実行をキャンセルする
    if($scope.searchQueue.length > 0) {
      $scope.searchQueue.forEach(function(elem){
        clearTimeout(elem);
        $scope.searchQueue.shift();
      });
    }

    // 1秒間request関数の実行を待つ。setTimeOutのIDを取得し、処理待ち用のキューに格納する
    var eventId =  setTimeout(request, 1000, searchQuery);
    $scope.searchQueue.push(eventId);

    // サーバーへのリクエスト処理。ここでは便宜的にscopeへ代入します。
    function request(query) {
        $scope.showString = query;
        $scope.$digest();
    }
  }
}

文字が入力されるたびに、

  1. 実行待ちのイベントは無いか確認
  2. あれば全て削除
  3. 入力された文字列でリクエストを実行するイベントを1秒間遅延させ、実行待ちのキューの中に登録

を、文字入力時ごとに、繰り返すことにより、ある程度まとまった文字列でGETリクエストを送信することが可能です。

16
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
15