さて、複数選択だけなら前回のエントリーだけでなんとかなりますが、左の項目の順番を入れ変えて保存したい場合、難易度がかなり上がります。
公式ページには下記のように書けばOKとかいてあります。
1 2 3 |
$('#hoge_id').multiSelect({ keepOrder: true }); |
このように書けば確かに左の項目の順番を選んだ順に組み替えることができます。
が、この方法だと実際にsubmitをしたときに順番が保存されないのです・・・
なおかつ、値を実際にデータベースに保存して意図した順番で表示したいときやエラー処理などで値が戻ってきたときに入力値の順番を保存させておくのも一筋縄ではいきません。
この対処について書きたいと思います。
Contents
順番を保存したまま送るには
選んだ項目の順番を保存したい場合は、残念ながらこのプラグインのディフォルトの設定だけではだめです。
multiSelectには値を選んだ後の処理を書くことができます。
詳しくは公式ドキュメントに書いてありますが、下記のように書きます。(afterSelect,afterDeleteがそうです。)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$('#hoge_id').multiSelect({ keepOrder: true , afterSelect: function(value, text){ var get_val = $("#data_id").val(); var hidden_val = (get_val !== undefined && get_val !== "") ? get_val+"," : get_val; $("#data_id").val(hidden_val+""+value); }, afterDeselect: function(value, text){ var get_val = $("#csv_field_data_csv_id").val(); var new_val = get_val.replace(value, ""); $("#data_id").val(new_val); } }); |
#data_idというのはhiddenで選択値をカンマ区切りで入力しておくフィールドで、これをhtmlに用意しておきます。
要するに項目を選ぶたびに値を別の場所にカンマ区切りで登録します。これが順番を保持した真の値になります。
削除する場合はちょうど対象の値だけを削除することになります。
データベースで処理をしたりする場合にはこちらの値を使います。
値を読み込むとき
上記は値を送信するときですが、エラーなどで値を再読み込みするときや、データベースから読み込むときも順番を保持させたい場合は特別な処理がいります。
1 この場合、まず値を順番通りにならべ、カンマ区切りでhiddenでhtmlに入れておく(さきほどのdata_idの原理をそのまま使います。)
2 ページを読み込んだ瞬間に下記のコードを実行させる。
1 2 3 4 5 6 7 8 9 10 11 |
var csvFieldDataCsv = $("#data_id").val(); if( csvFieldDataCsv !== undefined && csvFieldDataCsv !== ""){ //下記のように一度消さないと入力時に書かれてしまうため2重になる。そのためhiddenのCSVを一度消す $("#data_id").val(""); var csvFieldDataArr = csvFieldDataCsv.split(",") var csvFieldDataArrLength = csvFieldDataArr.length; for( var i =0;i < csvFieldDataArrLength;i++ ){ var data = csvFieldDataArr[i]; $('#hoge_id').multiSelect("select", data); } } |
multiSelect(“select”,何らかの値)で選択状態にすることができます。
配列を読み込ませてもエラーにはならないのですが、うまく順番が保存できませんでした。
上記のようにすれば値の順番を保存させたまま、データの更新、再表示が可能になります。
コードで書くとなんてことはないんですが、これだけの実装にやたら時間がかかりました。
参考リンク
stackoverflow jQuery MultiSelect – output data in the order in which it was selected
afterSelect,afterDeleteを使わなくてもこれで並び順のまま値を取得できますよ。
var orderedItems = new Array();
$(‘.ms-elem-selection.ms-selected’).each(function(i, elem) {orderedItems.push( $(elem).text() );});
ほにゃほにゃさん
レクチャーありがとうございます!
大変助かります!