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

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

ただいまの
回答率

90.40%

  • JavaScript

    18136questions

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

  • HTML

    9957questions

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

  • Windows

    1583questions

    Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

  • Internet Explorer

    304questions

    Internet Explorer(IE;MSIE)はマイクロソフトが開発したウェブブラウザです。Microsoft Windowsに組み込まれています。

単数か複数かを判断してチェックするプログラム

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 458

culuculu

score 44

親子関係にあるチェックボックスで親のチェックボックスを選択した際に以下の動作を行うプログラムを作成したいと考えています。

①親のチェックボックスを選択した際に、子のチェックボックスが単数の場合は子のチェックボックスが自動的に選択される。(親と子の選択が連動される。)
②親のチェックボックスを選択した際に、子のチェックボックスが複数の場合は子のチェックボックスが非選択になる。(親と子の選択が連動されない。)

<具体例>------------------------------------------------------------------
■単数の場合               ■複数の場合
☑親チェック               ☑親チェック
☑子チェック               □子チェック □子チェック

<説明>
■単数の場合
①親にチェックを入れる。
②子が単数なので自動的にチェックする。

■複数の場合
①親にチェックを入れる。
②子が複数なので自動的にチェックしない。
(子にチェックを入れたい場合は、ユーザがブラウザ上からクリックしてチェックを入れる必要がある。)


現時点での自身のプログラム内容は下記のようになっています。

<!DOCTYPE HTML>

<html lang="ja">

<head>

<META http-equiv="Content-Type" content="text/html; charset=Shift_JIS">

<META http-equiv="Content-Script-Type" content="text/javascript">

<title>タイトル</title>

<script type="text/javascript">

<!--

function checkParent(obj) {

var parentCheck = obj.checked;

var group = "group_" + obj.id;

var oInputs = document.getElementById(group).getElementsByTagName("input");

for (var i = 0; i < oInputs.length; i++) {

if (oInputs[i].getAttribute("type") == "checkbox") {

if(i==oInputs.length[0]){

oInputs[i].checked = parentCheck;

} else {

document.Form.elements["obj"].checked = false ;

}

}

}

function checkChild(obj) {

var childId = obj.id;

var parentId = childId.slice(0,8);

var parentId = document.getElementById(parentId);

var childCheck = childId.checked;

if(!childCheck) {

parentId.checked = false;

}

}

//>

</script>

</head>

<body>

<form>

<div id = "check_group">
<div id="group_check_01">

<label for="check_01">親チェック<input type="checkbox" value="checkbox" id="check_01" onClick="checkParent(this);"></label><br>

<label for="check_0101">子チェック1<input type="checkbox" value="checkbox" id="check_0101" onClick="checkChild(this)"></label><br>

<label for="check_0102">子チェック2<input type="checkbox" value="checkbox" id="check_0102" onClick="checkChild(this)"></label><br>

</div>


<div id="group_check_02">

<label for="check_02">親チェック<input type="checkbox" value="checkbox" id="check_02" onClick="checkParent(this);"></label><br>

<label for="check_0201">子チェック1<input type="checkbox" value="checkbox" id="check_0201" onClick="checkChild(this)"></label><br>

</div>
</div>

</form>

</body>

</html>

htmlに記載されている子のチェックボックスのinputタグ内の末尾に"checked"と記述することで解消される問題でもあります。

しかし、親チェックボックスの数が増えてくると逐一、子のチェックボックスが単数のものに対して"checked"と記述していくのはミスの発生や効率面でも良くないと考えました。(保守性の問題)

そのため今回のようなJavascriptを用いて自動的に単数か複数かを判断して選択するプログラムを作成したいと考えました。

下記のサイトを参考にしてプログラムを作成しているのですが
自身の思うようなプログラムが作れません。
少しでもわかる方はヒントや参考サイトでも構いませんので
教えていただけると助かります。
よろしくお願い致します。

■参考サイト:
http://d.hatena.ne.jp/osakana_21/20080416/1208330846
https://oshiete.goo.ne.jp/qa/1392550.html

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • unz.hori

    2018/02/19 11:31

    ②の仕様が良くわかりません。親がチェックされた時に子は全て非チェック状態にするということですか?

    キャンセル

  • culuculu

    2018/02/19 11:36

    ご質問ありがとうございます。はい。その通りです。例えば上記のプログラムの<div id="group_check_01">内にある親がチェックされてもそのdivタグ内の子は非チェック状態にするイメージです。説明不十分で申し訳ありません。よろしくお願い致します。

    キャンセル

  • x_x

    2018/02/19 16:05

    結局のところ、子が複数ある場合の親には意味がないと思っていいのでしょうか?

    キャンセル

  • culuculu

    2018/02/19 16:11

    申し訳ありません。言われるまで気づけませんでした。自身の言い方が不適切でした。その通りだと思います。子が複数ある場合は親との関係性はありません。子が単数の場合と比較すると単数と複数との違いが分かりやすくなるかなと考えて記載していました。

    キャンセル

回答 3

checkベストアンサー

+1

よっ!

問題点だけを試してみました。

①親のチェックボックスを選択した際に、子のチェックボックスが単数の場合は子のチェックボックスが自動的に選択される。
②親のチェックボックスを選択した際に、子のチェックボックスが複数の場合は子のチェックボックスが非選択になる。(非チェックになる。)

ただcheckParentのFuncを直しましたが、正直に、Culuculuさんのコーディングはもうちょっと綺麗に変更することが出来ます。

function checkParent(obj) {
        var parentCheck = obj.checked;
        var parentId = obj.id;

        var oInputs = []
        var getInput = true     
        var i = 1;
        while(getInput == true) {
                var childId = i
                if(i < 10) {
                        childId = '0'+childId
                }
                var id = parentId+childId
                var input = document.getElementById(id)

                if(input) {
                        oInputs.push(input)
                        i++
                } else {
                        getInput = false
                }
        }
        if(!oInputs.length) return false

        oInputs.map(function(input) {
                input.checked = parentCheck
        })
        return false
}

 提案です

同じculuculuさんのコードの構造で作り直してみて、こうなります。

<!DOCTYPE HTML>

<html lang="ja">
<head>
        <META http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
        <META http-equiv="Content-Script-Type" content="text/javascript">
        <title>タイトル</title>

        <script type="text/javascript">
                function checkParent(obj) {
                        var parentCheck = obj.checked;
                        var parentId = obj.id;

                        var oInputs = document.querySelectorAll('[check-parent="'+parentId+'"]')
                        if(!oInputs.length) return false

                        for(var i in oInputs) {
                                var input = oInputs[i]
                                input.checked = parentCheck
                        }
                        return false
                }
                function checkChild(obj) {
                        if(obj.checked) return false

                        var parentId = obj.getAttribute('check-parent')
                        var input = document.getElementById(parentId);
                        input.checked = false;
                        return false
                }
                </script>
</head>

<body>
        <form>
                <div id="check_group">
                        <div id="group_check_01">
                        <label for="check_01">親チェック<input type="checkbox" value="checkbox" id="check_01" onClick="checkParent(this);"></label><br>
                        <label for="check_0101">子チェック1<input type="checkbox" value="checkbox" id="check_0101" check-parent="check_01" onClick="checkChild(this)"></label><br>
                        <label for="check_0102">子チェック2<input type="checkbox" value="checkbox" id="check_0102" check-parent="check_01" onClick="checkChild(this)"></label><br>

                </div>

                <div id="group_check_02">
                        <label for="check_02">親チェック<input type="checkbox" value="checkbox" check-parent="check_02" id="check_02" onClick="checkParent(this);"></label><br>
                        <label for="check_0201">子チェック1<input type="checkbox" value="checkbox" check-parent="check_02" id="check_0201" onClick="checkChild(this)"></label><br>
                </div>
        </form>

</body>
</html>

サンプルをご覧ください : http://study.jeromedupuis.net/teratail/114136/

:)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/02/19 15:58

    function checkParent(obj) {
    var parentCheck = obj.checked;
    var parentId = obj.id;

    var oInputs = []
    var getInput = true
    var i = 1;
    while(getInput == true) {
    var childId = i
    if(i < 10) {
    childId = '0'+childId
    }
    var id = parentId+childId
    var input = document.getElementById(id)

    if(input) {
    oInputs.push(input)
    i++
    } else {
    getInput = false
    }
    }
    if(oInputs.length > 1) return false

    oInputs.map(function(input) {
    input.checked = parentCheck
    })
    return false
    }

    oInputs.lengthは1以上の場合に、checked = trueを行わないです。

    キャンセル

  • 2018/02/19 16:06

    回答してくださり、ありがとうございます。
    サンプルを拝見させて頂いたのですが複数のチェックボックスに対してもチェックが入っています。
    質問投稿の本文を修正(具体例の追加)を行ったため確認していただけると助かります。

    キャンセル

  • 2018/02/19 16:10

    具体例の追加の通りに、更新しましたが?
    http://study.jeromedupuis.net/teratail/114136/
    ちゃんと理解出来てないかもしれません。

    キャンセル

  • 2018/02/19 16:28

    申し訳ありません。教えていただいたURLからだと正しく動作しなかったのですが
    自身のデスクトップ上でファイルを新規に作り、ブラウザ上に表示させると正常に動作しました。
    原因はわかりませんがこのプログラムは正しく動作していました。
    ありがとうございます。

    キャンセル

+1

仕様に疑問がありますが、言葉通りならこう。

  document.addEventListener('change', function(event) {
    var target = event.target;
    if (!target.checked) {
      return true;
    }

    var id = target.id;
    if (!id) {
      return true;
    }

    var child = document.querySelectorAll('[id^="' + id + '"]');
    for (var i = 0, len = child.length; i < len; i++) {
      if (child[i] === target) {
        continue;
      }

      child[i].checked = len === 2;
    }

    return true;
  }, false);

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/02/19 16:12

    ありがとうございます。
    自身の望んでいる結果になっています。

    キャンセル

0

子が複数チェックされていて、親がチェックしたら子のチェックが外れるというのは
親がチェックされているけど子はチェックされていないという状態ですので
できないことはないですが仕様がおかしくないですか

普通はこんな感じでは?

  • 子がすべてチェックされていれば親はチェックがはいり
  • 子が一つでもチェックが外れたら親のチェックがはずれる
  • 親がチェックしたら子はすべてチェック

 sample

一応指定通りに書くとこんな感じ

window.addEventListener('DOMContentLoaded', function(e){
  document.querySelector('[type=checkbox][name=parent]').addEventListener('change',function(e){
    var flg=e.target.checked;
    var len=document.querySelectorAll('[type=checkbox][name=child]:checked').length;
    Array.prototype.forEach.call(document.querySelectorAll('[type=checkbox][name=child]'),function(x){
      if(flg) x.checked=(len>=2);
    });
  });
});
<input type="checkbox" name="parent"><br>
<input type="checkbox" name="child">子1
<input type="checkbox" name="child">子2
<input type="checkbox" name="child">子3
<input type="checkbox" name="child">子4

 別解

ごめんなさい、国語力の問題なので、質問を読み違えていたかもしれません。
もし親のチェックボックスの変更で、子が一つしかないときは連動、
子が複数あるときは非連動と読めばこんな感じですかね?

※とりあえず今回はjQueryで処理します
仕様があっているならピュアなjavascriptに書き下すことも考えます

$(function(){
  $('input[type=checkbox]').filter(function(){
    return $(this).attr('id').match(/^check_\d{2}$/);
  }).on('change',function(){
    var flg=$(this).prop('checked');
    var pid=$(this).attr('id');
    var child=$('input[type=checkbox]').filter(function(){
      var reg=new RegExp("^"+pid+"[0-9]{2}$",'g');
      return $(this).attr('id').match(reg);
    });
    child.prop('checked',flg && child.length==1);
  });
});
<div id="group_check_01">
<label for="check_01">親チェック<input type="checkbox" value="checkbox" id="check_01"></label><br>
<label for="check_0101">子チェック1<input type="checkbox" value="checkbox" id="check_0101"></label><br>
<label for="check_0102">子チェック2<input type="checkbox" value="checkbox" id="check_0102"></label><br>
</div>
<div id="group_check_02">
<label for="check_02">親チェック<input type="checkbox" value="checkbox" id="check_02"></label><br>
<label for="check_0201">子チェック1<input type="checkbox" value="checkbox" id="check_0201"></label><br>
</div>
</div>


ちなみに今回の親子関係をidで紐付けるのはちょっと面倒ですね
たとえば親子別々にclassをふって同じdiv内で親子関係を保つとかですかね

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/02/19 11:38

    私もちょっと質問者の②の仕様には疑問を感じました。

    キャンセル

  • 2018/02/19 11:59

    今回参考サイトにhttp://d.hatena.ne.jp/osakana_21/20080416/1208330846
    を指定したのは自身が比較的理解しやすいプログラム内容であると判断し、このプログラムに①②の仕様を反映させたいと考えました。
    本来であれば仕様に適したプログラム内容にすべきであったと思います。
    上記のサイトではすべてチェックする/すべてチェックを外すプログラムが書かれていますが自身の作りたいプログラムは①②の仕様を満たしているプログラムです。
    正確な仕様を記していませんでした。
    申し訳ありません。

    キャンセル

  • 2018/02/19 12:03

    うーんと②の非選択になる。(自動的にチェックが付いている状態。) って矛盾してないですか?非選択=非チェックって事ではないんですか?結局どっちか良く分からないです。

    キャンセル

  • 2018/02/19 12:19

    とりあえず追記したsampleどおりで間違いないならそれで採用してください
    あと親のチェックを外したときの処理はどうするかもわかりませんね
    (今回は親のチェックが外れても何もしないという仕様です)

    キャンセル

  • 2018/02/19 13:47

    >unz.hori
    申し訳ありません。文章修正が間違えていました。非選択=非チェックという認識です。

    >yambejp
    sampleの作成ありがとうございます。
    自身のブラウザ上で正しく動作できていないためプログラムの考察を行います。(子のチェックボックスが単数の場合にチェックが入らない状態。恐らく、
    if(flg) x.checked=(len>=2);
    上記のコードのlenの範囲を変更するとうまくいく気がしています。)
    わからない箇所があれば質問してもよろしいでしょうか。
    親のチェックが外れても何もしないという仕様で問題ありません。

    キャンセル

  • 2018/02/19 14:23

    私の理解が追いついていない気がしてきました。
    別の視点で追記してあります。
    逆に、具体的に例示されたチェックボックスをつかって
    この状態の時にこうするとこうなる・・・のような
    書き方をしてもらったほうがよいかもしれません

    キャンセル

  • 2018/02/19 15:28

    申し訳ありません。
    文字数が多くなりすぎてしまったと感じてなるべく簡潔に書いてしまいました。

    具体例を質問の本文に記載します。

    キャンセル

同じタグがついた質問を見る

  • JavaScript

    18136questions

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

  • HTML

    9957questions

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

  • Windows

    1583questions

    Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

  • Internet Explorer

    304questions

    Internet Explorer(IE;MSIE)はマイクロソフトが開発したウェブブラウザです。Microsoft Windowsに組み込まれています。