Ajax非同期通信を使ったページャー表現
表示する件数が多い場合に、ページ選択アイコンが並びぶページャーをjQuery+非同期通信で実現する方法です。調べるとおそらくはプラグイン等がたくさんあると思うのですが、そこは先ず自分で作ってみてからって事で。
サンプルは郵便局ホームページからダウンロード出来るCSVを利用させて頂きました。
HTMLとCSS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | /* * 表部分 */ #pager table { border : 1px solid #DDDDDD ; border-collapse : collapse ; font-size : 85% } #pager table tr th{ border : 1px solid #DDDDDD ; padding : 3px ; background : #828282 ; color : #FFF ; } #pager table tr td{ border : 1px solid #DDDDDD ; padding : 5px ; } /* * ページャーアイコン */ #ajax_pager{ height : 30px ; margin-bottom : 10px ; line-height : 30px ; overflow : hidden ; padding : 2px ; } #ajax_pager a{ display : block ; border : 1px solid #DDDDDD ; float : left ; padding-left : 5px ; padding-right : 5px ; text-align : center ; text-decoration : none ; margin-right : 2px ; } #ajax_pager a:hover{ background-color : #828282 ; color : #FFFFFF ; } #ajax_pager .nowpage{ border : 1px solid #DDDDDD ; float : left ; padding-left : 5px ; padding-right : 5px ; height : 30px ; background-color : #828282 ; color : #FFFFFF ; text-align : center ; line-height : 30px ; margin-right : 2px ; } #ajax_pager .page_message{ float : left ; height : 30px ; line-height : 30px ; padding-left : 30px ; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 | < script src = "//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js" ></ script > < script type = "text/javascript" src = "pager.js" ></ script > < div id = "pager" > <!-- 表を表示する部分 --> </ div > < script type = "text/javascript" > $(function(){ $('#pager').pager({ 'page_max': '30' //1ページの表示件数 ,'row' : ['zip','area','add1','add2'] //tableに表示する項目 ,'th' : ['郵便番号','都道府県','住所1','住所2'] //表題 }); }); </ script > |
オプションで1ページあたりの表示件数と、表示したい項目や表題などが設定出来ます。
pager.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | ( function ($){ $.fn.pager = function (options){ var settings = $.extend( { 'page_max' : 100 , 'row' : [ '' ] , 'th' : [ '' ] }, options); /* * データの読み込み */ var reading = function (div,nowpage){ $( "#list_div" ).html( '<img src="loader2.gif" />' ); var page_max = settings.page_max; var start = 0; if ( nowpage > 1 ){ start = (page_max*nowpage) - page_max+1; //2ページ目以降は次の開始位置を計算 } $.ajax({ type: "POST" , url: "pager.php" , data: "page_max=" +page_max+ "&start=" +start, async : false , success: function (xml){ var len = $(xml).find( "len" ).text(); page_icon (nowpage,len); var len = len.toString().replace( /([0-9]+?)(?=(?:[0-9]{3})+$)/g , '$1,' ); //3桁ごとにカンマ $( "#ajax_pager" ).append( '<p class="page_message">データ件数は <strong>' +len+ '</strong>件です</p>' ); var html = '<table>' ; html += '<tr>' ; for ( var i=0; i<settings.th.length; i++){ html += '<th>' +settings.th[i]+ '</th>' ; } html += '</tr>' ; $(xml).find( "item" ).each( function (){ html += '<tr>' ; for ( var i=0; i<settings.row.length; i++){ html += '<td>' +$( this ).find(settings.row[i]).text()+ '</td>' ; } html += '</tr>' ; }); html += '</table>' ; $( "#list_div" ).html(html); } }); }; /* * ページアイコンの作成 */ var page_icon = function (nowpage,len){ var p = 1; //ページ開始位置 //7ページ以上ならば、開始ページを1加算 if (nowpage > 6){ p = nowpage-5; } $( "#ajax_pager" ).html( '<img src="loader2.gif" />' ); var page = len/settings.page_max; //全件数をページ表示件数で割る page = Math.ceil(page); //小数点切り上げ var html = '' ; if ( nowpage > 1){ var backpage = nowpage-1; //前のページに戻る数 html += '<a href="#" id="page1"><<</a>' ; html += '<a href="#" id="page' +backpage+ '"><</a>' ; } for ( var i=0; i<10; i++){ //最大10ページ分のアイコン if (nowpage == p){ html += '<p class="nowpage">' +p+ '</p>' ; //現在のページならば } else { html += '<a href="#" id="page' +p+ '">' +p+ '</a>' ; } p++; if (p >= page) break ; //ページ数より大きくなったら停止 } var nextpage = nowpage+1; var endpage = page-1; if ( endpage != nowpage){ html += '<a href="#" id="page' +nextpage+ '">></a>' ; if (page >10) html += '<a href="#" id="page' +endpage+ '">>></a>' ; //10ページ以上あるならば } $( "#ajax_pager" ).html(html); //ページアイコンの表示 }; /* * ページをクリックしたら */ $(document).on( 'click' , '#ajax_pager a' , function (e){ var page= $( this ).attr( "id" ); page = page.match(/page(\d+)/)[1]|0; //page123 からpageを除去*数値にする reading( this ,page); e.preventDefault(); }); /* * <div id="pager"> 以下に要素の追加 */ $( this ).prepend( '<div id="ajax_pager"></div>' ); $( this ).append( '<div id="list_div"></div>' ); reading( this ,1); }; })(jQuery) |
現在の表示ページや表示件数等をpager.phpに非同期通信で渡す処理や、[1][2][3]といったアイコン表示を行っています。
pager.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | <?php /* * サニタイズなどは事前に処理 * ここではとりあえず$_POSTに対して仮の処理 */ if ( is_array ( $_POST ) ){ $data = array (); foreach ( $_POST AS $key => $str ){ $str = htmlspecialchars( $str , ENT_QUOTES , "UTF-8" ); $data [ $key ] = $str ; } } /* * pager.phpに直でアクセスされた場合など、停止させる * 特にここでデータベースからデータを取り出す場合は注意を! */ if (! $data [ 'page_max' ]) exit ; $row_all = file( 'zip.csv' ); //ファイルを配列へ $output = array_slice ( $row_all , $data [ 'start' ], $data [ 'page_max' ]); // 配列を指定行数から指定分だけ取り出す header( "Content-type: application/xml" ); echo '<?xml version="1.0" encoding="UTF-8" ?> ' . "\n" ; echo '<rss>' . "\n" ; echo ' <len>' . count ( $row_all ). '</len>' . "\n" ; //全件数 foreach ( $output AS $row ){ $row = str_ireplace ( '"' ," ",$row); //" "で括られているので除去 $row = explode ( "," , $row ); //カンマ区切りで配列に echo ' <item>' . "\n" ; // オプションで指定した 'row' : ['zip','area','add1','add2'] に合わせて名前を付ける echo ' <zip>' . $row [ '2' ]. '</zip>' . "\n" ; echo ' <area>' . $row [ '6' ]. '</area>' . "\n" ; echo ' <add1>' . $row [ '7' ]. '</add1>' . "\n" ; echo ' <add2>' . $row [ '8' ]. '</add2>' . "\n" ; echo ' </item>' . "\n" ; } echo '</rss>' . "\n" ; |
非同期通信で送信された$_POSTのサニタイズはご自由に。サンプルは$_POSTをループし、htmlspecialcharsでHTMLエンコードだけの、仮のものを書いています。
ページ数に応じて配列をarray_sliceで指定分だけ取り出し、XML形式で書き出します。ここでデータベースからデータを取り出すのであれば、LIMITで処理しても良いと思います。
注意
pager.phpに直でアクセスされると色々と問題があるので、正しい経路からの処理で有ることを確認する事が大切です。特にデータベースからデータを取り出す場合はより注意が必要だと思います。HTML側をphpにし、Sessionにランダムなワンタイムキーを記録、pager.php側でそれと照合し、OKの場合だけ処理など、対応を忘れずに。