jQuery UI Dialog と Tabulator と「そのインスタンス共有」でどツボる (clearData が効かないよー)

ゆめみてんのかしら、と頭掻き毟ることうん時間。

1時間かそれ以上かなぁ、全然解決しなくて困った。

出来上がって、作りたかったのはこんな UI:

先に今回のハマリネタ説明の前に前置き。画像でみえてる「Genres」はこれは jQuery UI の Autocomplete で入力させるインターフェイスになっている。が、今回のハマリネタの「Producers, Studios」でなぜ同じことが出来なかったかと言うと、「Producers, Studios」の名前自身にカンマを含むのが当たり前のように存在するから。なので multi values な入力インターフェイスとして「名前の方をカンマ区切りで列挙させる」を採用出来ない。

なので Tabulator な検索インターフェイスと Dialog の組み合わせを採用しようと考えたわけだけれど。上画像の「1」ボタンで「2」のダイアログが起動、「3」で検索すると、Tabulator 表に検索結果が入り、「4」のように選択することで、「5」に入力として(IDが)流し込まれる、という流れなのだけれど、「1」と「6」の2つのボタンで起動するのは、1個の Dialog だし 1個の Tabulator、なのですわ。(別々の Dialog を作っちゃう手はさすがに採用したくはなくて。)

当然「どっちから起動されたの?」がわからないと Dialog 側は「どっちの input に選択結果を流し込むの?」がわからないけれど、そんなんは別になんとでもなって:

1 // idではなくclassのほう相手のセレクタで反応
2 $(".open-filters-producer-list").on("click", function(ev) {
3     // おれだおれだおれだおれだおれだあ
4     __producers_list_triggered = $(this).attr("id");
5     // ...
6 });

とかね。

困ったのは「clearData が効かない」ことだった。2つを共有してるんで、毎度まっさらから始めたいのだが、まぁしつこく前のデータがリストに生き残る。

最初の NG パターン:

 1 var __producers_list_triggered = null;
 2 $("#producers-list").tabulator({
 3     // ...
 4     rowSelectionChanged: function(data, rows) {
 5         var target = null;
 6         if (__producers_list_triggered == "open-filters-producer-incl-list") {
 7             target = $("#producers-incl");
 8         } else {
 9             target = $("#producers-excl");
10         }
11         // ...
12     },
13 });
14 $(".open-filters-producer-list").on("click", function(ev) {
15     __producers_list_triggered = $(this).attr("id");
16     $("#search-producers").val("");
17     $("#producers-list").tabulator("clearData");
18     $("#filters-producer-list").dialog({
19         // ...
20     });
21 });

いや、ふつうにこれ、真っ先に考えるやつじゃん。うまくいくと思うじゃん。けど何が原因かは結局わからずじまいだったけれど「消えない、しつこく残る」。一つ上の検索ボックスのクリアはちゃんと効くので、ほんとに tabulator の clearData 「だけが」効かない。

「何かタイミングの問題なのだろう」とするならもう「何かのイベントを探そうか」しか解は残らないでしょ。だから先に:

これも NG
 1 var __producers_list_triggered = null;
 2 $("#producers-list").tabulator({
 3     // ...
 4     rowSelectionChanged: function(data, rows) {
 5         var target = null;
 6         if (__producers_list_triggered == "open-filters-producer-incl-list") {
 7             target = $("#producers-incl");
 8         } else {
 9             target = $("#producers-excl");
10         }
11         // ...
12     },
13 });
14 $(".open-filters-producer-list").on("click", function(ev) {
15     __producers_list_triggered = $(this).attr("id");
16     $("#filters-producer-list").dialog({
17         // ...
18         close: function(ev, ui) {
19             $("#search-producers").val("");
20             $("#producers-list").tabulator("clearData");
21         },
22     });
23 });

ここまでくりゃぁもう考えることは一つ:

やっと…
 1 var __producers_list_triggered = null;
 2 $("#producers-list").tabulator({
 3     // ...
 4     rowSelectionChanged: function(data, rows) {
 5         var target = null;
 6         if (__producers_list_triggered == "open-filters-producer-incl-list") {
 7             target = $("#producers-incl");
 8         } else {
 9             target = $("#producers-excl");
10         }
11         // ...
12     },
13 });
14 $(".open-filters-producer-list").on("click", function(ev) {
15     __producers_list_triggered = $(this).attr("id");
16     $("#filters-producer-list").dialog({
17         // ...
18         open: function(ev, ui) {
19             $("#search-producers").val("");
20             $("#producers-list").tabulator("clearData");
21         },
22     });
23 });

実際のとこ、「既存のものにこのインターフェイスを追加する作業」全体としては3~4時間くらいだったかなと思う。「autocomplete じゃだめだしなぁ…」で悩んでる時間も含めれば半日くらいか。そのトータル時間のうちどのくらいの時間この問題でハマってたかは、正直正確なところはわかんない。実際「動かしながらの確認」の繰り返しの中では、ほかにもしょうもないミスでのやり直しが多かったから。けど印象的にはもう2、3時間みっちり苦しんだ印象。

なんなんだろうねぇ、これは。そもそも「Dialog に包む」ということそのもので「非表示の状態で Tabulator を初期化する」ことになっていて、列幅の調整で既におかしいのは気付いていた。これもなんとかしたいとは思うけど別に今回の話ほどは致命的な話じゃないのでね、後でいいかと思ってたけれど、当然問題の本質はどちらも同じだろうと思う。「Tabulator + jQuery UI Dialog」ではあるいは共通の悩みごとなのかもしらんね。


2018-02-17追記:
続きの話を書いた。



Related Posts