自分の型を作り、それにこだわり続けること。あきらめずに自分を変えないで頑張っていると、ちゃんとだれかが見てくれているもんなんです。
投稿者: Hisa
本当にあったこと
本当にあったことが一番おもしろい
Tabulator5.6 RangeSelect を使ってExcelのようなことをする
T
abbulatorのドキュメントを見てたところ、Ver5.6にアップデートされてるのがわかり、有償のテーブルでしか出来なかったExcelのようなレンジセレクトができることがわかり、早速使ってみました。
ドキュメントはこちらにあります。
< コード例 >
イベントも沢山あっていろいろカスタマイズできるようですが、とりあえずは以下のようなプロパティを追加すれば動きました。
// ++ Tabulator ++ //
const table = new Tabulator("#table_" + this.tp, {
selectableRange: true,
selectableRangeColumns: true,
selectableRangeRows: true,
clipboardCopyRowRange:"range", //change default selector to selected
< 画面例 >
Shift, Ctrl も使えます。
Ctrl + C でクリップボードに選んだセルがコピー出来ました。
矩形選択
Ctrl + Cの後のクリップボードを貼り付けてみる
左端の行から選ぶと行選択になります
こんなことも出来ました。
フレームワークなしのPHPでURLから .php をなくす
個人開発なので、PHPはフレームワークを使ってません。
最近はほとんどのサイトでPHPの拡張子がURLから見えないので、多分フレームワークのルーティングで隠蔽してるからと思います。
.phpが見えてしまうのはよろしくない気がして、WordPressのURL表示を真似して試してみたところ出来ました。
< コード >
Apacheのhttpd.conf
# # DirectoryIndex: sets the file that Apache will serve if a directory # is requested. # <IfModule dir_module> DirectoryIndex index.html index.php </IfModule>
index.phpでインクルード
<?php
/**
* ルーティング
* .php を隠す為、メニューリンクからのリクエストはここを通る
*
* First create : 2024-02-09
* Last update :
*
*/
ini_set('display_errors', 0);
date_default_timezone_set('Asia/Tokyo');
// == リクエストパラメータ取得 == //
$pg = $_POST["pg"] ? $_POST["pg"] : $_GET["pg"];
if (!$pg) {
include "./photo.php";
}
else {
include "./".$pg.".php";
}
Bootstrap ナビゲーションバー
<li class="nav-item" id="nav_photo">
<a id="navlink_photo" class="nav-link tippyspan" href="./?pg=photo" target="_blank" title="写真集">写真集</a>
</li>
<li class="nav-item" id="nav_mailconfig">
<a id="navlink_mailconfig" class="nav-link tippyspan" href="./?pg=mailconfig" target="_blank" title="メール配信設定">メール配信</a>
</li>
VirtualBoxにAlma9がKernel panicでインストール出来ない問題の解消
開発環境がWindowsでSMTPのメール配信のテストが出来ず、VirtualBoxに入れたCentOS8 Streamを使ってましたが、Alma9も入れようとしたところエラーなのでしばらく悩んでましたところ、解決しました。
ここで教えていただきました。
PHP8 match を使う
PHPで条件分岐する場合、if then else, switch 三項演算子などを使ってましたが、8系に上げたのでmatchを使ってみました。
コードが短くわかりやすくなったのと、一致しない場合エラーになるのでミスが防げるのがメリットかと思います。
< コード例 >
リクエストパラメータの検索種別に応じたSQLをセット
// == リクエストパラメータ == //
$stdt = $_POST["stdt"] ? $_POST["stdt"] : $_GET["stdt"];
$endt = $_POST["endt"] ? $_POST["endt"] : $_GET["endt"];
$tp = $_POST["tp"] ? $_POST["tp"] : $_GET["tp"];
// Ver8.0以上 //
// SQL //
$sql = match ($tp) {
"PSPO" => SQLStc::$SQL_PSPO,
"SCP" => SQLStc::$SQL_SCP,
"MAIL" => SQLStc::$SQL_MAIL,
"PF" => SQLStc::$SQL_PF,
"TABLE" => SQLStc::$SQL_TABLE,
"SCHEMA" => SQLStc::$SQL_SCHEMA,
"OSINFO" => SQLStc::$SQL_OSINFO,
"BLFTML" => SQLStc::$SQL_BLFTML,
"DDAD" => SQLStc::$SQL_DDADHIST,
"SCPTBL" => SQLStc::$SQL_SCPTBL,
"SCPTGT" => SQLStc::$SQL_SCPTGT,
"MAILCHECK" => SQLStc::$SQL_MAILCHECK,
"BOOK" => SQLStc::$SQL_BOOK,
"DDADAPSTATS"=> SQLStc::$SQL_DDADAPSTATS,
"DDADOPESTATS"=> SQLStc::$SQL_DDADOPESTATS,
"MYSQLPS" => SQLStc::$SQL_MYSQLPS,
"HTTPDPS" => SQLStc::$SQL_HTTPDPS,
"PHPFPMPS" => SQLStc::$SQL_PHPFPMPS,
"TOMCATPS" => SQLStc::$SQL_TOMCATPS,
"AMPTPS" => SQLStc::$SQL_AMPTPS
};
SQL文クラスにstaticな変数で各設定
class SQLStc {
//const SQL_PSPO_CS = "";
// phpoto data //
public static $SQL_PSPO = <<<EOM
SELECT
ID, CNT_PS, CNT_PS_NOIMG, CNT_OS_ALL, CNT_OS_TGT,
LEFT(TM_ADD, 16) AS TM_ADD
FROM
log_photo_count lp
WHERE
DATE(TM_ADD) BETWEEN :STDT AND :ENDT
ORDER BY ID DESC
EOM;
## 以下省略 ##
Tabulator 通し行番号取得
TabulatorのFormatterのrownumで行番号が取得できますが、ページを変えると1に戻ってしまうので自作してみました。
< コード例 >
Formatter
// 行番号 //
{
// 各表の //
title: "No.",
field: "__",
//frozen: true,
width: 16,
hozAlign: "right",
cssClass: "cell_num",
//formatter: "rownum",
formatter: function (cell, formatterParams, onRendered) {
// 反転させて強調 //
const cellelm = cell.getElement()
$(cellelm).on("mouseover", function (e) {
$(this).addClass("text_reverse")
})
$(cellelm).on("mouseout", function (e) {
$(this).removeClass("text_reverse")
})
// 通し行番号 //
return new TableUtil().getRowNum(cell)
},
テーブルユーティリティクラス
class TableUtil {
// クリップボード設定 //
static
clipboardCopyConfig = {
columnHeaders: true, //do not include column headers in clipboard output
columnGroups: false, //do not include column groups in column headers for printed table
rowGroups: false, //do not include row groups in clipboard output
columnCalcs: true, //do not include column calculation rows in clipboard output
dataTree: false, //do not include data tree in printed table
formatCells: false //show raw cell values without formatter
}
/**
* コンストラクタ
* @returns {TableUtil}
*/
constructor() {
}
/**
* 通し行番取得
* @param {type} cell
* @returns {Number}
*/
getRowNum(cell) {
const tbl = cell.getTable()
const page = tbl.getPage()
const pageSize = tbl.getPageSize()
//console.log("# page # " + page + ":" + pageSize)
let num = (page - 1) * pageSize
num += cell.getRow().getPosition(true)
return num
}
Javascript Fetch API を使う (ファイルアップロードとPOST)
< コード例 >
HTML
<form id="photoupload_uploadform" enctype=”multipart/form-data”>
<table>
<tr>
<td valign="top" class="td_title">Book ID</td>
<td valign="top" class="td_input"><span id="photoupload_bookid"></td>
</tr>
<!--
<tr>
<td valign="top" class="td_title">Dep date</td>
<td valign="top" class="td_input"><input id="photoinp_depdate" type="text" size="10" max="10" value=""></td>
</tr>
<tr>
<td valign="top" class="td_title">Flight No.</td>
<td valign="top" class="td_input"><input id="photoinp_flnum" type="text" size=12" max="12" value=""></td>
</td>
</tr>
-->
<tr>
<td valign="top" class="td_title">Reg No.</td>
<td valign="top" class="td_input"><input id="photoinp_regno" type="text" size="12" max="12" value=""></td>
</tr>
<tr>
<td valign="top" class="td_title">Airport</td>
<td valign="top" class="td_input">
<select id="photoupload_iatasel">
<option id="iatasel_from" value="from" selected></option>
<option id="iatasel_to" value="to"></option>
</select>
<span id="selapname" class="ml-1">..</span>
</td>
</tr>
<tr>
<td valign="top" class="td_title">Publish</td>
<td valign="top" class="td_input">
<select id="photoupload_publishsel">
<option value="yes" selected>Yes</option>
<option value="no">No</option>
</select>
</td>
</td>
</tr>
<tr>
<td valign="top" class="td_title">Select</td>
<td class="td_input" valign="top">
<input id="photoupload_fileinput" type="file" accept="image/*" id="userfile" name="userfile">
</td>
</tr>
</table>
</form>
Javascript
// ここに確認を入れる //
$("#marker_loading_booklist").removeClass("dsp_none")
$("#marker_loading_booklist").show()
// フォームの値を連想配列に入れる //
const array = {
userid: userid,
bookid: $("#photoupload_bookid").text(),
depdate: $("#photoinp_depdate").val(),
flnum: $("#photoinp_flnum").val(),
regno: $("#photoinp_regno").val(),
airport: $("#photoupload_iatasel").val(),
publish: $("#photoupload_publishsel").val()
}
const fd = new FormData($('#photoupload_uploadform').get(0));
fd.append('json', JSON.stringify(array));
// Fetch API //
fetch("upload/UploadAPhoto.php",
{
method: "POST", body: fd
}
)
// ** 応答時 ** //
.then((data) => data.text())
// ** 応答後 ** //
.then((res) => {
$("#marker_loading_booklist").addClass("dsp_none")
$("#marker_loading_booklist").hide()
const array = JSON.parse(res)
// 正常完了の場合 //
if (array["result"] === "Success") {
toastr.success("Photo upload was completed")
}
// エラーの場合 //
else {
toastr.error("Photo upload was FAILED.")
}
// 写真表示更新 //
new BookListUserPhoto(rowdataThis).showPhoto()
})
})
Javascript Fetch API を使う (POST)
最近使い始めた Fetch APIでPOSTを試してみました。
< コード例 >
HTML
<!-- 検索条件メニュー -->
<div id="menudiv" class="container float-left ml-0 badge-dark rounded">
<form id="formdiv" class="form-inline form-group ml-0 mr-1 mt-1 mb-1 p-1">
<!-- 日付範囲選択 -->
<div class="pl-0 pr-1"></div>
<input type="text" id="mindtinput" value="" size="10" class="mr-1 form-control" />
~
<input type="text" id="maxdtinput" value="" size="10" class="ml-1 mr-1 form-control" />
<!-- 検索ボタン -->
<button id="search_button" type="button"
class="btn btn-primary ml-1 config_button tippyspan"
data-toggle="tooltip" data-placement="bottom"
title="Execute search">
<i class="fa fa-search"></i></button>
<!-- ページネーション -->
<div id="top_pagenator" class="ml-2 mt-0 pt-0">
<span id="topp_first" class="mr-1 curpo topps tippyspan" title="Move to first page"><i class="fa fa-angle-double-left"></i></span>
<span id="topp_prev" class="mr-1 curpo topps tippyspan" title="Move to previous page"><i class="fa fa-angle-left"></i></span>
<span id="topp_next" class="mr-1 curpo topps tippyspan" title="Move to next page"><i class="fa fa-angle-right"></i></span>
<span id="topp_last" class="mr-1 curpo topps tippyspan" title="Move to last page"><i class="fa fa-angle-double-right"></i></span>
<span id="topp_position" class=""></span>
</div>
<span id="reccnt" class="ml-3 mr-1"></span> Records
</form>
</div>
Javascript
// moment.jsで前日を取得 //
const mm = moment()
mm.add(BFCNT[tpThis] * -1, "day")
const mindt = mm.format('YYYY-MM-DD')
// inutに日付をセット //
$("#mindtinput").val(mindt)
$("#maxdtinput").val(TODAY_FORMAT)
// フォームデータを作成 //
const fd = new FormData();
fd.set('tp', tpThis);
fd.set('stdt', mindt);
fd.set('endt', TODAY_FORMAT);
// Fetch API //
fetch("include/SelectLogStc.php",
{
method: "POST", body: fd
}
)
// ** 応答時 ** //
.then((data) => data.text())
// ** 応答後 ** //
.then((res) => {
// JSON文字列を配列にする //
const data = JSON.parse(res)
console.log("-- data")
console.log(data)
// ** 応答後の処理をここに書く ** //
})
< 画面例 >
Fetch APIでリクエストした応答結果をTabulatorのテーブルで表示
Javascript Fetch API を使う (GET)
最近使い始めました。
最近まで、JQueryのAjaxから自サイトのPHPにリクエストして取得するのが普通でしたが、APIにキーが必要ない場合、隠蔽するものがないので、PHPを介する必要なしなので便利で少ないコードで済むのがメリットかと思います。
次はPOSTを試してみます。
< コード例 >
// PlaneSpotter写真問い合わせ //
const url = "https://api.planespotters.net/pub/photos/hex/" + acmodeS
// fetch API //
fetch(url)
.then((data) => data.text())
.then((res) => {
console.log("-- PLANESPOTTERS")
console.log(res)
// 取得出来たら写真を表示 //
if (res) {
const array = JSON.parse(res)["photos"][0]
$("#photo_bookside_img").attr("src", array["thumbnail_large"]["src"])
$("#photo_bookside_a").attr("href", array["link"])
$("#photo_bookside_figcap").text("@ " + array["photographer"])
$("#photo_bookside").show()
}
else {
$("#photo_bookside").hide()
}
})
コメントを投稿するにはログインしてください。