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

少し方針転換

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

検索して、一覧表示までは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

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

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

アップロードファイルの最大サイズ: 1 MB。 画像 をアップロードできます。 ここにファイルをドロップ