

ぐるなびapiを利用して、飲食店の検索ページを作成しました。

都道府県、飲食店の種類を指定して、検索ボタンをクリックすると、５００件ごとの検索結果（飲食店名、存在する地域、交通機関、最寄駅のリスト）が表示されるようなページを
javascript(jQuery)を使って組み立てました。

「次の結果」ボタンクリックで、次の５００件の検索結果を表示する。「前の結果」ボタンクリックで、前の５００件の検索結果を表示するようにしています。

「次の結果」を連続してクリックすると、順調に次の検索結果が表示されるのですが、途中で「前の結果」をクリックして前へ戻ろうとすると、「前の結果」にもかかわらず、次の検索結果が表示されます。

ただし、それは１回のみで、その後「前の結果」を連続してクリックしていけば、前の結果が表示されていきます。

同様に「前の結果」を連続してクリックすると、順調に前の検索結果が表示されるのですが、途中で「次の結果」をクリックして次へ進もうとすると、「次の結果」にもかかわらず、前の検索結果が表示されます。

ただし、これも同様に１回のみで、その後「次の結果」を連続してクリックしていけば、次の結果が表示されていきます。

途中でボタンを切り替えると、直前のボタン処理で行った関数が残っているような感じです。途中でボタンを切り替えても、すぐに検索結果が反映されるようにしたいのですが、どなたかご教示いただけますか。

コード  

[code]

    <!DOCTYPE html>
    
    <html>
    
    <head>
    
      <meta charset="utf-8">
    
      <meta name="viewport" content="width=device-width">
    
      <link rel="stylesheet" type="text/css" href="./gurunavi.css">
    
      <script type="text/javascript" src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
    
      <script type="text/javascript">
    
      jQuery(function() {
    
        (function() {
    
          var $container = jQuery('.grid'); //wrapper要素指定
    
          var $inner = '.grid-item'; //inner要素指定
    
          var api_key = '個人のapiキーをここに入力';
    
          var hit_per_page_num = 500; //一度に表示する件数
    
          var offset_page_num = 1; //初期ページ
    
          var sort = 1; //ソート(名前順)
    
      　　var url_rest = 'http://api.gnavi.co.jp/RestSearchAPI/20150630/?callback=?'; //レストラン検索API
    
          var url_pref = 'http://api.gnavi.co.jp/master/PrefSearchAPI/20150630/?callback=?'; //エリアマスタ取得API
    
    　　　var url_cat = 'http://api.gnavi.co.jp/master/CategoryLargeSearchAPI/20150630/?callback=?'; //カテゴリー取得API
    
          var params = {
    
            keyid: api_key,
    
            format: 'json',
    
          }  
    
          var params_shop = jQuery.extend({ }, params);
    
          params_shop.hit_per_page = hit_per_page_num;
    
          params_shop.offset_page = offset_page_num; 
    
          params_shop.sort = sort;
    
          var resultLooplength = 0; //店舗データ数判定
    
          var resultLoopnext = function(result) { //次ページの店舗データ出力
    
            document.getElementById("load_next").disabled = false;
    
            document.getElementById("load_back").disabled = false;
    
            resultLooplength = hit_per_page_num * (params_shop.offset_page - 1);
    
            if(resultLooplength < 0) {
    
              resultLooplength = 0;
    
              params_shop.offset_page = 1;
    
            }
    
            var res = "";
    
            res += "<table border='1' cellpadding='5' style='border-collapse:collapse;'>";
    
            res += "<tr><td align='center'>No.</td><td align='center'>店舗名（五十音順）</td><td align='center'>登録エリア</td><td align='center'>交通路線</td><td align='center'>最寄駅</td></tr>";
    
            for (var i in result.rest) {
    
              var elem = {
    
                name: result.rest[i].name, //店舗名取得
    
                url: result.rest[i].url, //ぐるなび店舗詳細ページURL取得
    
                area: result.rest[i].code.areaname_s, //エリア名取得
    
                line: result.rest[i].access.line, //路線名取得
    
                station: result.rest[i].access.station //最寄駅名取得
    
              }
    
              i++; 
    
              res += "<tr>";
    
              if(elem.area == '[object Object]') {
    
                elem.area = "情報提供なし";
    
    　　　　　} else {
    
                elem.area = elem.area;
    
              }
    
              if(elem.line == '[object Object]') {
    
                elem.line = "情報提供なし";
    
    　　　　　} else {
    
                elem.line = elem.line;
    
              }
    
              if(elem.station == '[object Object]') {
    
                elem.station = "情報提供なし";
    
    　　　　　} else {
    
                elem.station = elem.station;
    
              }
    
        　resultLooplength++;
    
        　res += "<td>" + resultLooplength + "</td><td><a href='" + elem.url + "' target='_blank'>" + elem.name + "</a></td><td>" + elem.area + "</td><td>" + elem.line + "</td><td>" + elem.station + "</td>";
    
              res += "</tr>";
    
            }
    
            res += "</table>";
    
            document.getElementById("table").innerHTML = res;
    
            var page_num = params_shop.offset_page + " ページ目";
    
            document.getElementById("page").innerHTML = page_num;
    
            if(resultLooplength >= result.total_hit_count) {
    
              alert("全店舗を表示しました。");
    
              document.getElementById("load_next").disabled = true;
    
              if(params_shop.offset_page == 1) {
    
                document.getElementById("load_back").disabled = true;
    
              } else {
    
                params_shop.offset_page--;
    
              }         
    
            }       
    
            params_shop.offset_page++;
    
          };
    
          var resultLoopback = function(result) { //前ページの店舗データ出力
    
            document.getElementById("load_next").disabled = false;
    
            document.getElementById("load_back").disabled = false;
    
            resultLooplength = hit_per_page_num * (params_shop.offset_page - 1);
    
            var res = "";
    
            res += "<table border='1' cellpadding='5' style='border-collapse:collapse;'>";
    
            res += "<tr><td align='center'>No.</td><td align='center'>店舗名（五十音順）</td><td align='center'>登録エリア</td><td align='center'>交通路線</td><td align='center'>最寄駅</td></tr>";
    
            for (var i in result.rest) {
    
              var elem = {
    
                name: result.rest[i].name, //店舗名取得
    
                url: result.rest[i].url, //ぐるなび店舗詳細ページURL取得
    
                area: result.rest[i].code.areaname_s, //エリア名取得
    
                line: result.rest[i].access.line, //路線名取得
    
                station: result.rest[i].access.station //最寄駅名取得
    
              }
    
              i++; 
    
              res += "<tr>";
    
              if(elem.area == '[object Object]') {
    
                elem.area = "情報提供なし";
    
    　　　　　} else {
    
                elem.area = elem.area;
    
              }
    
              if(elem.line == '[object Object]') {
    
                elem.line = "情報提供なし";
    
    　　　　　} else {
    
                elem.line = elem.line;
    
              }
    
              if(elem.station == '[object Object]') {
    
                elem.station = "情報提供なし";
    
    　　　　　} else {
    
                elem.station = elem.station;
    
              }           
    　　
              resultLooplength++; 
    
        　res += "<td>" + resultLooplength + "</td><td><a href='" + elem.url + "' target='_blank'>" + elem.name + "</a></td><td>" + elem.area + "</td><td>" + elem.line + "</td><td>" + elem.station + "</td>";
    
              res += "</tr>";
    
              if(resultLooplength == 1) {
    
                document.getElementById("load_back").disabled = true;
    
              }
    
            }  
    
            res += "</table>";
    
            document.getElementById("table").innerHTML = res;
    
            var page_num = params_shop.offset_page + " ページ目";
    
            document.getElementById("page").innerHTML = page_num;
    
            params_shop.offset_page--;
    
          };
    
          var resultNum = function(result) { //取得件数を表示
    
            if (result.total_hit_count > 0) {
    
              jQuery('.total').html(resultLooplength + ' / ' + result.total_hit_count + ' の店舗を表示\n');
    
            } else {
    
              jQuery('.total').html('店舗がありません。');
    
            }
    
          };
    
          var resultPref = function(result) { //都道府県データをselect要素として生成
    
            for (var i in result.pref) {
    
              var pref_name = result.pref[i].pref_name;
    
              var pref_code = result.pref[i].pref_code;
    
              jQuery("[name = pref_name]").append('<option value="' + pref_code + '">' + pref_name + '</option>');
    
            }
    
          };
    
          var resultCat = function(result) { //カテゴリーデータをselect要素として生成
    
            for (var i in result.category_l) {
    
              var cat_name = result.category_l[i].category_l_name;
    
              var cat_code = result.category_l[i].category_l_code;
    
              jQuery("[name = cat_name]").append('<option value="' + cat_code + '">' + cat_name + '</option>');
    
            }
    
          };
    
          jQuery(window).on('load', function() {
    
            jQuery.getJSON(url_pref, params, function(result) { //都道府県データを取得し表示
    
              resultPref(result);
    
            })
    
            jQuery.getJSON(url_cat, params, function(result) { //カテゴリーデータを取得し表示 
    
              resultCat(result);
    
            })
    
          });
    
          jQuery("#load_next").on('click', function() {
    
            jQuery.getJSON(url_rest, params_shop, function(result) {
    
              resultLoopnext(result);
    
              resultNum(result);
    
            })
    
          });  
    
          jQuery("#load_back").on('click', function() {
    
            jQuery.getJSON(url_rest, params_shop, function(result) {
    
              resultLoopback(result);
    
              resultNum(result);
    
            })        
    
          });
    
          jQuery('[name = shop_search]').on('click', function() { //都道府県を変更して店舗データを再取得　
    
            resultLooplength = 0; //店舗データ数判定を初期化
    
            document.getElementById("load_next").disabled = false;
    
            document.getElementById("load_back").disabled = false;
    
            var pref_val = jQuery('[name = pref_name]').val(); //option要素のvalue(都道府県パラメータ)を取得
    
            var cat_val = jQuery('[name = cat_name]').val(); //option要素のvalue(カテゴリーパラメータ)を取得
    
            $container.empty(); //データ一覧を初期化
    
            params_shop.offset_page = 1; //ページ数を初期化
    
            params_shop.pref = pref_val; //都道府県パラメータを都道府県データ取得APIにセット
    
            params_shop.category_l = cat_val; //カテゴリーパラメータを大カテゴリーデータ取得APIにセット
    
            jQuery.getJSON(url_rest, params_shop, function(result) {
    
              resultLoopnext(result); 
    
              resultNum(result);
    
            })
    
          });
    
        }).call(this);
    
      }); 
    
      </script>
    
    </head>
    
    <body>
    
      <article class="wrap">
    
        <header class="header">
    
          <div class="inner">       
    
            <center>
    
              <span class="pref_search">
    
                都道府県&nbsp;&nbsp;                    
    
                <select name="pref_name"></select>&nbsp;&nbsp;
    
              </span>
    
              <span class="cat_search">
    
                ジャンル&nbsp;&nbsp;
    
                <select name="cat_name"></select>&nbsp;&nbsp;
    
                <button type="button" name="shop_search">検 索</button>&nbsp;&nbsp;
    
                <input type="button" id="load_back" value="前の結果">&nbsp;&nbsp;
    
                <input type="button" id="load_next" value="次の結果">
    
              </span>&nbsp;&nbsp;
    
              <span class="total"></span>&nbsp;&nbsp;
    
              <span id="page"></span>
    
             </center>  
    
          </div>
    
        </header><br>
    
        <hr><br>
    
        <div class="content_outer">
    
          <div class="content_inner">
    
            <section>
    
              <div id="table"></div><br>
    
              <center>
    
                <a href="javascript:scrollTo(0, 0)"><input type="button" id="page_top" value="ページトップへ"></a>
    
              </center>   
    
            </section>
    
          </div>
    
        </div>
    
        <footer>
    
          <div class="container"></div>
    
        </footer>
    
      </article>
    
    </body>
    
    </html>
    
[/code]


CC BY-SA 3.0
2016-10-16T11:54:48.480
29608
2016-11-18T15:50:03.753
2016-10-16T13:26:51.453
5246
19190
question
javascript jquery
ボタンクリックの関数の処理が残ってしまう


※全くの勘違いだったので前の回答は削除しました

質問に書かれたコードから「前の結果」を押した時の処理を抜粋します。

[code]

    jQuery("#load_back").on('click', function() {
      jQuery.getJSON(url_rest, params_shop, function(result) {
        resultLoopback(result);
        resultNum(result);
      })
    });
    
[/code]

そして `resultLoopback()` は次のようになっています。

[code]

    var resultLoopback = function(result) { //前ページの店舗データ出力
      document.getElementById("load_next").disabled = false;
      document.getElementById("load_back").disabled = false;
      resultLooplength = hit_per_page_num * (params_shop.offset_page - 1);
    
      // 略（resultの表示処理）
    
      params_shop.offset_page--;
    };
    
[/code]

今回表示する分の **API呼び出しを行った後に** `params_shop.offset_page`
を更新していますね・・・？言い換えると、次にどのページが表示されるかを変更してしまっているのです。

  * 「検索」 表示: 1ページ目 params_shop.offset_page: 2
  * 「次の結果」 表示: 2ページ目 params_shop.offset_page: 3
  * 「次の結果」 表示: 3ページ目 params_shop.offset_page: 4
  * 「前の結果」 表示: 4ページ目 params_shop.offset_page: 3
  * 「次の結果」 表示: 3ページ目 params_shop.offset_page: 4

「前の結果」というのはその時に取得・表示されるページを前ページにしたいのですから、 **APIを呼び出す前に**
`params_shop.offset_page` を更新しなければいけません。むしろ取得結果の表示ロジックは同じものが使えるはずです。


CC BY-SA 3.0
2016-10-17T08:23:56.757
29628
2016-10-17T08:23:56.757
8000
29608
answer