![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?5a7ff87)
リストボックス間で値をコピーしたいと思い、http://jsajax.com/Articles/listbox/339の「このサンプルを編集して試してみる」を参考に変更を行っていたのですが、どうすればできるか分からないことがあったので、アドバイスいただける方がいらっしゃいましたら、ご教示の程、よろしくお願いします。
1. →ボタン押下時、リンク先のプログラムでは移動動作をおこないますが、これを選択中のアイテムが右のリストボックスに存在しなければコピーし、右のリストボックスに存在する場合は何も動作しないようにしたいと思います。
ソース内の下記の部分で削除動作をしているようなので、removeを削除すれば消えなくなると思いますが、そうすると無限ループしてしまうと思います。
while ( fromBox.selectedIndex >= 0 ) {
// 略
fromBox.remove(fromBox.selectedIndex);
}
そのため、上記のwhileではなく、その時選択中のアイテム数を取得し、forなどでループ(その際、selectedIndexの取得方法には工夫が必要?)させるとやりたいことができるのかなと思いましたが、具体的にどう記述すればよいかわかりませんでした。
2. (出来れば)1のコピー後、左のリストボックスのアイテムの中で、
右のリストボックスに存在するアイテムのフォント色を変えたいと思います。
3. ←ボタン押下時、右のリストボックスからアイテムを消去したいと思います。
これは←ボタン押下時のみtoBox.options[toBox.length] = newOption;を実行しなければできるのかなと思いましたが、1番のコピー動作ができていないため、あくまで想像となります。
4. (出来れば)右から左へ移動時、2番の動作が実現できていてフォント色が変更されている場合、基に戻したいと思います。
なお、2と4については、あらかじめスタイルシートにスタイルを定義しておき、
toBox.options.length分、toBox.options[i].valueの値を得た上で、fromBox.options[fromBox.selectedIndex].valueと一致するものがあれば、classを付加し、fromBox.options[fromBox.selectedIndex].valueと一致するものがなければclassを付加しなければできるのかなと思いましたが、具体的にどう記述すればよいかわかりませんでした。
以上、よろしくお願いします。
No.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;
ご回答ありがとうございます。
ご教示いただいたソースを試した所、意図した動作になりました。
まだソース自体は見れていませんが、時間が取れ次第ソースの中身を確認させていただくようにします。
このたびはどうもありがとうございました。
以上、よろしくお願いします。
No.4
- 回答日時:
#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>
No.3
- 回答日時:
リストボックス間で!て言ってるので、<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となります。
以上、よろしくお願いします。
No.2
- 回答日時:
もう回答が出てますがせっかく記述したのでおまけ程度に・・・
共通処理になってないのでかっこわるいです。
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で比較するように変更させていただきました。
なお、上記現象の解消にまだ着手していない為、私のほうでも動かせていませんが、クラスの付け方などを参考にさせていただきます。
以上、よろしくお願いします。
No.1
- 回答日時:
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>
以上、よろしくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Outlook(アウトルック) Outlookでメールをデリートキーで削除した場合における、メールの移動先フォルダを変更したい。 2 2022/10/31 00:53
- Excel(エクセル) ログインIDの一発入力? 5 2023/07/07 12:30
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- Excel(エクセル) 【困っています】VBA 追加処理の記述を教えてください。 1 2022/08/25 22:54
- Visual Basic(VBA) Excel(VBA) 特定の条件に該当する行の値、書式を同じセルにコピ&ペーストしたいです 1 2022/05/21 18:18
- Visual Basic(VBA) いつもお世話になっております、VBAで教えて頂きたいのですが 2 2022/05/05 22:20
- Visual Basic(VBA) VBAコードを張り付け後のエクセルの進め方 2 2023/02/07 18:24
- PHP 配列の値の更新方法について 1 2022/08/05 09:49
- Visual Basic(VBA) VBAでoutlook365が起動しません。 4 2022/08/25 13:31
- Excel(エクセル) エクセル シート内のボックスを縦並びから横並びに 7 2023/04/05 04:28
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
プルダウン 項目が多いので先頭...
-
リストボックスの4連
-
JQuery selectが反映されない
-
Selectの中身をfor文で入れる
-
Selectボックスの幅を自動で広...
-
リストボックスに追加した全て...
-
特定の要素内に入力された文字...
-
DB(MySQL)、PHP、jQueryの連結
-
html selectの内容を初期値に戻す
-
セレクトメニューの連動 multip...
-
どちらのほうが処理が早いか
-
メッセージを出したい!
-
ブラウザの戻るボタンを押した...
-
int select(int n, fd_set *rea...
-
JavaScriptでプルダウンのサイ...
-
メールフォームのタグについて...
-
セレクトで選んだ項目を表示さ...
-
jQuery セレクトボックスで選択...
-
js セレクター書式
-
ラジオボタンでポップアップメ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
プルダウン 項目が多いので先頭...
-
Selectの中身をfor文で入れる
-
Selectボックスの幅を自動で広...
-
CSVファイルを読みこみ、プルダ...
-
セレクトを全て選択されていな...
-
jQuery セレクトボックスで選択...
-
UWSCのIE操作でプルダウンを選...
-
html selectの内容を初期値に戻す
-
現在時刻を取得してフォームのs...
-
javascriptでの2つのプルダウン...
-
テーブルにおける行(セルにプル...
-
selectタグに直接onChangeを書...
-
【javascript・PHP】プルダウン...
-
セレクトメニューで選択された...
-
ブラウザの戻るボタンを押した...
-
JQuery selectが反映されない
-
<textarea>にプルダウンを表示...
-
プルダウンで現在の年月日を取...
-
リストボックスの項目の順番を...
-
親ウィンドウのリスト値変更
おすすめ情報