画面上、リスト並び替えの古典的な方法

Webページ表示上で何らかの項目リストを並び替える方法は、jQuery などで、ドラッグさせる方法が今の時代、
大半であろう。


しかし、古いシステムの保守など簡単に jQuery などを導入させてもらえない諸事情もあったりする。

以下のようなサンプルは使えることがあるかもしれない。

f:id:posturan:20160313194702j:plain

 

f:id:posturan:20160313194657j:plain



===HTMLソースの一部====
<input type="hidden" id="recorder" name="palette:recorder" value="生姜,バジル,ブロッコリー,トマト" />
<div>
<table cellspacing="0" cellpadding="2">
   <tr>
      <td><span>Available</span></td>
      <td></td>
      <td><span>Selected</span></td>
   </tr>
   <tr>
      <td>
         <select id="choices" name="choices" multiple="multiple" size="12"
               onfocus="Palette.choicesOnFocus('choices','selection','recorder');"
               ondblclick="Palette.add('choices','selection','recorder');"
 >
            <option value="きゃべつ">きゃべつ</option>
            <option value="にんじん">にんじん</option>
            <option value="いんげん">いんげん</option>
            <option value="かぼちゃ">かぼちゃ</option>
         </select>
      </td>
      <td>
         <button type="button" id="addButton"      onclick="Palette.add('choices','selection','recorder');">Add</button><br/><br/>
         <button type="button" id="removeButton"   onclick="Palette.remove('choices','selection','recorder');">Remove</button><br/><br/>
         <button type="button" id="moveUpButton"   onclick="Palette.moveUp('choices','selection','recorder');">Up</button><br/><br/>
         <button type="button" id="moveDownButton" onclick="Palette.moveDown('choices','selection','recorder');">Down</button><br/><br/>
      </td>
      <td>
         <select id="selection" name="selection"  multiple="multiple" size="12"
               onfocus="Palette.selectionOnFocus('choices','selection','recorder');"
               ondblclick="Palette.remove('choices','selection','recorder');"
 >
            <option value="生姜">生姜</option>
            <option value="バジル">バジル</option>
            <option value="ブロッコリー">ブロッコリー</option>
            <option value="トマト">トマト</option>
         </select>
      </td>
   </tr>
</table>
</div>
<hr/>
<br/>
<input type="button" value="確認" onclick="alert(document.getElementById('recorder').value)">
</form>


=== JavaScript ====

/*
 * pallete.js
 */

if (typeof(Palette) == "undefined") Palette = { };

Palette.$ = function(id){
   return document.getElementById(id);
};

Palette.choicesOnFocus = function(choicesId, selectionId, recorderId){
   Palette.clearSelectionHelper(Palette.$(selectionId));
};

Palette.selectionOnFocus = function(choicesId, selectionId, recorderId){
   Palette.clearSelectionHelper(Palette.$(choicesId));
};

Palette.add = function(choicesId, selectionId, recorderId){
   var choices = Palette.$(choicesId);
   var selection = Palette.$(selectionId);
   if (Palette.moveHelper(choices, selection)){
      var recorder = Palette.$(recorderId);
      Palette.updateRecorder(selection, recorder);
   }
};

Palette.remove = function(choicesId, selectionId, recorderId){
   var choices = Palette.$(choicesId);
   var selection = Palette.$(selectionId);
   if (Palette.moveHelper(selection, choices)){
      var recorder = Palette.$(recorderId);
      Palette.updateRecorder(selection, recorder);
   }
};

Palette.moveHelper = function(source, dest){
   var dirty = false;
   for(var i=0;i < source.options.length;i++){
      if (source.options[i].selected){
         dest.appendChild(source.options[i]);
         i--;
         dirty = true;
      }
   }
   return dirty;
};

Palette.moveUp = function(choicesId, selectionId, recorderId){
   var selection = Palette.$(selectionId);
   if (Palette.moveUpHelper(selection)){
      var recorder=Palette.$(recorderId);
      Palette.updateRecorder(selection, recorder);
   }
};

Palette.moveUpHelper = function(box){
   var dirty = false;
   for(var i=0;i<box.options.length;i++){
      if (box.options[i].selected && i > 0){
         if (!box.options[i-1].selected){
            box.insertBefore(box.options[i],box.options[i-1]);
            dirty = true;
            box.focus();
         }
      }
   }
   return dirty;
};

Palette.moveDown = function(choicesId, selectionId, recorderId){
   var selection = Palette.$(selectionId);
   if (Palette.moveDownHelper(selection)){
      var recorder = Palette.$(recorderId);
      Palette.updateRecorder(selection, recorder);
   }
};

Palette.moveDownHelper = function(box){
   var dirty = false;
   for(var i=box.options.length-1;i >= 0;i--){
      if (box.options[i].selected && i < box.options.length - 1){
         if (!box.options[i+1].selected){
            box.insertBefore(box.options[i+1],box.options[i]);
            dirty = true;
         }
      }
   }
   return dirty;
};

Palette.updateRecorder = function(selection, recorder){
   recorder.value = "";
   for(var i=0;i < selection.options.length;i++){
      recorder.value=recorder.value+selection.options[i].value;
      if (i+1 < selection.options.length){
         recorder.value = recorder.value + ",";
      }
   }
   if (recorder.onchange!=null){ recorder.onchange(); }
};

Palette.clearSelectionHelper = function(box){
   for(var i=0;i < box.options.length;i++){
      box.options[i].selected = false;
   }
};