質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Bootstrap

BootstrapはウェブサイトデザインやUIのWebアプリケーションを素早く 作成する可能なCSSフレームワークです。 Twitter風のデザインを作成することができます。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

解決済

2回答

2649閲覧

サーバーからデータ取得後のDatatablesでページ切り替えができない

Nishin

総合スコア30

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Bootstrap

BootstrapはウェブサイトデザインやUIのWebアプリケーションを素早く 作成する可能なCSSフレームワークです。 Twitter風のデザインを作成することができます。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

0クリップ

投稿2021/12/07 15:42

編集2021/12/07 15:45

PHP&MySQLと、JQueryのDatatablesを使った、一覧表示アプリを作成しようとしています。CRUD機能は、画面遷移でなくJQueryのモーダルとAjaxを利用しています。

尚、サーバーはさくらレンタルサーバーでphpMyAdminを利用しています。

ディレクトリ、ファイルの現状

これまでに作成してきたファイルのうち、問題の現象に関連すると思われるものは、以下のとおりです。

php

1~ db.php ~ 2 3<?php 4 5$dsn = '(自分のサーバーDSN)'; 6$dbname = '(サーバー名)'; 7$username = '(ユーザ名)'; 8$password = '(パスワード)'; 9$connection = new PDO( 'mysql:host='.$dsn.';dbname='.$dbname, $username, $password ); 10 11?>

php

1~ user_ajax/function.php ~ 2 3<?php 4 5$theme = "閲覧してきた『ググリサイト』一覧"; 6$td = array("ピックアップページ", "関連ページ", "タグ1", "タグ2"); 7 8$table = "webgoogles"; 9$column = array("id", "name", "namesurl", "sight", "url", "tag_1", "tag_2"); 10 11function get_total_all_records(){ 12 include('../db.php'); 13 $statement = $connection->prepare("SELECT * FROM ".$table); 14 $statement->execute(); 15 $result = $statement->fetchAll(); 16 return $statement->rowCount(); 17} 18 19?>

php

1~ user_ajax/index.php ~ 2 3<html> 4<?php 5 include('function.php'); 6?> 7<head> 8 <title></title> 9 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script> 10 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"> 11 <script src="https://cdn.datatables.net/1.10.12/js/jquery.dataTables.min.js"></script> 12 <script src="https://cdn.datatables.net/1.10.12/js/dataTables.bootstrap.min.js"></script> 13 <link rel="stylesheet" href="https://cdn.datatables.net/1.10.12/css/dataTables.bootstrap.min.css"> 14 <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> 15</head> 16 17<body> 18 <input type="hidden" id="theme" value=<?php echo $theme ?>> 19 <div class="container box"> 20 <h1 id="title" align="center">PHP PDO Ajax CRUD with Data Tables and Bootstrap Modals</h1> 21 <br> 22 <div class="table-responsive"> 23 <br> 24 <div align="right"> 25 <button type="button" id="add_button" data-toggle="modal" data-target="#userModal" class="btn btn-info btn-lg">新規追加</button> 26 </div> 27 <br> 28 <br> 29 <table id="user_data" class="table table-bordered table-striped"> 30 <thead> 31 <tr> 32 <th class="nowrap"><?php echo $td[2] ?></th> 33 <th class="nowrap"><?php echo $td[3] ?></th> 34 <th class="nowrap"><?php echo $td[0] ?></th> 35 <th class="nowrap"><?php echo $td[1] ?></th> 36 <th class="nowrap">編集</th> 37 <th class="nowrap">削除</th> 38 </tr> 39 </thead> 40 </table> 41 </div> 42 </div> 43 <div id="userModal" class="modal fade"> 44 <div class="modal-dialog"> 45 <form method="post" id="user_form" enctype="multipart/form-data"> 46 <div class="modal-content"> 47 <div class="modal-header"> 48 <button type="button" class="close" data-dismiss="modal">×</button> 49 <h4 class="modal-title">新規追加</h4> 50 </div> 51 <div class="modal-body"> 52 <label><?php echo $td[0] ?></label> 53 <input type="text" name=<?php echo $column[1] ?> id=<?php echo $column[1] ?> class="form-control" placeholder=<?php echo $td[0]."を入力" ?>> 54 <br> 55 <label><?php echo $td[0]."URL" ?></label> 56 <input type="text" name=<?php echo $column[2] ?> id=<?php echo $column[2] ?> class="form-control" placeholder=<?php echo $td[0]."URLを入力" ?>> 57 <br> 58 <label><?php echo $td[1] ?></label> 59 <input type="text" name=<?php echo $column[3] ?> id=<?php echo $column[3] ?> class="form-control" placeholder=<?php echo $td[1]."を入力" ?>> 60 <br> 61 <label><?php echo $td[1]."URL" ?></label> 62 <input type="text" name=<?php echo $column[4] ?> id=<?php echo $column[4] ?> class="form-control" placeholder=<?php echo $td[1]."URLを入力" ?>> 63 <br> 64 <label>タグ</label> 65 <input type="text" name=<?php echo $column[5] ?> id=<?php echo $column[5] ?> placeholder=<?php echo $td[2] ?>> 66 <input type="text" name=<?php echo $column[6] ?> id=<?php echo $column[6] ?> placeholder=<?php echo $td[3] ?>> 67 <br> 68 </div> 69 <div class="modal-footer"> 70 <input type="hidden" name="user_id" id="user_id"> 71 <input type="hidden" name="operation" id="operation"> 72 <input type="submit" name="action" id="action" class="btn btn-success" value="新規追加"> 73 <button type="button" class="btn btn-default" data-dismiss="modal">閉じる</button> 74 </div> 75 </div> 76 </form> 77 </div> 78</div> 79<script type="text/javascript" language="javascript"> 80 function _(query){ return document.querySelector(query) } 81 82 const theme = _("#theme").value; 83 document.title = theme; 84 _("#title").innerText = theme; 85 86 $('#add_button').click(function(){ 87 $('#user_form')[0].reset(); 88 $('.modal-title').text("新規追加"); 89 $('#action').val("新規追加"); 90 $('#operation').val("Add"); 91 }); 92 93 var dataTable = $('#user_data').DataTable({ 94 "language": { 95 "url": "http://cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/Japanese.json" 96 }, 97 "info": false, 98 "paging:": true, 99 'pagingType': 'full_numbers', 100 "processing": true, 101 "serverSide": true, 102 "lengthMenu": [ 10, 20, 50 ], 103 "order": [], 104 "ajax": { 105 url:"fetch.php", 106 type:"POST" 107 }, 108 "columnDefs": [ 109 { "targets": [0,1], "width": "10%" }, 110 { "targets": [2,3], "width": "30%" }, 111 ] 112 }); 113 114 $(document).on('submit', '#user_form', function(event){ 115  **~ 一覧表示に関するものでない為、文字数の都合で省略 ~** 116 }); 117 118 $(document).on('click', '.update', function(){ 119  **~ 一覧表示に関するものでない為、文字数の都合で省略 ~** 120 }); 121 122 $(document).on('click', '.delete', function(){ 123  **~ 一覧表示に関するものでない為、文字数の都合で省略 ~** 124 }); 125 126</script> 127</body> 128</html>

php

1~ user_ajax/fetch.php ~ 2<?php 3include('../db.php'); 4include('function.php'); 5 6$query = ''; 7$output = array(); 8$query .= "SELECT * FROM ".$table." "; 9 10if(isset($_POST["search"]["value"])){ 11 $query .= 'WHERE '.$column[1].' LIKE "%'.$_POST["search"]["value"].'%" '; 12 $query .= 'OR '.$column[3].' LIKE "%'.$_POST["search"]["value"].'%" '; 13} 14if(isset($_POST["order"])){ 15 $query .= 'ORDER BY '.$_POST['order']['0']['column'].' '.$_POST['order']['0']['dir'].' '; 16}else{ 17 $query .= 'ORDER BY id DESC '; 18} 19if($_POST["length"] != -1){ 20 $query .= 'LIMIT ' . $_POST['start'] . ', ' . $_POST['length']; 21} 22$statement = $connection->prepare($query); 23$statement->execute(); 24$result = $statement->fetchAll(); 25$data = array(); 26$filtered_rows = $statement->rowCount(); 27foreach($result as $row){ 28 $sub_array = array(); 29 if(mb_strlen($row[$column[1]])>25){ 30 $row[$column[1]] = mb_substr($row[$column[1]], 0, 25)." ..."; 31 } 32 if(mb_strlen($row[$column[3]])>25){ 33 $row[$column[3]] = mb_substr($row[$column[3]], 0, 25)." ..."; 34 } 35 $sub_array[] = $row[$column[5]]; 36 $sub_array[] = $row[$column[6]]; 37 $sub_array[] = '<a href="'.$row[$column[2]].'" target="_blank" onClick="return confirm(\'このサイトに移動しますか?\')" class="deco-none">' 38 .'<span class="nowrap">'.$row[$column[1]].'</span></a>'; 39 $sub_array[] = '<a href="'.$row[$column[4]].'" target="_blank" onClick="return confirm(\'このサイトに移動しますか?\')" class="deco-none">' 40 .'<span class="nowrap">'.$row[$column[3]].'</span></a>'; 41 $sub_array[] = '<button type="button" name="update" id="'.$row["id"].'" class="btn btn-warning btn-xs update">編集</button>'; 42 $sub_array[] = '<button type="button" name="delete" id="'.$row["id"].'" class="btn btn-danger btn-xs delete">削除</button>'; 43 $data[] = $sub_array; 44} 45$output = array( 46 "draw" => intval($_POST["draw"]), 47 "recordsTotal" => $filtered_rows, 48 "recordsFiltered" => get_total_all_records(), 49 "data" => $data 50); 51echo json_encode($output); 52?>

(字数の関係でuser_ajax/fetch_single.phpとuser_ajax/delete.phpは省略)

DBからのフェッチによる一覧表示もCRUDに関わる機能も、一通り動くことを確認できています。

Datatablesの機能としては、検索機能、列の幅、ソート、件数選択などの、ページング以外の一通りの機能は画面内に表示されて動くことを確認できています。

###困りごと

問題のページングボタンは、表示自体はされているのですが、何故か押して表示を切り替えようとしても禁止マークが出て押すことができません(添付画像のとおりです)。
index.php表示時

この状態が作成後から依然として続いております。

###試みたこと

  • こちらのサイト を参考にして、JQueryとBootstrapのバージョンをそれぞれ3と4変更してアップし直したのですが、状況は変わりませんでした。
  • index.phpのDatatablesで、pagingTypeを「full_number」以外のものに変更してみても、表示されるページングボタンの種類が変わるだけで、押せないことに変わりありませんでした。
  • index.htmlのヘッダースタイルタグ内に「cursor: pointer」を記述してみましたが、これでも押下後に何も変化はありませんでした。

果たして、どのファイルにどのような記述を施せば、このエラーは解消されるのか、もはや皆目見当がつかず埒が明かない状況が続いてしまっています。

至らぬ事が多く、お目汚し申し訳ございませんが、この点についてご存じの方がいらっしゃいましたら、どうかご回答をお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cerfweb

2021/12/07 15:59

データは何件中20件の表示となっていますか。オプションのinfoをtrueにして確認していただけますか。
Nishin

2021/12/08 00:14

ご返答ありがとうございます。 先程レンタルサーバーに収めているindex.phpのdatatables部分を編集して確認したところ、テーブルの左下にこう表示されておりました。 「Showing 0 to 0 of 0 entries (filtered from 10 total entries)」 データ自体はこれまでに75件程登録している筈なのですが、そうなるとサーバーの情報を、何故だかdatatablesがうまくキャッチ出来ていない、という事なのでしょうか ...
cerfweb

2021/12/08 08:27

提示されているスクリーンショットでは20件表示されていますが、何件のうち20件かわかりますか。
Nishin

2021/12/08 09:37

75件中の20件です。 宜しければ、phpMyAdminのMySQLでの表示内容をスクショしたものか、レコードをJSON形式でエクスポートしたものをお見せすることもできます。
cerfweb

2021/12/08 09:45

データベースに入っているデータではなく、テーブルに読み込まれているデータです。オプションのinfoをtrueにすれば表示されると思いますが。
Nishin

2021/12/08 11:17

info: trueとして画面を更新したところ、テーブル(20件/頁の設定で、レコード75件分のうち20件が表示されている)左下には「「Showing 0 to 0 of 0 entries (filtered from 20 total entries)」」とありました。 「困りごと」に挙げた画面の画像のとおりテーブルが表示されている左下に、このようなメッセージが表示されている格好です。
guest

回答2

0

ご指摘頂いた「"recordsTotal"と"recordsFiltered"の記述が逆」のメッセージが契機となり、次のようにコードを修正したところ解決しました。

PHP

1<?php 2// ~ user_ajax/fetch.php ~ 3 4$theme = "閲覧してきた『ググリサイト』一覧"; 5$td = array("ピックアップページ", "関連ページ", "タグ1", "タグ2"); 6 7$table = "webgoogles"; 8$column = array("id", "name", "namesurl", "sight", "url", "tag_1", "tag_2"); 9 10function get_total_all_records($target){ 11 include('../db.php'); 12 13 $statement = $connection->prepare("SELECT * FROM ".$target.";"); 14 $statement->execute(); 15 $result = $statement->fetchAll(); 16// ↓修正箇所 17 $countQuery = "SELECT COUNT(id) FROM ".$target." "; 18 $countStatement = $connection->prepare($countQuery); 19 $countStatement->execute(); 20 $countResult = $countStatement->fetch(); 21 22 return $countResult[0]; 23// ↑修正箇所 24} 25

PHP

1// ~ user_ajax/fetch.php ~ 2 3<?php 4include('../db.php'); 5include('function.php'); 6 7$query = ''; 8$output = array(); 9$query .= "SELECT * FROM ".$table." "; 10 11if(isset($_POST["search"]["value"])){ 12 $query .= 'WHERE '.$column[1].' LIKE "%'.$_POST["search"]["value"].'%" '; 13 $query .= 'OR '.$column[3].' LIKE "%'.$_POST["search"]["value"].'%" '; 14} 15if(isset($_POST["order"])){ 16 $query .= 'ORDER BY '.$_POST['order']['0']['column'].' '.$_POST['order']['0']['dir'].' '; 17}else{ 18 $query .= 'ORDER BY id DESC '; 19} 20if($_POST["length"] != -1){ 21 $query .= 'LIMIT ' . $_POST['start'] . ', ' . $_POST['length']; 22} 23 24$statement = $connection->prepare($query); 25$statement->execute(); 26$result = $statement->fetchAll(); 27$data = array(); 28 29foreach($result as $row){ 30 $sub_array = array(); 31 if(mb_strlen($row[$column[1]])>25){ 32 $row[$column[1]] = mb_substr($row[$column[1]], 0, 25)." ..."; 33 } 34 if(mb_strlen($row[$column[3]])>25){ 35 $row[$column[3]] = mb_substr($row[$column[3]], 0, 25)." ..."; 36 } 37 $sub_array[] = $row[$column[5]]; 38 $sub_array[] = $row[$column[6]]; 39 $sub_array[] = '<a href="'.$row[$column[2]].'" target="_blank" onClick="return confirm(\'このサイトに移動しますか?\')" class="deco-none">' 40 .'<span class="nowrap">'.$row[$column[1]].'</span></a>'; 41 $sub_array[] = '<a href="'.$row[$column[4]].'" target="_blank" onClick="return confirm(\'このサイトに移動しますか?\')" class="deco-none">' 42 .'<span class="nowrap">'.$row[$column[3]].'</span></a>'; 43 $sub_array[] = '<button type="button" name="update" id="'.$row["id"].'" class="btn btn-warning btn-xs update">編集</button>'; 44 $sub_array[] = '<button type="button" name="delete" id="'.$row["id"].'" class="btn btn-danger btn-xs delete">削除</button>'; 45 $data[] = $sub_array; 46} 47// ↓修正箇所 48$output = array( 49 "draw" => intval($_POST["draw"]), 50 "recordsTotal" => get_total_all_records($table), 51 "recordsFiltered" => get_total_all_records($table), 52 "data" => $data 53); 54// ↑修正箇所 55echo json_encode($output); 56

主に、テーブル内のレコード数を取得してくる関数の記述を修正しています。
余計なコード記述もまだあるかと思われますが、これで下の画像のとおり修正されたので安心しました。
あとはログインセッションとの連携とセキュリティ強化関係の機能を盛り込んでいくようにします。

functionとfetch修正後

投稿2021/12/10 02:57

Nishin

総合スコア30

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

skys215

2021/12/10 03:08

"recordsFiltered" => get_total_all_records($table), recordsFilteredは絞り込んだ後の数です。絞り込んてない数を表示すると、最後のページのはずなのに、まだ「次」ボタンが表示される事になると思います。 例えば、75項目あって、絞り込んだ後は35項目。1ページに20項目を表示するとしたら、2ページしかないはずなのに、recordsFilteredは75なので4ページまでボタンが表示されると思います。
guest

0

ベストアンサー

ここ

PHP

1 "recordsTotal" => $filtered_rows, 2 "recordsFiltered" => get_total_all_records(),

が逆だと思います。

PHP

1 "recordsTotal" => get_total_all_records(), 2 "recordsFiltered" => $filtered_rows,

投稿2021/12/09 01:48

skys215

総合スコア910

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Nishin

2021/12/09 05:21

ご回答ありがとうございます。 ご教示頂いたとおりに、該当する「fetch.php」の記述を編集したのですが、依然として問題は解消されておらず、現在もinfoをtrueにしたところ「records total: 0」と出続けております...
Nishin

2021/12/09 05:51

その後行数取得関係で多々調べてみたのですが、どうやら$filtered_rows($statement->rowCount())を使ってDB内のレコードの件数をうまく取得できていないのが原因らしく、この値を現在テーブル内に登録されている数値の75に書き換えて更新した途端に、ページネーションのボタンが動いてくれるようになりました。 その為、今度は「$statement->rowCount()」を修正して変数に格納したものかそれに代わるものを当てはめなければならず、これにハマってます... (COUNT(*)を使ったクエリ文を当てはめるとかできないでしょうか...)
skys215

2021/12/09 07:32

function get_total_all_records(){ include('../db.php'); $statement = $connection->prepare("SELECT count(id) FROM ".$table); $statement->execute(); ... } count(id) にしてデータベース側で数えたほうがいいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問