Wicket の extension には昔から Palette なるものが存在してました。
意外にも使いやすかったのですが、あまり使うことがなく忘れてました。
前のWicketで使われてなかったjQuery で再現してみたところ、jQueryコーディング の良いトレーニングになります。
まず、このHTMLは、以下のとおりです。
(optionタグは長いのでここでは省略)
======================
<div class="palette">
<table>
<thead><tr><th>非選択</th><th></th><th>選 択</th><th></th></tr></thead>
<tbody>
<tr>
<td>
<select id="unactiveSelections" size="20" multiple="multiple" >
:
</select>
</td>
<td>
<button id="shiftRight" type="button"><img src="right_arrow.png" width="28px" height="28px"></button>
<br/><br/><br/><br/>
<button id="shiftLeft" type="button"><img src="left_arrow.png" width="28px" height="28px"></button>
</td>
<td>
<select id="activeSelections" size="20" multiple="multiple" >
:
</select>
</td>
<td>
<button id="upBtn" type="button"><img src="up_arrow.png" width="28px" height="28px"></button>
<br/><br/><br/><br/>
<button id="downBtn" type="button"><img src="down_arrow.png" width="28px" height="28px"></button>
</td>
</tr>
</tbody>
</table>
<input type="hidden" name="unactiveList" value="1,2,3,4,5">
<input type="hidden" name="activeList" value="11,12,13,14,15,16">
</div>
======================
次に、jQuery は、わずかこれでだけで済みます。
======================
$(function(){
var setHiddenList = function(options, hidden){
var a = new Array();
$(options).each(function(){
a.push($(this).val());
});
$(hidden).val(a.join(","));
};
$('#shiftRight').click(function(){
$($('#unactiveSelections option:selected').get().reverse()).each(function(){
$('#activeSelections').prepend($(this));
$('#activeSelections').scrollTop(0);
});
/* hidden に結果をセット */
setHiddenList('#unactiveSelections option', 'input[name="unactiveList"]');
setHiddenList('#activeSelections option', 'input[name="activeList"]');
});
$('#shiftLeft').click(function(){
$($('#activeSelections option:selected').get().reverse()).each(function(){
$('#unactiveSelections').prepend($(this));
$('#unactiveSelections').scrollTop(0);
});
/* hidden に結果をセット */
setHiddenList('#unactiveSelections option', 'input[name="unactiveList"]');
setHiddenList('#activeSelections option', 'input[name="activeList"]');
});
$('#upBtn').click(function(){
$('#activeSelections option:selected').each(function(){
if ($(this).prev() != undefined){
$(this).after($(this).prev());
}
});
/* hidden に結果をセット */
setHiddenList('#unactiveSelections option', 'input[name="unactiveList"]');
setHiddenList('#activeSelections option', 'input[name="activeList"]');
});
$('#downBtn').click(function(){
$($('#activeSelections option:selected').get().reverse()).each(function(){
if ($(this).prev() != undefined){
$(this).before($(this).next());
}
});
/* hidden に結果をセット */
setHiddenList('#unactiveSelections option', 'input[name="unactiveList"]');
setHiddenList('#activeSelections option', 'input[name="activeList"]');
});
});
======================
選択済み、:selected フィルタで取得したリストを reverse で参照するのが重要です。
そうしないと、移動した時に並びが逆になってしまいます。
CSSは、以下のとおり。
div.palette{ margin-left: 40px; }
.palette table{
box-sizing: border-box;
border-spacing; 0;
border-collapse: collapse;
white-space: nowrap;
width: 540px;
}
.palette th:nth-child(odd){
background-color: #f0f8ff;
border-top: 2px solid #0000c0;
border-bottom: 3px double #0000c0;
}
.palette td{
padding: 0;
}
.palette td:nth-child(1){ width: 180px; }
.palette td:nth-child(2){ width: 90px; text-align: center; }
.palette td:nth-child(3){ width: 180px; }
.palette td:nth-child(4){ width: 90px; text-align: center; }
.palette select{
width: 100%;
height: 180px;
}
.palette button{ cursor: pointer; }