LoginSignup
4
2

More than 5 years have passed since last update.

特殊な状況でのページングメモ

Last updated at Posted at 2018-03-11

ページング処理をしたい

フロントエンドの両方の開発で検索結果フィルタリングした結果を表示したいという場面がありました。
やったことは、サーバー側であるAPIをたたいた結果を内部でフィルタリングして、その結果をクライアントに渡すというものでした。また結果が多いときのためにページング処理を行うことになりました。

問題

ここで問題がありまして、利用しているAPIにはoffsetの概念があったので、それを指定してあげればページングを実現できそうだと思っていましたが、肝心のoffsetの指定がうまくできるのかという問題に直面しました。
というのも、サーバー側でフィルタリングしているのでフィルタリングではじいているものがある分、続きの検索結果がどこから始まるかが変わってしまうのです。(ページ番号×表示件数で表せない(´;ω;`))
いろんな利用者がいることを想定しており、サーバー側で値を保持するわけにもいかないのでクライアントに持ってもらうのがいいということになりました。

解決策

しかし、ここでどのように持ってもらうかが重要になるわけですね。
方法としては以下のようなものが考えられます。

  • Cookieに保存
  • HTMLに必要な情報を埋め込みリンクにクエリを仕込む
  • jsで頑張る!

わざわざCookieで持ってもらうとデータ構造が複雑なときに対応できないだろうと思い却下。
HTMLに埋め込むのは一番簡単だなと思いましたがURLのバーにクエリが表示されるのは、パソコンに詳しくない人でも簡単にいじれてしまうため誤操作を招くだろうと却下。
ということでjsで頑張ってみました。

見るのは最新の結果がほとんどなので、ページング処理といっても"次へ"と"戻る"と"最初に戻る"くらいで済むと判断し、offsetの値をスタックで保持しておきます。
苦肉の策でhtmlに次のoffsetを記録しています。(この辺いい方法ありませんかねえ…)
また、jsでAjaxを使えば画面遷移無しで処理できるのでイケてるシステムの出来上がりです。

index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <h1>Test</h1>

    <div id="result">
        <p>ここに結果を表示</p>
    </div>

    <button id="top">Top</button>
    <button id="prev">PREV</button>
    <button id="next" value="${ここにサーバーからの値が入ります}">NEXT</button>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="paging.js"></script>

</html>
paging.js
// offset初期化
let offsets = ["0"];
// url設定
const url = "/index";


/**
 * nextボタン押下
 */
$('#next').on('click',() => {
    // query作成
    const query = "?offset="+$("#next").val();
    $.ajax({
        type : "get",
        url: url + query,
        dataType : "html",
    }).done((responseData, status, jqXHR) => {
        // 次のオフセットを保存
        offsets.push($("#next").val());
        $('#result').html(responseData);
    }).fail((responseError, status, errorThrown) => {
    });
});

/**
 * prevボタン押下
 */
$('#prev').on('click',()=>{
    // 前のページのオフセットを読み込み
    const preoffset = offsets[offsets.length-2];
    // query作成
    const query = "?offset="+preoffset;
    $.ajax({
        type : "get",
        url: url + query,
        dataType : "html",
    }).done((responseData, status, jqXHR) => {
        offsets.pop();
        $('#result').html(responseData);
    }).fail((responseError, status, errorThrown) => {
    });
});

/**
 * topボタン押下
 */
$('#top').on('click',() => {
    // オフセットをクリア
    offsets = ["0"];
    $.ajax({
        type : "get",
        url: url,
        dataType : "html",
    }).done((responseData, status, jqXHR) => {
        $('#result').html(responseData);
    }).fail((responseError, status, errorThrown) => {
    });
});

最後に

続きの検索結果がない場合の処理は省略しました。
皆さんはこんな状況なかなかないかもしれませんが、参考になれば幸いです。

4
2
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
4
2