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

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

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

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

1回答

525閲覧

2つ以上のラジオボタンの条件を同時に満たすフィルタをつくりたい

maki_oden

総合スコア10

JavaScript

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2022/09/05 08:47

実現したいこと

ふたつのラジオボタンをそれぞれ選択した際、
リストの中から「AかつB」のものが抽出されている状態にしたいです。

ラジオボタンAは「誰が」、
ラジオボタンBは「何する」といった感じで
それぞれ選択したものが項目の中から残るイメージにしたいです。

どうぞ、よろしくお願いいたします。

発生している問題

javascriptに問題があると思うのですが、
片方のラジオボタンで隠したものが
もう片方のラジオボタンを押下すると表示されてしまいます。

<!-- HTML --> <ul> <li><input type="radio" id="All" name="who" value="All" checked> <label for="All">All</label></li> <li><input type="radio" id="CharaA" name="who" value="CharaA"> <label for="CharaA">Aさん</label></li> <li><input type="radio" id="CharaB" name="who" value="CharaB"> <label for="CharaB">Bさん</label></li> </ul> <ul> <li><input type="radio" id="All" name="what" value="All" checked> <label for="All">All</label></li> <li><input type="radio" id="Wark" name="what" value="Wark"> <label for="Wark">歩く</label></li> <li><input type="radio" id="Song" name="what" value="Song"> <label for="Song">歌う</label></li> </ul> <ul class="filter"> <li class="target" data-category="CharaA Wark"> <p>Aさんが歩く</p> </li> <li class="target" data-category="CharaB Wark"> <p>Bさんが歩く</p> </li> <li class="target" data-category="CharaA Song"> <p>Aさんが歌う</p> </li> <li class="target" data-category="CharaB Song"> <p>Bさんが歌う</p> </li> </ul>
<script> window.addEventListener('DOMContentLoaded', function(){ const input_categories = document.querySelectorAll("input[name=who]"); const targets = document.querySelectorAll(".target"); for(let input_category of input_categories) { input_category.addEventListener('change',function(){ for(let target of targets) { target.style.setProperty('display', 'block'); } if( this.checked ) { if(this.value !== 'All') { const not_checked_categories = document.querySelectorAll('.target:not([data-category~=' + '"' + this.value + '"])'); for(let not_checked_category of not_checked_categories) { not_checked_category.style.setProperty('display', 'none'); } } } }); } }); window.addEventListener('DOMContentLoaded', function(){ const input_categories = document.querySelectorAll("input[name=what]"); const targets = document.querySelectorAll(".target"); for(let input_category of input_categories) { input_category.addEventListener('change',function(){ for(let target of targets) { target.style.setProperty('display', 'block'); } if( this.checked ) { if(this.value !== 'All') { const not_checked_categories = document.querySelectorAll('.target:not([data-category~=' + '"' + this.value + '"])'); for(let not_checked_category of not_checked_categories) { not_checked_category.style.setProperty('display', 'none'); } } } }); } }); </script>

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

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

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

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

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

guest

回答1

0

ベストアンサー

まずHTMLのほうで、id="All"inputが2つあるので、以下のように who-Allwhat-All に修正しておきます。

diff

1- <li><input type="radio" id="All" name="who" value="All" checked> 2- <label for="All">All</label></li> 3+ <li><input type="radio" id="who-All" name="who" value="All" checked> 4+ <label for="who-All">All</label></li>

diff

1- <li><input type="radio" id="All" name="what" value="All" checked> 2- <label for="All">All</label></li> 3+ <li><input type="radio" id="what-All" name="what" value="All" checked> 4+ <label for="what-All">All</label></li>

(ただし下記のJSのコードでは id は使用しません。)

JavaScriptのコードはたとえば以下のような感じでいけるのではないかと思います。(DOMContentLoadedハンドラの設定は1個で事足ります)

javascript

1window.addEventListener('DOMContentLoaded', function(){ 2 3 const handleChange = () => { 4 const [whoValue, whatValue] = 5 [...document.querySelectorAll('input[type=radio]:checked')].map(e => e.value); 6 document.querySelectorAll('.target').forEach(item => { 7 const [who, what] = item.dataset.category.split(' '); 8 const isDisplayed = ['All', who].includes(whoValue) && ['All', what].includes(whatValue); 9 item.style.display = isDisplayed ? 'list-item' : 'none'; 10 }) 11 }; 12 13 document.querySelectorAll('input[type=radio]').forEach(radio => { 14 radio.addEventListener('change', handleChange); 15 }); 16 17}); 18 19

追記(1)

上記で回答したコードのHTMLを少し修正すると、JSの一部がより簡単にできます。

まず HTML のほうのフィルター条件部分の2つの <ul><form>・・・</form>で囲みます。

diff

1+ <form> 2 <ul> 3 <li><input type="radio" id="who-All" name="who" value="All" checked> 4 <label for="who-All">All</label></li> 5 <li><input type="radio" id="CharaA" name="who" value="CharaA"> 6 <label for="CharaA">Aさん</label></li> 7 <li><input type="radio" id="CharaB" name="who" value="CharaB"> 8 <label for="CharaB">Bさん</label></li> 9 </ul> 10 <ul> 11 <li><input type="radio" id="what-All" name="what" value="All" checked> 12 <label for="what-All">All</label></li> 13 <li><input type="radio" id="Wark" name="what" value="Wark"> 14 <label for="Wark">歩く</label></li> 15 <li><input type="radio" id="Song" name="what" value="Song"> 16 <label for="Song">歌う</label></li> 17 </ul> 18+ </form>

そうすると、JSのほうでフィルター条件の値となる whoValuewhatValue を得るところが少し簡単にできます。

diff

1- const [whoValue, whatValue] = 2- [...document.querySelectorAll('input[type=radio]:checked')].map(e => e.value); 3+ const [whoValue, whatValue] = [...new FormData(document.forms[0]).values()];

追記(2)

追記(1) に書いたようにHTMLのフィルタ条件部分(二つの<ul>・・・</ul>) を <form>・・・</form> で囲むと、javascriptのほうをさらに詰めることができ、以下で意図した動作になると思います。

javascript

1window.addEventListener('DOMContentLoaded', function(){ 2 3 document.forms[0].addEventListener('change', () => { 4 document.querySelectorAll('.target').forEach(item => { 5 const categories = item.dataset.category.split(' '); 6 const isDisplayed = ['who', 'what'].every( 7 (name, i) => ['All', categories[i]].includes(document.forms[0][name].value) 8 ); 9 item.style.display = isDisplayed ? 'list-item' : 'none'; 10 }) 11 }); 12 13}); 14

投稿2022/09/05 09:42

編集2022/09/05 12:29
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

maki_oden

2022/09/05 10:47

ありがとうございます!! ご返信いただいた記述で完璧に動作しました!
退会済みユーザー

退会済みユーザー

2022/09/05 12:25

よかったです!さらにコードを詰める案を追記2に書きました。参考までにどうぞ。
maki_oden

2022/09/05 12:59

ありがとうございます! もし可能でしたらでかまいませんので、1点ご教授いただけませんでしょうか? 結果表示するリストのdata-categoryに、同一のnameの二つの値が指定されている場合 どちらを指定しても表示するようにできますでしょうか? 例:ラジオボタンのAさん(CharaA)でもBさん(CharaB)でも以下を表示させたい。 <li class="target" data-category="CharaA CharaB Wark"> <p>AさんとBさんが歩く</p></li> 何卒宜しくお願いいたします!必要であれば別の質問板をつくらせていただきます。
退会済みユーザー

退会済みユーザー

2022/09/05 13:20 編集

はい。要件は理解できましたが、それを実現するには data-category 属性の値は "CharaA CharaB Wark" ではないほうがよいです。 ではどうするかといえば2案ほどあります。 (1) who部分とwhat部分とを分ける区切りに、半角スペース以外のたとえばスラッシュにするとして <li class="target" data-category="CharaA CharaB/Wark" > にするか、 (2) いっそ data属性を二つにして、 <li class="target" data-who="CharaA CharaB" data-what="Wark" > にしたほうがよいです。 これらのいずれか( どっちかといえば、javascript書く人からすると (2)のほうが楽な気がします。) にした上で、別の質問として投稿していただければ、(私も見ますが)他の人からより早い(or良い)回答もあるかもしれないので、よろしいかと思います。
maki_oden

2022/09/05 13:29

最後までご丁寧にありがとうございます! 言葉でしか感謝を伝えられないのが残念です!ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問