質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

3回答

1113閲覧

JavaScriptで2つのセレクトボックスを連動させたい

onakahetta

総合スコア23

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2019/01/21 00:56

編集2019/01/21 07:11

前提・実現したいこと

お世話になっております。
Laravelでフォームを作っており、DBから取得したリストを2つのセレクトボックスに表示させているのですが
一つ目のセレクトボックスを選択したらそれと関連するもののみ二つ目のセレクトボックスに表示させる動きをjQueryを使わず素のJavaScriptのみで実装したいです。
下のソースコードで言うと、corporationセレクトボックスにはgroupセレクトボックスで選択したoptionのvalueと同じgroup_idをdata-valに持つoptionのみ表示させたいです。

該当のソースコード

HTML

1 2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 3<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"> 4<head> 5<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 6<meta http-equiv="Content-Style-Type" content="text/css; charset=UTF-8" /> 7<meta http-equiv="Content-Script-Type" content="text/javascript; charset=UTF-8" /> 8<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" /> 9<link rel="stylesheet" type="text/css" href="http://192.168.73.10/wired_admin/default.css" /> 10<script type="text/javascript" src="http://192.168.73.10/javascripts/vendor/prototype.js"></script> 11<script type="text/javascript" src="http://192.168.73.10/javascripts/vendor/scriptaculous/scriptaculous.js"></script> 12<link rel="stylesheet" type="text/css" href="http://192.168.73.10/wired_admin/themes/classic/theme.css" /> 13<script type="text/javascript" src="http://192.168.73.10/wired_admin/themes/classic/theme.js" charset="UTF-8"></script> 14<script type="text/javascript" src="http://192.168.73.10/javascripts/application.js"></script> 15<link rel="stylesheet" type="text/css" href="http://192.168.73.10/wired_admin/themes/classic/member.css" /> 16<title>管理システム</title> 17!-- <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> --> 18<script type="text/javascript"> 19 20 Event.observe(window, 'load', function() { 21 22 disableCoporations(); 23 }); 24 25 26 function disableCoporations() { 27 if ($('p_s_service_account_group_id').value == 3 || $('p_s_service_account_group_id').value == 7) { 28 $('p_m_groups').disabled = false; 29 $('p_m_corporation_id').disabled = false; 30 } else if ($('p_s_service_account_group_id').value == 6) { 31 $('p_m_groups').disabled = false; 32 $('p_m_corporation_id').disabled = true; 33 $('p_m_corporation_id').value = "all"; 34 } else { 35 $('p_m_groups').disabled = true; 36 $('p_m_groups').value = "all"; 37 $('p_m_corporation_id').disabled = true; 38 $('p_m_corporation_id').value = "all"; 39 } 40 } 41 42 window.addEventListener('DOMContentLoaded', function(e){ 43 var cl=document.querySelector('#p_m_corporation_id').cloneNode(true); 44 document.querySelector('#p_m_groups').addEventListener('change',function(e){ 45 var t=e.target; 46 [].forEach.call(document.querySelectorAll('#p_m_corporation_id option'),function(x){ 47 x.parentNode.removeChild(x); 48 }); 49 [].filter.call(cl.querySelectorAll('option'),function(x){ 50 return x.value=="all" || t.value=="all" || x.getAttribute("data-val")==t.value; 51 }).forEach(function(x){ 52 document.querySelector('#p_m_corporation_id').appendChild(x.cloneNode(true)); 53 }); 54 }); 55 }); 56 57 // $(function($) { 58 // var $corporation = $('p_m_corporation_id'); 59 // var original = $corporation.html(); 60 61 // $('#p_m_groups').change(function() { 62 // var val1 = $(this).data('val'); 63 64 // $corporation.html(original).find('option').each(function() { 65 // var val2 = $(this).data('val'); 66 // if (val1 != val2) { 67 // $(this).not(':first-child').remove(); 68 // } 69 // }); 70 71 // if ($(this).val() === '') { 72 // $corporation.attr('disabled', 'disabled'); 73 // } else { 74 // $corporation.removeAttr('disabled'); 75 // } 76 77 // }); 78 // }); 79 80</script> 81</head> 82<body class="logged_in"> 83 84<div id="container"> 85 <div id="main"> 86 <div id="content"> 87 <h2>新規登録</h2> 88 <form method="post" action="/create_confirm"> 89 <table class="usual"> 90 <tr> 91 <th style="width:100px">アカウント<span class="required">*</span></th> 92 <td style="width:300px"><input type="text" name="account" value="" style="ime-mode:disabled; width: 150px;"></td> 93 </tr> 94 <tr> 95 <th style="width:100px">ニックネーム<span class="required">*</span></th> 96 <td style="width:300px"><input type="text" name="name" value="" style="ime-mode:disabled; width: 150px;"></td> 97 </tr> 98 <tr> 99 <th>権限グループ<span class="required">*</span></th> 100 <td> 101 <select name="group" id="group" class="group"> 102 <option value="all"></option> 103 <option value="0">グループなし</option> 104 <option value="1" >テストグループ1</option> 105 <option value="2" >テストグループ2</option> 106 <option value="3" >テストグループ3</option> 107 <option value="4" >テストグループ4</option> 108 <option value="5" >テストグループ4</option> 109 <option value="6" >テストグループ5</option> 110 <option value="7" >テストグループ6</option> 111 <option value="13" >テストグループ7</option> 112 <option value="14" >テストグループ8</option> 113 </select> 114 115 <select name="corporation" id="corporation" class="corporation"> 116 <option value="all"></option> 117 <option value="584" data-val="1" >テスト法人1-1</option> 118 <option value="585" data-val="0" >テスト法人1-2</option> 119 <option value="586" data-val="1" >テスト法人2-1</option> 120 <option value="587" data-val="14" >テスト法人2-2</option> 121 <option value="588" data-val="5" >テスト法人3-1</option> 122 <option value="589" data-val="13" >テスト法人4-1</option> 123 <option value="590" data-val="6" >テスト法人4-2</option> 124 <option value="591" data-val="7" >テスト法人5-1</option> 125 <option value="592" data-val="7" >テスト法人5-2</option> 126 <option value="593" data-val="1" >テスト法人6-1</option> 127 <option value="594" data-val="2" >テスト法人6-2</option> 128 </select> 129 </td> 130 </tr> 131 </table> 132 <p> 133 <input type="button" value=" キャンセル " onclick="location.href='list'"> <input type="submit" value=" 登録 "> 134 <input type="hidden" name="id" value=""> 135 </p> 136 </form> 137 </div> 138 </div> 139</div> 140</body> 141</html> 142 143

試したこと

jQueryだとこのようなコードになりました。

JavaScript

1$(function() { 2 var $corporation = $('#corporation_id'); 3 var original = $corporation.html(); 4 5 $('#group').change(function() { 6 var val1 = $(this).data('val'); 7 8 $corporation.html(original).find('option').each(function() { 9 var val2 = $(this).data('val'); 10 if (val1 != val2) { 11 $(this).not(':first-child').remove(); 12 } 13 }); 14 15 if ($(this).val() === '') { 16 $corporation.attr('disabled', 'disabled'); 17 } else { 18 $corporation.removeAttr('disabled'); 19 } 20 21 }); 22});

JavaScriptで実装する方法も調べたのですが、optionをJS内で生成しているものばかりで、
グループ分けされていないリストを制御する方法が分からなかったため質問させていただきました。

初心者なので説明等分かりにくい箇所が多いかもしれませんが、ご教授頂けますと幸いです。
よろしくお願い致します。

追記:
同じテンプレート内の別の箇所でJavaScriptを使っている箇所があり、
上記jQueryをテンプレート内で実行したところそのJavaScriptも動かなくなってしまったので、
JavaScriptしか使えないのだと思いこの質問をしました。
jQueryの実行確認は別のHTMLファイルで行いました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2019/01/21 01:00

動的にリストを生成されているのでしたら、サンプルデータかVIEWファイルの内容ではなくブラウザから参照して「ソースを表示」した際の情報を提示されたほうが再現確認・調整がしやすくなります。 また、jQueryも結局は裏でPure JavaScriptで組まれているので実現できている方法があるのでしたら問題はないように思うのですが。(やることはどっちでも同じです)
onakahetta

2019/01/21 01:30

ご指摘ありがとうございました。ソースコードを修正しました。 説明が足りず申し訳ございませんが、同じテンプレート内の別の箇所でJavaScriptが使われているところがあり、上記jQueryを同テンプレート内で実行したところ元のJavaScriptも動かなくなったので、このjQueryは同じソースをHTMLファイルに写したもので実行して動いたという次第です。 そのため、JavaScriptでないとうまくいかないのだと思いこの質問をさせていただきました。
m.ts10806

2019/01/21 04:18

動かないということは何かしらエラーがでているはずで、エラーを確認してきちんと作動させることが先決かと思います。jQueryはJavaScriptで書かれているため、jQuery本体が正しく読み込めているのであれば動かないと言うことはありません。(文法エラーだとすればそこはそこでなおすべきですし)
onakahetta

2019/01/21 06:17

コメントありがとうございます。 GoogleAPIのjQueryを使おうとしていたのですが、こちらをインポートするとJavaScriptが使えなくなるようでした。インポートしている行をコメントアウトするとJavaScriptは動作するのですが、jQueryが動かなくなります。 原因としてこういうことはあるのでしょうか?
m.ts10806

2019/01/21 06:23 編集

「GoogleAPIのjQuery」が何か分かりませんが、(CDNのことだろうか・・・) エラーも何も出てないのでしょうか?jQuery本体がバッティングしているようにも思いますが。 実際のコードを提示されたほうが良さそうです。(できればブラウザ表示したときのHTMLコードで)
guest

回答3

0

allの仕様が書いていないのでなんと言えませんが、こうやります

javascript

1<script> 2window.addEventListener('DOMContentLoaded', function(e){ 3 var cl=document.querySelector('#corporation').cloneNode(true); 4 document.querySelector('#group').addEventListener('change',function(e){ 5 var t=e.target; 6 [].forEach.call(document.querySelectorAll('#corporation option'),function(x){ 7 x.parentNode.removeChild(x); 8 }); 9 [].filter.call(cl.querySelectorAll('option'),function(x){ 10 return x.value=="all" || t.value=="all" || x.dataset["val"]==t.value; 11 }).forEach(function(x){ 12 document.querySelector('#corporation').appendChild(x.cloneNode(true)); 13 }); 14 }); 15}); 16</script> 17<select name="group" id="group" class="group"> 18 <option value="all">all</option> 19 <option value="0">グループなし</option> 20 <option value="1" >テストグループ1</option> 21 <option value="2" >テストグループ2</option> 22 <option value="3" >テストグループ3</option> 23 <option value="4" >テストグループ4</option> 24 <option value="5" >テストグループ4</option> 25 <option value="6" >テストグループ5</option> 26 <option value="7" >テストグループ6</option> 27 <option value="13" >テストグループ7</option> 28 <option value="14" >テストグループ8</option> 29</select> 30 31<select name="corporation" id="corporation" class="corporation"> 32 <option value="all">all</option> 33 <option value="584" data-val="1" >テスト法人1-1</option> 34 <option value="585" data-val="0" >テスト法人1-2</option> 35 <option value="586" data-val="1" >テスト法人2-1</option> 36 <option value="587" data-val="14" >テスト法人2-2</option> 37 <option value="588" data-val="5" >テスト法人3-1</option> 38 <option value="589" data-val="13" >テスト法人4-1</option> 39 <option value="590" data-val="6" >テスト法人4-2</option> 40 <option value="591" data-val="7" >テスト法人5-1</option> 41 <option value="592" data-val="7" >テスト法人5-2</option> 42 <option value="593" data-val="1" >テスト法人6-1</option> 43 <option value="594" data-val="2" >テスト法人6-2</option> 44</select>

disabled版

単純にcorporationのoptionのdisabledを付け替えたいだけならこう
以下のみをコピペして確認してください
(なにかに組み込むとかまずは忘れてください)

javascript

1<html> 2<head> 3<script> 4window.addEventListener('DOMContentLoaded', function(e){ 5 document.querySelector('#group').addEventListener('change',function(e){ 6 var t=e.target; 7 [].forEach.call(document.querySelectorAll('#corporation option'),function(x){ 8 x.disabled=!(x.value=="all" || t.value=="all" || x.getAttribute("data-val")==t.value); 9 }); 10 }); 11}); 12</script> 13</head> 14<body> 15<select name="group" id="group" class="group"> 16 <option value="all">all</option> 17 <option value="0">グループなし</option> 18 <option value="1" >テストグループ1</option> 19 <option value="2" >テストグループ2</option> 20 <option value="3" >テストグループ3</option> 21 <option value="4" >テストグループ4</option> 22 <option value="5" >テストグループ4</option> 23 <option value="6" >テストグループ5</option> 24 <option value="7" >テストグループ6</option> 25 <option value="13" >テストグループ7</option> 26 <option value="14" >テストグループ8</option> 27</select> 28<select name="corporation" id="corporation" class="corporation"> 29 <option value="all">all</option> 30 <option value="584" data-val="1" >テスト法人1-1</option> 31 <option value="585" data-val="0" >テスト法人1-2</option> 32 <option value="586" data-val="1" >テスト法人2-1</option> 33 <option value="587" data-val="14" >テスト法人2-2</option> 34 <option value="588" data-val="5" >テスト法人3-1</option> 35 <option value="589" data-val="13" >テスト法人4-1</option> 36 <option value="590" data-val="6" >テスト法人4-2</option> 37 <option value="591" data-val="7" >テスト法人5-1</option> 38 <option value="592" data-val="7" >テスト法人5-2</option> 39 <option value="593" data-val="1" >テスト法人6-1</option> 40 <option value="594" data-val="2" >テスト法人6-2</option> 41</select> 42</body> 43</html>

※datasetはブラウザによって微妙なのでgetAttributeしておきました

jQuery版

javascript

1$(function(){ 2 $('#group').on('change',function(){ 3 var self=$(this); 4 $('#corporation option').prop('disabled',function(){ 5 return !(self.val()=="all" || $(this).val()=="all" || $(this).data('val')==self.val()); 6 }); 7 }); 8});

投稿2019/01/21 01:59

編集2019/01/21 08:19
yambejp

総合スコア114572

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2019/01/21 02:04

ちなみによほど根本から競合しない限り「 JavaScriptしか使えない」 ような状況は考えづらいです。
onakahetta

2019/01/21 02:50

ご回答ありがとうございます。 頂いたコードを実行したのですが、corporationの中身が表示されなくなってしまいました、、、 allは内部的に使うためにこの名前にしていますが要するに未選択です。説明不足で申し訳ございません。 そうなのですね!書き方が悪くて動かなかったのを使えないものだと思い込んでしまったのかもしれません。もう一度考え直してみます。
onakahetta

2019/01/21 03:33

追記もありがとうございます。何度も申し訳ございません。 disableの方でやってみて分かったのですが、groupで何を選択しても全てdisableになってしまったので、よろしければgroupのvalueとcorporationのdata-valの対応をどのように処理しているのか教えていただけますでしょうか。
yambejp

2019/01/21 03:39

一度私のソースだけコピペしてためしてください (他に何も足さず、かってになにも引かない) その上で動作が確認できたら次の段階にすすみます。 もしコピペしたのでも動作がおかしいならブラウザがおかしいのかも 別のブラウザで動作確認をお願いします
onakahetta

2019/01/21 03:51

すみません。ご丁寧にありがとうございます。 正しく動作しました。
yambejp

2019/01/21 04:41

そうなると何かと組み合わせて処理をするときに競合しているのかも しれないですね。 動作を確認しながら少しずつ機能をたしてみて判断するしかないかも。
onakahetta

2019/01/21 05:46

もう一度確認してみたところ、本番のソースでdisabledの方が動作しました! ですが最初のdisabledでない方でもう一度試したところ、頂いたソースでは正常に動いたのですが、本番の方ではgroupセレクトクリック時にUncaught TypeError: this.each is not a functionが出てしまっており動いていないようでした。 重ね重ね申し訳ないのですが、何か考えられる原因はございますでしょうか。
yambejp

2019/01/21 06:19

> groupセレクトクリック時にUncaught TypeError: this.each is not a function えーと、groupをクリックする処理は書いた覚えがありません。 指定しているのはchangeイベントなのでclickイベントでのエラーは 元ソース側の問題だと思います。 またthis.each的な表現も指定なのでこの辺も怪しいと思います
onakahetta

2019/01/21 06:36

表現が下手で申し訳ないです。クリックイベントという意味ではなくただクリック(変更)したときにという意味でした。 [].filter.call(cl.querySelectorAll('option'),function(x) この箇所でエラーが起きているようです。 this.eachはprototype.jsのNodeList.findAllにあるようですが、触っていないところなのでよく分からず、、、本当に無知ですみません泣
yambejp

2019/01/21 06:50

> prototype.js あー(汗) jQueryとは相性がわるいので厳しいですね prototype.jsを排除するところからじゃないでしょうか・・・
onakahetta

2019/01/21 07:22

そこが原因だったのですか、、、 テンプレート共通のヘッダーで読まれているので排除も難しそうです、、、
yambejp

2019/01/21 07:27

ライブラリなしのピュアなjsの挙動を阻害するようなライブラリは 害悪でしかないと思いますけどね・・・ なんらかの形でjQueryへ置き換えを模索してください (もちろんライブラリなしで頑張る手もありますが)
onakahetta

2019/01/21 07:44

そうですね、、、 勉強の機会と思って色々と試してみます。 お時間頂き本当にありがとうございました。
onakahetta

2019/01/21 08:59

jQuery版まで、ありがとうございます! こんなにスッキリ書けるのですね。勉強になります。 自己解決にしてしまい申し訳ないです。 また機会があればご教授よろしくお願い致します。
guest

0

javascript

1function handler (event) { 2 let val = event.target.value; 3 let [first, ...opts] = document.querySelectorAll ('select[name="corporation"] option'); 4 let p = first.parentNode; 5 6 ('all' === val) 7 ? opts.forEach (e => e.disabled = false) 8 : opts.forEach (e => 9 (e.disabled = e.getAttribute ('data-val') !== val) 10 ? null 11 : p.insertBefore (e, first.nextElementSibling) 12 ); 13 first.selected = true; 14} 15 16document 17 .querySelector ('select[name="group"]') 18 .addEventListener ('change', handler, false); 19

投稿2019/01/21 06:22

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

onakahetta

2019/01/21 07:14

ご回答ありがとうございます。 頂いたコードを試したのですが、 .addEventListener ('change', handler, false); の部分で Uncaught TypeError: Cannot read property 'addEventListener' of null が出てしまいます。
退会済みユーザー

退会済みユーザー

2019/01/21 07:41

document ?
guest

0

自己解決

prototype.jsとjQueryの競合が原因だったようで、以下のように書き換えて動きました。

JavaScript

1 jQuery.noConflict(); 2 3//prototype.jsのコードを記述 4 5//jQueryのコード 6 (function($) { 7 $(function() { 8 var $corporation = $('#corporation'); 9 var original = $corporation.html(); 10 11 $('#group').change(function() { 12 var val1 = $(this).val(); 13 14 $corporation.html(original).find('option').each(function() { 15 var val2 = $(this).data('val'); 16 if (val1 != val2) { 17 $(this).not(':first-child').remove(); 18 } 19 }); 20 21 if ($(this).val() === '') { 22 $corporation.attr('disabled', 'disabled'); 23 } else { 24 $corporation.removeAttr('disabled'); 25 } 26 27 }); 28 }); 29 })(jQuery)

投稿2019/01/21 08:09

onakahetta

総合スコア23

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問