選択リストの項目を削除のするには?

[上に] [前に] [次に]
TOM [E-Mail] 1999/03/31(水) 11:31:46
選択リストから項目を選択して(複数可)、削除ボタンが押されたら
削除するといった処理で作りたいのですが

選択された項目に
document.formname.selectname[i].value = ""
document.formname.selectname[i].text = ""
としてから
document.formname.selectname.length = document.formname.selectname.length - 選択された分

こんな感じでやったのですがうまくいきません。
どうやればいいのでしょうか?

Tmb 1999/03/31(水) 12:06:46
上のやり方だとlengthを減らすところで,チェックされていたかどうかに関わらず
最後から(選択数)個が削除されてしまうからだと思います。
例えばいちばん上の項目を選んでいたら,その項目は選択可能な空白になり,
選んでもいなかった最後の項目が消える。
解決するためにはソートして,選択された項目のvalue, textを末尾に
持っていくようにしないといけないような気がします。selectedもクリアする。
#他にいい方法が思いつかない。

Tmb 1999/03/31(水) 13:22:21
IE4やNN4以上ならdeleteで対応できるのかな?

http://www.tohoho-web.com/js/statement.htm#delete

Tmb 1999/03/31(水) 13:52:03
面白そうだったのでdeleteを使わない例で組んでみました。コメントなしで恐縮ですが
解析して参考にしてくだされば。
あ,引数としてselectを渡してselectnameで受けてますのでご注意。

function func(selectname){
DelCount = 0;
WritePos = 0;
 for (i = 0; i < selectname.length; i++){
  if (selectname.options[i].selected == true){
  DelCount++;
  selectname.options[i].selected = false;
  } else {
  selectname.options[WritePos].text = selectname.options[i].text;
  selectname.options[WritePos].value = selectname.options[i].value;
  WritePos++;
  }
 }
selectname.length=selectname.length - DelCount;
}

Tmb 1999/03/31(水) 14:06:55
補足訂正
>  selectname.options[WritePos].text = selectname.options[i].text;
>  selectname.options[WritePos].value = selectname.options[i].value;
selectname.options[WritePos] = selectname.options[i];
の一行で十分でしたね。
#うん,なかなかエレガント。

VW 1999/03/31(水) 16:53:48
たったいまラウンジのCGIをつかわせてもらいました。
とても便利ですね 情報を記入できるし、また
ラウンジのCGIの中では記入された特定のメッセージを削除することも
できます。 参考までに

Tmb 1999/03/31(水) 19:34:16
えっと,<SELECT>とJavaScriptの・・・話ですよね>>TOMさん

そういや,上のソースですがもっと短くできましたね。ループ抜けた時点での
WritePosがそのままselectname.lengthと同じのはずだから(最後に++
されて),DelCountなんて変数を作る必要もなくて。
そうするとif文もtrueでなくfalseの場合(!selectname...)で書いて,if文を抜けた後に必ず
selectedをfalseにすれば・・・。
あと,それからこの場合は等価だけど,厳密にはi = 0からのスタートでは
なくて i = WritePos からでしたね。あらかじめWritePos = selectedIndex
にしておく手もあったなぁ。

たこすけ 1999/04/01(木) 12:35:23
エレガント対決です(笑)

function func(selectname){
for (i = selectname.length; i > 0; i--){
selectname.options[selectname.selectedIndex] = null;
}
}

引数はTmbさんと同じです。動作保証をしていないのが欠点(←オイオイ)

あと勝手に質問なんですけど
> あらかじめWritePos = selectedIndexにしておく手もあったなぁ。
これは複数選択された場合、selectedIndexが最小値を返すからですよね。

Tmb 1999/04/01(木) 13:27:33
>for (i = selectname.length; i > 0; i--){
>selectname.options[selectname.selectedIndex] = null;

うわーっ,これはやられた (^^) まさかこの手があったとは。
NN3.0でばっちり動作しました。この勝負,僕の完敗です。
#よーし,次こそは。<<こりないやつ(笑)

>・・・selectedIndexが最小値を返すから・・・
その通りです。でも全ての項目が非選択のときの例外指定がもしかしたら
必要だったかも(自分のは確認してないのです (^^;)

Tmb 1999/04/01(木) 13:44:03
ささやかな反撃(笑)

非選択のときのselectedIndexは-1を返すようです(いつものようにNN3で確認)
そこでforの代わりに
while (selectname.selectedIndex != -1) {
で回していくとループ回数が減ってスピードアップ・・・って
何百項目もなけりゃ変わらないか (^^;;;

たこすけ 1999/04/01(木) 14:26:52
わ〜い、と喜んだのも束の間
IE4と5でエラーが出ちゃいました。
エラーが出ても動作はちゃんとしてたので気付かんかった。
#わかり難いよIE5のエラーメッセージ

エラー回避版はコチラ
function func(selectname){
for (i = selectname.length; i > 0; i--){
if(selectname.selectedIndex != -1){
selectname.options[selectname.selectedIndex] = null;
}
}
}

こうすると何故かエラーが出ません。
しかしエレガントさに欠けてしまったので
この勝負は引き分けでどうでしょう?Tmbさん。

#質問者さんそっちのけでチャット状態ですね

Tmb 1999/04/01(木) 14:36:41
whileループの方でもエラーでますか?

元のたこすけさんのアルゴリズムで気になったのは,選択されてた項目が
すべて消された後,selectedIndexが-1になったとき,options[-1]を
nullにする,という命令が出ることです。NNではこれは無視されるみたい
なので問題ないのですが,IEでエラーになるのはそこらへんの問題では
ないでしょうかね?

while文の場合はdo〜whileと違って,最初から条件がfalseなら,
ステートメントを1回も実行せずにループを抜けるみたいなので,
実はこの問題(というかNNでは単に「気持悪い」だけなんだけど)も
回避できると思っていたのですが。
#まさかwhileの仕様まで違うなんてことはないよね?

たこすけ 1999/04/01(木) 14:39:07
失礼、さっきの発言を書いたのはTmbさんの反撃の前でした。
#ラウンジ常駐なものでして (^^;;
> while (selectname.selectedIndex != -1) {
これを早速頂いて

エレガントに復活版はコチラ
function func(selectname){
while (selectname.selectedIndex != -1) {
selectname.options[selectname.selectedIndex] = null;
}
}

いや〜、人様のスクリプトを盗むのは気持ちが良いな〜(←外道)
Tmbさんが居なければ作れなかったので、勝負は無効にしましょう
#ていうかこのままだと確実に負けそうなので・・・(笑)

たこすけ 1999/04/01(木) 14:42:35
度々失礼、言い訳ですが
> たこすけ 1999/04/01(木) 14:39:07
この書き込みは
> Tmb 1999/04/01(木) 14:36:41
これ以前に書きました。

> whileループの方でもエラーでますか?
でません。でません。全然でません。
#私の完敗で〜す。(涙)

Tmb 1999/04/01(木) 15:26:05
>>whileループで・・・
エラー出なくて安心しました(笑) 僕の方も書き込むタイミングが早すぎました。

>エレガントに復活版・・・
いやぁ,美しくなったなぁ。あれがたった2行のステートメントでいけるなんて。
しかし,ホントoption = null というのは目から鱗でした。こんな使い途があった
なんて知らなかった。
というわけで,もし僕の最初のスクリプトを参考にして使っているなら,できれば
たこすけさんの復活版にしてください>TOMさん

#これだけきれいなのがあると,効率の悪いスクリプトを紹介したのが恥ずかしい
#のです (^^;;;;

[上に] [前に] [次に]