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>

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()
                }

              })