【最新記事】⇒仮公開開始(2019/02/07)

簡易表示画面がほぼ決まった

まず、タスク管理(プロジェクト管理)は、UpStreamというプラグインで管理する事にした。チャート表示とかカレンダー表示とかは、どうやら有料のようだけど、タスクの管理だけなら無料で使えるし、これでひとまずやっていこう。

CollabPressは古いせいか、使うとTwenty-SeventeenのCSSへ干渉を起こしてしまうようだったので使うのをやめた。まぁ6年も更新してない奴を使う事はないよね。

さて、タスクの管理ができたところで簡易画面の作成に取り掛かった。前回までで、流れとしては確認できていたので、データの受け渡しや表示内容について再検討を行った感じになる。

データの持ち回り方法は、暫定ながらメモリ上で行う事にした。検索結果が増えたりした場合、DOMがどれくらい消費されるのか…などは、注意が必要だろう。

また、表示項目に関しては極力ショートコードを使って、画面表示段階で終らせるようにしている。現状表示に関して簡易表示画面でJavaScriptを使っての実装は無い。ショートコードの範囲指定や、ショートコードの入れ子などをうまく使って、検索結果などの条件で表示したいエリアの切り替えなどもできているし、方針としてはこれでOKだろうと思う。

細かいデザインは後回しにして、取りあえず必要な情報が全て表示できるか(「簡易」の名に相応しい程度で)については、もう少し詰める必要があるだろう。

このまま詳細表示画面も進めていきたい所。簡易表示の状態でも、テーブルのデータの持ち方などは結構考慮が必要だったし、カラムの使途なども見直しがでてきた。詳細表示になればそのあたりも増えそうだし、やはりデータ入力よりも優先して行わないといけないだろう。

現状は、プログラムで頑張るより、テーブル上のデータを増やすという方針になっているが、これでいいのかはまた考えなくてはならないだろう。ともあれ、今日はそこそこ順調だった。

CollabPress導入完了

昨日ブログで一覧にした、やり残し項目を、CollabPressを導入して、タスクとして入力完了した。今後はCollabPressを使って完成までを管理していきたいと思う。

ただ、ガントチャート的なものもないし、優先度や期限などは後から修正できないなど、色々と不便な部分もあるので、その辺りは臨機応変に運用していこう。まぁ備忘録程度と思っておけばいいかな。

やりたいと思った事をブログに書いても忘れてしまう可能性もあるので、思いついた事はCollabPressにタスクとして何でも登録し、後から分類してやらなくていいものはやめるなどの判断をすればいい。

今日はプログラムは何も進まずに終わってしまったな…。明日はもうちょっと手を動かしたいね。

やり残している事(2018/12/22)

結構色々とやってきているのだが、やり残している事も多い。忘れないよう、今のうちに列挙しておいた方がいいかもしれない。

  • トップ画面に表示している画像の変更
  • そもそもtwenty-seventeenでいいのか?
  • Google Adsenseの自動広告が大きすぎる
  • functions.phpの処理の絞込み(page.phpへ移動)
  • 各固定ページに直接記述しているJSの外部ファイル化
  • サニタイジングなどの処理
  • PHPと画面側でシェイクハンド(認証?)の必要性
  • 一覧画面(テーブル)のスクロール処理
  • 一覧画面の表示方法(一行おきに色を変える等)
  • ポップアップウィンドウの「×」ボタンがスマホで表示されない
  • ボタンを<button>にするのか<input type=”button”>にするのか
  • 検索画面の英語化(そもそもローカライズってどうするの?)
  • 管理用項目(最大検索数など)の検討
  • 管理用項目の保持方法(DB?ファイル?)
  • 選択行をJSのグローバル変数で保持している事の妥当性
  • 英語データが無い(所持してないキャラ)場合の処理
  • 限定公開する場合、ユーザー登録させるか否か
  • キャラの対象範囲をどこまでにするのか(SSR,SR,R)
  • 召喚石を含めるかどうか
  • ジョブの表示方法の検討
  • キャラ等の画像の利用について
  • データ入力どこまで頑張れるかw

ざっと考えてみただけでまだまだこんなにやる事積み上がってしまった。やっぱり全部一人でやろうとすると、それだけ時間もかかるよね。でも一つずつやらないとな。進捗管理用のツールみたいなもの、インストールしたりできないのかな。既にあるのかな?WordPress使ってそういう事できたりするのかな?又調べてみよう。

大きな流れが完成した!

ひとまず、想定していた

検索→結果一覧→行選択でポップアップ→簡易/詳細表示の選択→それぞれの画面表示→選択した行のデータ表示

という一連の流れが全て確認できた。想定していた動作が全て実現できたという事では無いけれど、後はできている事を元に肉付けしていけば、全体的な完成度が高まるはずだ。

ポップアップウィンドウで次に進む画面を選択したら、hidden設定にしてあるフィールドに選択された行のIDをセットし、次に表示する画面をactionで指定しsubmit()するという手順を踏んだ。次に表示する画面も、WordPressの固定ページとして作成してある。

jQuery(function($) {
var view_id = document.getElementById( "view_id" ) ;
view_id.value = selected_id ;
$("#view_form").attr( "action", "/viewpage/" ) ;
$("#view_form").submit() ;
$("#mydialog").dialog( "close" ) ;
}) ;

ポップアップウィンドウ上のボタンが押下された場合の処理(抜粋)は概ね上記のようにしてある。”view_id”というのがhiddenにしてあるformの要素で、そこに選択されたIDをセットした上で、formをsubmitしている。actionとして作成してある固定ページを指定している。ちなみに、form上にはtarget句で「_blank」を指定しているので、常に新しいタブが開くようになっている。

固定ページ側では$_POSTグローバル変数から値を取得する事ができるようになったので、今後渡したいパラメータが増えた場合にはhidden属性のパラメータを増やす事で対応が可能になる。固定ページの表示が完了するまでは、同一プロセスで動作するようなので、$_POSTグローバル変数だけでなく、ショートコード間でデータを共有する事が可能なようだ。

そこで、簡易画面側で、実際にSQLを発行してDBから詳細データを取得して見る事にした。結果は勿論良好♪想定したデータがちゃんと流れに沿って取り出され表示される事を確認した。

取り出したデータは、JavaScript側にJSON形式で返して固定ページのJavaScriptで個々のフィールドへ設定しようかとも考えたのだが、今回はサーバー側のコストを使ってみようと思う。つまり、一回SQLを発行するショートコードを冒頭で呼び出し、ショートコード内で取り出したデータをグローバル変数に保存。そして、画面側はショートコードをその都度呼び出して必要なデータを取り込み、表示するというもの。

現状では、取り出す項目毎にショートコードを作っているのだが、確かショートコードには引数を渡せるはずだったので、取り出したい項目名を指定しデータを返却するような汎用的なショートコードを作った方が良さそうな気がする。

実際、この方法でデータを増やしたりして試して、あまりにもサーバーに負荷がかかりすぎるようなら、JSON形式で返却し、JS側(つまり端末側)で処理する方法に切り替える必要があるかもしれない。この辺りの負荷などが、現状全く読めていないのは問題な気がする。自前サーバーならともかく、レンタルサーバーだからその辺りは慎重にやらないといけないだろう。

とは言え、これで取りあえず全体的な流れが確認できたので、後は各画面に必要なデータがテーブル上に揃っているのか、それをちゃんと取り出して表示させられるのか等の確認をする事ができるようになった。取りあえずは機械的に必要な項目を全てSELECTして画面上に表示させられるようにしてみよう。

各画面のレイアウトは、表示させる部分をショートコードにしているが、span等をうまく使って色や大きさ、配置などを後からCSSで設定できるようにしておく必要があるだろう。そういう部分は不得手なので苦労するだろうが、まぁ何とかなるだろう。

そういえば、WordPressのGutenbergで固定ページも編集しているのだが、spanタグを表示文字列の部分に「コードエディタ」で挿入しようとしたのだが、保存しようとするとspanタグが綺麗に削除されてしまうという現象にでくわした。結論から言うとdivタグで挟んでいなかった為なのだろう。編集エリア内のpタグの親にdivタグを記述する事で、spanタグはきちんと保存されるようになった。spanタグはdivの子要素になってないといけないとかの制約があったかもしれない。

spanをマメに指定する事で、その部分のCSSも自在に設定できる(と思いたいw)ので、spanが保存されないと困ってしまうw

次は、簡易画面に表示させる項目の検討と、詳細画面に表示させる項目の検討。及びそれらを実際に検索して表示させる部分の作りこみを頑張ろう。そこで現状のテーブルに必要十分なカラムが用意されているかどうかがわかるだろう。念のため、英語画面も用意しておくほうがいいのかもしれない。

画面表示に関しては2~3日かかるかもしれないが、大事な所なのでじっくり確実にやりたいと思う。

また一つ覚えた!

検索結果から遷移する画面を、又固定ページで作ろうとしたのだけど、固定ページ個別に読み込まれるpage.phpというものが作れるという事を知った。具体的には「page-スラッグ.php」を、子テーマのフォルダ内に作って入れておくだけ。元になるpage.phpは、親テーマフォルダ直下にあるので、そこからダウンロードし、名前を変更して子テーマのフォルダへアップロードすればいい。

page-スラッグ.phpは、page.phpより優先して呼ばれるようなので、今回簡易表示、詳細表示の二つの画面を作ろうと思っていたけれど、それぞれ別のphpを用意すれば良さそうだ。

今回の画面作成にあたり、functions.phpに検索用のあらゆる記述を仕込んでしまっているのだけれど、本来ならこれはこのpage-スラッグ.phpに記述すべきものなのではないだろうか。子テーマ全体で使う処理はfunctions.phpで、固定ページ個別で使う処理はpage-スラッグ.phpに記述するのが素直な気がする。

詳細(簡易)表示ページでも、SELECT文使ってDBにアクセスしなくてはならないし、詳細表示ページの処理はpage-スラッグ.phpの方に実装していってみよう。functions.php、header.php、footer.php、page-スラッグ.phpの呼び出し関係などがどうなっているのかは、出力された画面のソースとかである程度認識できそうだし。

そして、画面遷移時に色々と情報を受け渡そうと思っていたのだけれど、ひょっとして、「カスタムフィールド」とか使えないだろうか。複数の固定ページで同じ名前のカスタムフィールドを設定したらどうなってしまうのかまだ不明だけど、プログラム側からアクセスできるフィールドのようだし、必要な情報をここに格納するようにすればページ間でデータを受け渡せるかもしれない。こちらも調べてみよう。

だが取りあえずは、GETでID受け渡す形式で一連の流れを作ってみよう。

デザインに嵌まると地獄

今日はずーっとダイアログのデザインだけに終始してしまった。

デザインというよりは、結局CSSについてのお勉強という感じではあったんだけどね。ダイアログに色々と見た目上の変更を加えたかったので、CSSに色々設定してみたものの、うまく反映されずに時間ばかり経過した…というのが実状。

まず、どう反映されているのか…を確認する為に、ChromeのDevToolsを活用させて頂いた。キーボードでPF12を押下する事で表示させられるが、Chromeメニューのその他のツールの中からも表示させられる。けど、もっぱら該当画面でPF12で表示させる方が簡単だしそうしてる。

そして、該当する項目(段落やボタンなど)を指定して、そこに設定されているスタイルを確認していたのだが、どうにも自分の設定したCSSが反映されてくれない。クラス指定やID指定、その他諸々試してみたもののダメ。何が悪いかわからず、お手上げとなった時に、そういやキャッシュがどうとかと書いてあるサイトもあったな…と思い出す。

常にリロードしてるんだし、それがそこまで影響するもんじゃ無いだろうと頭から除外していたのだけれど、DevToolsを開いている時だけ有効になる、スーパーリロードというものがある事を思い出した。

DevToolsを開いている時に、Chromeの更新ボタンを長押ししていると、メニューが表示されるので、そこからやりたいリロードを選ぶ事ができる。キャッシュ全クリアとかは恐らく必要ないので、2番目の「ハード再読み込み」という奴を選択する。

ちなみに、それが可能なのはDevToolsを開いたタブのみであり、仮にDevToolsが開いていたとしても、関係ないタブでは働かない機能なので注意したい。そしてここまで書いて思ったのだが、ひょっとしたらShift+F5でもCSSの再読み込みだけなら十分だったかもしれない。(試してみると大丈夫だったwうぉいっw)

というわけで、次からCSS(style.css)を触った場合には、Shift+F5で再読み込みを実施して、それでもうまく反映されなかったら、ハードリロードを試してみる事にする。くっそw

無事CSSが反映されるようになったので、そこからは順調にダイアログの調整もできたのだが、色の反映などがやっぱりうまくいかない。そこでDevToolsで確認してみると、どうやらstyle.cssの後に、テーマのカスタマイズ(20-17のcolors-dark)用のCSSが後から読み込まれ、それで指定したスタイルが上書きされている事が判明。

色々調べてみたが、クラス指定ではどうしてもその優先度を覆せなかった。かといって!importantはあまり使いたくなかったので、ID指定で試して見た所うまく行くようになった。前々回の投稿で、前半CSSの設定がうまく反映されないという事を書いていたのだが、ひょっとしてと思い、そちらもID指定にしたところうまく反映されるようになった。まぁピンポイントで、そこの項目にのみ反映させたいものだったし、これで解決という事にした。

しかし試練は続く。今度はダイアログ中のPタグの下部にある余白がどうにもうざく(文字列とボタンの間が不必要にあいてしまう)、どうにかできないかとPタグに対し、クラスやらIDやら色々セレクタをいじってみたのだが、結局他の外部CSSに優先度的に勝てなかった。仕方が無いので、style句で直接指定する事にして目的通りの表示が得られるようになった。

教訓としては、ピンポイントでそこにしか影響しないスタイルの場合は、下手にstyle.css等の外部CSSに記述するのではなく、差分のみを直接style句で指定するのが一番良さそうだ。すべての外部CSSの読み込み順などを制御できるなら別だけど、そうでないのならそっちの方が結局わかりやすくていいだろう。もう少し広範で影響ありそうなものは、style.cssに書くべきだろうけれど、何やっても優先度で勝てないなら、!importantを使うよりはstyle句を使う方が多分いい。

そんなこんなで、ダイアログは落ち着いた(デザインの変更の仕方は抑えた)ので、想定していた処理の実装へ進む事にした。

ただ、検索画面で選択した行を、ダイアログへ通知し、そこでボタン押下で別画面へ遷移させる際、最初に選択した行をどうやって持ちまわるのかが課題として見えてきた。グローバル変数に持たせておくというので、取りあえずは解決するのだけれど、他にも持ちまわりたいデータがあるのに、それを全部グローバル変数でやり取りするのは美しくないw

jQuery UIのダイアログオブジェクトを継承して、自前のプロパティを追加して、そこへ設定…みたいな、Java的なアプローチができない事も無いのだろうけれど、そこまですべきなのだろうか…。あまり変数を多くしても良くなさそうだし、連想配列にでもして受け渡す方がいいのだろうか。それなら、検索結果の配列を保存しておいて、受け渡すのは選択されたindexのみにした方がいいんじゃ無いだろうか?

これを書いている内に色々考え始めてしまったなw取りあえずこれ以上ダラダラ続けても意味が無いので、ここまでにしよう。データの受け渡しはまたちゃんと考えよう。そして今日やれなかった別ページへの遷移までできるといいな。

ダイアログの表示成功

マウス操作ではなく、リンク(アンカー)による操作に切り替えてみた。まず検索結果の第一要素(1列目)を単なる文字列ではなく、AタグをcreateElementして、それをTDタグにアペンド、そしてそれをTRへ追加…という手順を踏む事にした。具体的にはこんな感じ。

// 1カラム目の処理
var new_tr = document.createElement( 'tr' ) ;
var new_td = document.createElement( 'td' ) ;
var new_a = document.createElement( 'a' ) ;
a.id = row_identifier ;
a.innerHTML = 1st_column_string ;
jQuery( new_a ).on( 'click', my_click_process ) ;
new_td.appendChild( new_a ) ;
new_tr.appendChild( new_td ) ;
// 2カラム目の処理
new_td = ...

この処理を、行数分繰り返す事でアンカー(Aタグ)つきの表形式結果一覧が完成する。アンカーをクリックして、単にどこかへ飛ばすわけではないので、href属性は設定せずに、onClickで処理を挟むようにした。処理としては何かしらのポップアップウィンドウを表示する事を想定した。

そして次に取り掛かったのが、ポップアップの表示なのだが、ポップアップ表示と言ってもいろいろな種類がある。いわゆるalertではダイアログ内のレイアウトも限定されてしまうので、できればもう少しレイアウトが自由なのがいいなぁと色々調べてみると、HTML+CSSで作るポップアップや、jQuery UIのダイアログなど、結構候補が色々あった。とりあえず手っ取り早そうなjQuery UIのダイアログを試してみようと思って作ってみたのだが…。

$("#test_dialog").dialog( "open" ) ;

みたいに書いても、「dialogが関数として定義されていない」とエラーになる。jQueryの記述に慣れていないのもあるのかと思い、色々と書き方とか触ってみたのだが結果は変わらない。そしてこれは、必要なライブラリが足りてないとかではないのか?と思って調べてみたら、やっぱりデフォルトではjQuery UIは読み込まれていなさそう。という事で、早速jQuery UIを読み込んでみた。functions.phpに次のように書き加えてみた。

add_action( 'wp_enqueue_scripts', 'additional_scripts_enqueue' );
function additional_scripts_enqueue() {
wp_enqueue_script( 'jquery-ui-dialog' );
wp_enqueue_style( 'jquery-ui-dialog-min-css', includes_url().'css/jquery-ui-dialog.min.css' );
}

そして試してみると…、できた!!!想定通りのダイアログが画面にでてきた。PCの場合、ダイアログの位置や大きさも、表示した後に自由に変更できるようだけれど、スマホ(Chrome)では動かせなかった。まぁ動かす必要も無いので構わないのだが。その辺り、色々とデザイン等を見て考えるとしよう。今回は「OK」ボタンを配置したけれど、「×」ボタンはデフォルトでつくようだし、「簡易表示」「詳細表示」の2ボタンを配置すれば、「OK」ボタンは無くても良さそうに思う。

後、表示させるダイアログはHTML(今回の場合はWordPressの固定ページ)上にdivで囲った要素として、あらかじめ記述しておく必要がある。しかし処理が遅かったりするのか、余計な処理が多くて手間取っているのかまだ不明だが、表示させたくないのに画面上に一瞬表示されてしまう事がある。取りあえず以下のように非表示のスタイルを設定してみたが、これでも問題なくダイアログは表示されるようだし、しばらくこのままでいこうかな。

<div id="test_dialog" style="display: none ;">
<p>test dialog</p>
<button>簡易表示</button>
<input type="button" value="詳細表示" />
</div>

このjQuerty UIのダイアログで全て目的が達成されるようなら、次は実際の簡易表示、詳細表示の処理へと進む事になるが、どうやってやるのかは全く不明。雛形HTMLを用意して…でも、固定ページへ埋め込んで…でもダメだと思うからどうしようね。まぁそれはダイアログが完成した後に考えよう。取りあえずは固定ページを作って、そこへ別タブ(target=”_blank”)で表示するような流れまでできれば、ダイアログ関連も完了にできるから頑張りたい。

CSSの謎とポインター処理

子テーマにクラスを設定して、画面上の部品にクラス指定して、色々反映させるというのは以前絞込み条件設定画面のレイアウトでうまくいっていた。今回、条件のリセットボタンを作ろうとして、ボタンを配置したが、さすがにデフォルトのままだと見栄えがよろしく無いので、こちらもスタイルを変更しようとstyle.cssにクラス設定して使おうとした。

しかし、全然ボタンにスタイルが反映されてくれない。ボタンに直接style属性にあれこれ設定すれば有効になるのだけど、クラス指定だとうまくいかない。ボタン系は他のinputとは異なるのかな?あれこれやってみたけどうまくいかなかったので、とりあえず保留して操作系に移る事にした。

検索結果は、表形式で表示されるのだが、表示された行(行の上ならどこでもOK)をマウスで長押しすると、ポップアップなどが表示されるようにしようと思って実装を進めた。onmousedownやonmouseup、onmouseout等々思ったとおりの動作をしてくれたので、次はタイマー(setTimeout)を仕込んで、指定秒数経過したらポップアップなどを表示させようと目論んだ。

しかし、その前にマウスの無いスマホはどうなるのか?と思い、試してみると、案の定反応してくれない。調べてみると、mousedownの代わりにtouchstart等を使うと良いようで、タップできるかどうか事前に確認して切り替えるなどの方法が使えるそう。そしてさらに調べると、それらをwrappingしているのか、pointerdownなどのイベントが既に実装されているようだ。mousedownの代わりに、pointerdownを使ってみたら、想定通りPCでもスマホでも動作してくれた。

では、これを使って実装…と思ったのだが、PCはともかく、スマホの場合はブラウザ上で長タップし続けると、おそらくデフォで「文字の範囲選択」になるだろう。その辺りの処理をさせないようにする事もできる(イベントの破棄など)のだろうけれど、そこまでして長押し表示に拘るべきなのか?と考えた。

表で結果が表示され、特にボタンもリンクも無い場合、普通は何もできないと思うだろう。詳細表示させる為に「長押し(タップ)して下さい」と表示するのは、説明みないと操作できないという、UIとしては失敗作(自己満足)でしかない気がする。だったら既に確立している、ボタンや遷移でリンクさせるという方が、利用者へ考えさせるという負担を軽減する事にもなるんじゃないか?

今回、イベントをjQueryでいくつか書いてみたけれど、例えば…

function foo() {
var newtr = document.createElement( 'tr' ) ;
jQuery( newtr ).on( 'pointerdown', bar ) ;
}

みたいな感じ。この’pointerdown’は単なる文字列だから、変数などで状況に応じたイベントにハンドラを登録できるというやり方を今回学んだ。jQuery自体がまだまだ使いこなせていないけど、ちょっと縁から深遠を覗き込んだような気がする。ある意味、メソッド名を自動生成するようなものだから、今回のようなプログラムで色々イベントハンドラ登録したい時は有用な気がしてる。

とりあえず、今回の件に関しては、第一要素にAnchorを貼って、そこにidとonclickをセットし、ポップアップで簡易表示か詳細表示を選ばせるという処理にする予定だけど、アンカーの設定やハンドラの設定も、同じようにjQueryでやれそうかな。

少し方針転換

検索系が結構できあがったので、テスト用のデータを増やして色々な精度を高めて行こうと思っていたのだけど、データ入力している最中に色々とこのままの構造でいいのか?という疑問がわいてきてしまった。

検索して、一覧表示まではOKだったけど、さらにそこから行を選んで詳細表示という流れになった際、詳細データの持ち方や、そもそもどうやって詳細表示させるのか?というのがまだ未解決だった事に気づいた。これを放置してデータを増やしても、後からテーブルの見直しなどをするのは大変な事になる。

という事で、データ入力はひとまずおいて、検索結果一覧から、詳細画面への遷移の流れを作っていく事にした。

検索したデータは従来はHTML形式のTRタグをPHP側で生成し、その文字列をJS側でinnerHTMLとして渡すというやり方で結果一覧をTABLE形式で表示させていた。しかし、検索結果一覧で行を選択し、詳細画面を表示させるには、その行を一意に表す必要がある。タグで文字列を返していたので、TRタグにid属性を指定し、そこへその一意の値を設定すれば、JavaScript側でidを取得できるのでは?という目論みだった。

しかしながら、結果としては失敗だった。というのもidを取り出しても空白(未設定)状態のままだった。色々試行錯誤もしてみたけれど、うまくいかずもう一度良く考えてみた。

PHP側で以下のような文字列を1行のデータとして返している。

<tr id="id001"><td>data1></td><td>data2</td><td>data3</td></tr>

これをJavaScript側で受け取った際(実際はJSONへencodeした後に、Parseしているが)、次のような処理で1行のデータを作成していた。

var newtr = document.createElement( 'tr' ) ;
newtr.innerHTML( row_data ) ; // <tr id="..."><td>...
var id = newtr.id ; // idを取得したつもりだったが…

今まで、これでちゃんとテーブル形式でデータが表示されていたので、問題ないと思っていたのだが、よーく考えてみると、TRの要素にTRタグを入れているという解釈になってはいないか?と気付いた。もしそうなら、HTMLの構文上TRの子要素にTRはありえないため、DOM側で無視していたのではないだろうか。無視されているなら、いくらid属性に値を入れた所で無視されるのは当然の事だった。

では、createElementせず別の方法で文字列を評価し、それをTRオブジェクトとして処理をすれば良いのでは…と思ったのだが、どうにもそれはおかしな考えなのでは?と思い始めた。また、タグを含めた文字列が検索結果として返ってくると、検索結果の行数が増えれば増えただけタグ部分のデータ量が増えてしまう。検索件数に上限を設ける予定とは言え、無駄な通信料を増やすのは良く無いだろう。

という事で、タグの文字列を返していた部分を全面的に作り変え、検索結果の多次元配列(JSON化したもの)を返却するようにした。あわせて、検索件数とデータのみを返していた部分を、検索件数とエラーコード、検索結果という3構成にして返す事にした。エラー種別でJavaScript側の対応を分けられるようにしたのだが、現状は正常時とそうでない時(検索件数0はエラーでは無いが処理上は異常時と同じ表示で済ませるため)で分けているだけにしてある。この部分は今後エラーが増えた場合には相応の対応が必要になるだろう。

検索結果には、日本語文字列を含むが、データベース上は数値で格納しているものもある。PHPから返却する際、検索結果の数値部分を文字列に置き換えて返却しているが、エラーメッセージなども全てPHP側で文字列を作って返却し、ブラウザ側ではそれがそのまま表示されるようにしようと思う。

これは、将来英語化を視野に入れた対応で、多国語化対応をJavaScriptでガリガリやるわけにもいかないだろうと考えたためだ。実際日本語データと英語データは別フィールドに格納するようにしているので、画面の言語情報をPHP側で受け取って生成するSELECT文を変えたりする必要もある。上述の数値を置き換えた文字列も当然切り替える必要もあるので、表示される文字列に関しては全てPHP側で生成して返却しようと思っている。

実際には、日本語ページと英語ページで別URLになるのだろうから、HTML上の文字列はともかく、JavaScriptで扱う文字列なども別々のJSファイルで持つなどすればいいのかもしれないが、その辺りどっちがいいのか?というのはイマイチ経験不足で判断がつかないというのが正直な所。ただ、ローカライズに関する部分はできる限り少なくしたいとは思うので、前述のようにSELECT文が言語で対象フィールドが変わり、その部分の実装が必要なのであれば、ローカライズに関する部分(プログラム的な部分)は全てPHP側に集約する方が良いんじゃないかな?と考えた次第。これは今後変わるかもしれないし、そもそも英語化はハードルも高いのでやらない可能性も十分あるw

とりあえず従来からこのような変更をした上で、検索結果の各行にマウスクリックのイベントハンドラを登録する所までは完成した。というより、イベント部分はさっさと完了していたのだが、そこで取得する「行を識別するID」をどうするか…の部分(上記のあれこれ)に時間を取られてしまっていたのが実状だったりする。

次はマウスやタップの処理をどうするのかを考える必要がある。想定では行の長押しで一定時間経過後にポップアップ表示がでて、そこで概要か詳細かを選ばせて別タブ(target=”_blank”)で画面遷移するという事を目論んでいる。しかし、ぱっと見でそんなイベントハンドラは用意されている感じでは無いので(ダブルクリックとかはあるが)、タイマーとか使って自分で処理しなくてはならないのだろうなぁ…。

また、PCとスマホでどちらも長押しでいいのか、PCの場合は別方法にすべきかというのも考える必要がありそう。一番簡単なのは、表示名をリンクにしてリンククリック(タップ)でポップアップ表示という流れなのだが、日和ってそちらに落ち着く可能性も大w

でも、とりあえずやるだけやってみよう。この辺りの使い勝手が良く無いと余り意味が無いものになってしまうかもしれないし。イベント系は色々難しい(発火や消費、二重発火の抑止など)と思うのだが、最近はその辺りも緩和されていたりするのかな?逆に難しくなっていたりして…。まぁやるだけやるしかないかな…。

絞込み条件の完成

今日は昨日作った絞込み条件用のHTMLをAjaxでPHP側に渡し、その値でWHERE句を生成するという部分を作ってみた。

チェックボックスからの値の取得は、jQueryでやったけど、これはちょっと正直理解せずにほぼコピペという形になってしまった。意味自体はわかるけど、jQueryの記述でそれが実現できている意味が理解できていないという意味。mapで無名関数を登録して値を配列にpushしているという事で、eachはいわゆるeachでいいのかな?要素それぞれに処理を行うというeachとかmap系の命令?。まぁそこはいいとして、画面上のcheckboxからその配列を取り出してくるjQueryの記述

$("[name='opt_foo[]']:checked").each(function() {
checked_foo.push(this.value) ;
}) ;

これの一番最初の部分が理解できてない。HTML上にある全チェックボックスから、名前「opt_foo」という名前を持つものでかつ、「checked」になっているチェックボックスのリストを返す記述…なのかな。jQueryに関しては、ちゃんとやらないと理解しないまま進んでしまいそうだから気をつけないと。

それはさておき、Ajaxのコールバック関数(JavaScript)内でこれらを使ってそれぞれの絞込み条件を取り出し、POST変数に指定してPHPを呼び出し、WHERE句を自動生成する部分は案外スムーズにできた。

条件が指定されると配列が作られるので、配列サイズが0じゃなかったらANDで条件を付与。それを絞り込み条件のグループ分繰り返すだけ。個別の条件内は複数の数値の中に該当するもの…という事でINを使って実装した。

AND XXX IN(0,1,2) AND YYY IN(3,4,5) AND (ZZZ IN (1,2,3) OR ZZZ2 IN (1,2,3))

 のようにANDでINが連なるようになっている。フルに条件つけるとANDとINが大量になってしまうが…、MySQLはその辺り十分耐えられるのだろうか?そういうのはデータを増やして実際に動かしてみないとわからない部分だろうな。

しかしながら、この部分は非常にあっさりと、思った通りの動きをしてくれているように思う。複数の条件の組み合わせもできているし、問題ないだろう。

実際テストしてて思ったけど、条件のリセットってのは必要だと感じた。JavaScriptで実装できるだろうけど、どうやるのが一番簡単かな。そいやFORMのDOMにresetとかなかったかな?あったら楽だけどw

明日は集中して何かやるのは難しそうだから、まったりとデータ入力をしようかなと思う。土日で50件分のデータ入力完了ってのを目指そうか。