- ベストアンサー
リストボックス間で値をコピーする方法について
- リストボックス間で値をコピーする方法についてアドバイスをいただきたいです。
- リストボックス間で値のコピーと、フォント色の変更方法について教えてください。
- 左から右への移動と右から左への移動時のアイテムの追加と削除について教えてください。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
#4の内容で間違いがありました。 valueが一致した際のcontinueはwhileに戻らなければいけないのに forに戻るようになってます。 javascriptで2個上のループに戻る記述を残念ながら私は知らないので フラグを作って不恰好に修正しました。 何度もすみません>< while ( leftBox.selectedIndex >= 0 ) { continueflg=false; if(rightBox.length > 0) { for(index=0;index<rightBox.length;index++) { if(leftBox.options[leftBox.selectedIndex].value==rightBox.options[index].value) { leftBox.options[leftBox.selectedIndex].selected = false; continueflg=true; break; } } } if(continueflg==true){ continue; } var newOption = new Option(); newOption.text = leftBox.options[leftBox.selectedIndex].text; newOption.value = leftBox.options[leftBox.selectedIndex].value; rightBox.options[rightBox.length] = newOption; leftBox.options[leftBox.selectedIndex].className="copy"; leftBox.options[leftBox.selectedIndex].selected = false;
その他の回答 (4)
- duron
- ベストアンサー率77% (73/94)
#2です。 複数選択のことを忘れててwhileをばっさり切り落としてしまいました。 修正してみたので時間がありましたら確認してみてください。 <script type="text/javascript"> window.onload = function() { document.getElementById("btnMoveRight").onclick = moveItems; document.getElementById("btnMoveLeft").onclick = moveItems; } function moveItems() { var leftBox = document.getElementById("ListBox1"); var rightBox = document.getElementById("ListBox2"); if (this.value == "→") { if ((leftBox != null) && (rightBox != null)) { if(leftBox.length < 1) { alert("リストボックスにアイテムがありません!"); return false; } if(leftBox.selectedIndex == -1) { alert("移動するアイテムを選択してください!"); return false; } while ( leftBox.selectedIndex >= 0 ) { if(rightBox.length > 0) { for(index=0;index<rightBox.length;index++) { if(leftBox.options[leftBox.selectedIndex].value==rightBox.options[index].value) { leftBox.options[leftBox.selectedIndex].selected = false; continue; } } } var newOption = new Option(); newOption.text = leftBox.options[leftBox.selectedIndex].text; newOption.value = leftBox.options[leftBox.selectedIndex].value; rightBox.options[rightBox.length] = newOption; leftBox.options[leftBox.selectedIndex].className="copy"; leftBox.options[leftBox.selectedIndex].selected = false; } } } else if (this.value == "←") { if ((rightBox != null) && (leftBox != null)) { if(rightBox.length < 1) { alert("リストボックスにアイテムがありません!"); return false; } if(rightBox.selectedIndex == -1) { alert("削除するアイテムを選択してください!"); return false; } while ( rightBox.selectedIndex >= 0 ) { if(leftBox.length > 0) { for(index=0;index<leftBox.length;index++) { if(rightBox.options[rightBox.selectedIndex].value==leftBox.options[index].value) { leftBox.options[index].className="none"; break; } } } rightBox.remove(rightBox.selectedIndex); } } } return false; } </script> <style TYPE="text/css"> <!-- .copy { color:red;} .none { color:black;} --> </style>
- yyr446
- ベストアンサー率65% (870/1330)
リストボックス間で!て言ってるので、<select>でなく、リスト要素(li)をコピーするやつを作ったぞ。たったこんだけの機能でもやたらと長くなったので、本体JS「ListItemMove.js」は↓に置いた。 https://gist.github.com/779432#comments HTMLマークアップサンプルは↓なかんじ。 <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>List Item Move</title> <style type="text/css"> ul {margin:0px;padding:5px;list-style:none;border:1px solid black;width:50px;height:90px;overflow:auto;} </style> <script type="text/javascript" src="ListItemMove.js" charset="UTF-8"></script> </head> <body> <h1>List Item Move</h1> <table></tbody><tr> <td> <ul id="LeftList"> <li>Item1</li> <li>Item2</li> <li>Item3</li> <li>Item4</li> <li>Item5</li> </ul> </td> <td> <button type="button" id="btnMoveRight" onclick="move1.rightmove();">>></button><br> <button type="button" id="btnMoveLeft" onclick="move1.leftmove();"><<</button> </td> <td> <ul id="RightList"></ul> </td> </tr></tbody></table> <script type="text/javascript"> var move1 = new ListItemMove( document.getElementById("LeftList"), document.getElementById("RightList"), {selectcolor:"yellow"} ); </script> </body> </html>
お礼
ご回答ありがとうございます。 それと大変申し訳ないのですが、リストボックス間と発言させていただいたのは、リンク先がそう書いてある為、それが一般的なのかと思っておりました。 今回の要望はselectとなります。 以上、よろしくお願いします。
- duron
- ベストアンサー率77% (73/94)
もう回答が出てますがせっかく記述したのでおまけ程度に・・・ 共通処理になってないのでかっこわるいです。 1.右リストに同じ名称があるかチェックしてあればalert出してます 2.コピーしたらclass:copyを設定してます 3.4.左リストに削除する項目と同じ名称があるかチェックしてあればclass;noneを設定し 右リストからは削除します ※左リストの各optionは最初class:noneを指定しておきます (<option value="1" class="none">Item1</option>というように) --スクリプトココカラ-- <script type="text/javascript"> window.onload = function() { document.getElementById("btnMoveRight").onclick = moveItems; document.getElementById("btnMoveLeft").onclick = moveItems; } function moveItems() { var leftBox = document.getElementById("ListBox1"); var rightBox = document.getElementById("ListBox2"); if (this.value == "→") { if ((leftBox != null) && (rightBox != null)) { if(leftBox.length < 1) { alert("リストボックスにアイテムがありません!"); return false; } if(leftBox.selectedIndex == -1) { alert("移動するアイテムを選択してください!"); return false; } if(rightBox.length > 0) { for(index=0;index<rightBox.length;index++) { if(leftBox.options[leftBox.selectedIndex].text==rightBox.options[index].text) { alert("すでにコピーされています!"); return false; } } } if ( leftBox.selectedIndex >= 0 ) { var newOption = new Option(); newOption.text = leftBox.options[leftBox.selectedIndex].text; newOption.value = leftBox.options[leftBox.selectedIndex].value; rightBox.options[rightBox.length] = newOption; leftBox.options[leftBox.selectedIndex].className="copy"; } } } else if (this.value == "←") { if ((rightBox != null) && (leftBox != null)) { if(rightBox.length < 1) { alert("リストボックスにアイテムがありません!"); return false; } if(rightBox.selectedIndex == -1) { alert("削除するアイテムを選択してください!"); return false; } if ( rightBox.selectedIndex >= 0 ) { if(leftBox.length > 0) { for(index=0;index<leftBox.length;index++) { if(rightBox.options[rightBox.selectedIndex].text==leftBox.options[index].text) { leftBox.options[index].className="none"; break; } } } rightBox.remove(rightBox.selectedIndex); } } } return false; } </script> <style TYPE="text/css"> <!-- .copy { color:red;} .none { color:black;} --> </style> --スクリプトココマデ--
補足
ご回答ありがとうございます。 取り急ぎ動作確認をさせて頂いたところ、下記の現象が見受けられました。 1. 複数を選択して移動しても1件しかコピーしなくなってしまっています(whileを削られているのが原因のようです)。 2. これは私の説明不足ですが、textは一意では、valueは一意のため、valueで比較するように変更させていただきました。 なお、上記現象の解消にまだ着手していない為、私のほうでも動かせていませんが、クラスの付け方などを参考にさせていただきます。 以上、よろしくお願いします。
- yamada_g
- ベストアンサー率68% (258/374)
1. まず、右側に追加した値を保持するための変数を用意します。 var selectedValue = []; //functionの外側に whileループの最初に、 if(!selectedValue[fromBox.options[fromBox.selectedIndex].value]) { で追加済かを判断し、追加していないない場合のみ右側への追加処理を行います。 その際、 selectedValue[fromBox.options[fromBox.selectedIndex].value] = true; で追加した値を保持しておきます。 削除ではなくコピーするようにするには、 >fromBox.remove(fromBox.selectedIndex); を fromBox.options[fromBox.selectedIndex].selected = false; として、選択状態を解除するだけにすればよさそうです。 これは上記の判断に関係なく必ず行うようにします。 2. 上記の判定を行って、コピーする際にはスタイルを設定する処理を追加すればいいですね。 3. delete selectedValue[fromBox.options[fromBox.selectedIndex].value]; で配列から値を削除してから fromBox.remove(fromBox.selectedIndex); でリストから削除します。 4. 3.で削除する際に左側のリストをループして削除する値と一致するoptionのスタイルを元に戻せばいいですね。 (ここはループするしかないのでしょうかね・・)
お礼
ご回答ありがとうございます。 ご回答を読んだ所、selectedValueの使い方が分からなかったので、別の方法で対応しました。 1については、ご教示いただいた下記の記述で大丈夫そうでした。 fromBox.options[fromBox.selectedIndex].selected = false; 2については、duronさんの回答を基に下記の記述を追加する事で大丈夫そうでした。 fromBox.options[fromBox.selectedIndex].className="copy"; 3については、←ボタン押下時のみ下記を実行しない事で大丈夫そうでした。 toBox.options[toBox.length] = newOption; ただ、4については確かにループする必要がありそうですが、 これは今の所どう記述すればよいか分からなかったので、引き続き検討してみたいと思います。 <script type="text/javascript"> window.onload = function() { document.getElementById("btnMoveRight").onclick = moveItems; document.getElementById("btnMoveLeft").onclick = moveItems; } function moveItems() { var leftBox = document.getElementById("ListBox1"); var rightBox = document.getElementById("ListBox2"); var fromBox, toBox; if (this.value == "→") { fromBox = leftBox; toBox = rightBox; } else if (this.value == "←") { fromBox = rightBox; toBox = leftBox; } if ((fromBox != null) && (toBox != null)) { if(fromBox.length < 1) { alert("リストボックスにアイテムがありません!"); return false; } if(fromBox.selectedIndex == -1) { alert("移動するアイテムを選択してください!"); return false; } var toBoxArray = new Array; for(i=0; i<toBox.options.length; i=i+1) { toBoxArray.push(toBox.options[i].value); } while ( fromBox.selectedIndex >= 0 ) { var newOption = new Option(); newOption.text = fromBox.options[fromBox.selectedIndex].text; newOption.value = fromBox.options[fromBox.selectedIndex].value; move_ng = false; for(i=0; i<toBoxArray.length; i=i+1) { if(toBox.options[i].value == newOption.value) { move_ng = true; break; } } if(this.value == "→" && move_ng == false) { toBox.options[toBox.length] = newOption; } if (this.value == "→") { fromBox.options[fromBox.selectedIndex].className="copy"; fromBox.options[fromBox.selectedIndex].selected = false; } else if (this.value == "←") { fromBox.remove(fromBox.selectedIndex); } } } return false; } </script> <style TYPE="text/css"> <!-- .copy { color:red;} --> </style> 以上、よろしくお願いします。
お礼
ご回答ありがとうございます。 ご教示いただいたソースを試した所、意図した動作になりました。 まだソース自体は見れていませんが、時間が取れ次第ソースの中身を確認させていただくようにします。 このたびはどうもありがとうございました。 以上、よろしくお願いします。