JavaScriptでフォームのラジオボタンとチェックボックスの値を確認する

現在、テキストエリアだけのフォームがあるのですが、それにラジオボタンとチェックボックスを加える予定です。

【やりたいこと】
・追加する予定のラジオボタンとチェックボックスは必須項目であるため、入力されていないときはエラーを出したい。
・エラーの出し方は、現在テキストエリアでの方法と同様にしたい。

【現在のコード】
HTML
<form id="hoge" name="hoge" method="post" action="hoge.php" onsubmit="return check()">
<input type="text" name="会社名" id="name" value="" />
<p id="namealert" class="errormsg">会社名が未入力です。</p>

JavaScript
function check() {
document.getElementById("namealert").style.display="none";

x=new Boolean(false);
x = false;

if(hoge.name.value == "") {
document.getElementById("namealert").style.display="block";
hoge.name.focus();
x = true;
}
if (x) {
return false;
}else return true;
}


ちなみに、追加予定のHTMLは以下です。
ラジオボタン
<input type="radio" name="hogehoge" id="hogehoge" value="選択肢A">選択肢A
チェックボックス
<input type="checkbox" name="hogehogehoge" id="hogehogehoge" value="選択肢B">選択肢B


以上、よろしくお願い致します。

回答の条件
  • 1人50回まで
  • 登録:2018/06/02 13:58:45
  • 終了:2018/06/03 18:27:29

ベストアンサー

id:a-kuma3 No.1

a-kuma3回答回数4737ベストアンサー獲得回数20302018/06/02 14:28:11

ポイント1000pt

こんな感じでどうでしょう。
HTML + CSS

<form id="hoge" name="hoge" method="post" action="hoge.php" onsubmit="return check()">
<input type="text" name="会社名" id="name" value="" />
<p id="namealert" class="errormsg">会社名が未入力です。</p>
<br>
<input type="radio" name="hogehoge" id="hogehoge1" value="選択肢A1">選択肢A1<br>
<input type="radio" name="hogehoge" id="hogehoge2" value="選択肢A2">選択肢A2<br>
<input type="radio" name="hogehoge" id="hogehoge3" value="選択肢A3">選択肢A3<br>
<p id="radioalert" class="errormsg">選択肢Aが未入力です。</p>
<br>
<input type="checkbox" name="hogehogehoge1" id="hogehogehoge1" class="check_b" value="選択肢B1">選択肢B1<br>
<input type="checkbox" name="hogehogehoge2" id="hogehogehoge2" class="check_b" value="選択肢B2">選択肢B2<br>
<input type="checkbox" name="hogehogehoge3" id="hogehogehoge3" class="check_b" value="選択肢B3">選択肢B3<br>
<p id="checkalert" class="errormsg">選択肢Bが未入力です。</p>
<br>
<input type="submit" value="Go">
</form>

<style>
.errormsg {
    display: none;
}
</style>

javascript

function check() {
    let form = document.getElementById("hoge");
    let ok = true;
    let checked;

    // reset error message
    Array.from(form.querySelectorAll('.errormsg')).forEach(err => {
        err.style.display = "none";
    });

    // 会社名
    if (form.name.value == "") {
        document.getElementById("namealert").style.display="block";
        hoge.name.focus();
        ok = false;
    }

    // 選択肢A (radio)
    checked = Array.from(form.querySelectorAll('[name="hogehoge"]')).find(e => e.checked);
    if (! checked) {
        document.getElementById("radioalert").style.display="block";
        ok = false;
    }

    // 選択肢B (checkbox)
    checked = Array.from(form.querySelectorAll('.check_b')).find(e => e.checked);
    if (! checked) {
        document.getElementById("checkalert").style.display="block";
        ok = false;
    }

    return ok;
}

チェックボックスの方は、あるひとつのグループに複数の選択肢があって、最低でもどれかひとつを選ばなければいけない、というふうに解釈してます。
なので、name と id をユニークにして、「ひとつのグループに」という目印が欲しいので、上記では type="checkbox" に class="check_b" を指定しています。

あと、環境の指定がなかったのですが、今どきのブラウザを対象としています。

他3件のコメントを見る
id:a-kuma3

こんな感じでどうでしょう。

// Production steps of ECMA-262, Edition 6, 22.1.2.1
// Reference: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.from
if (!Array.from) {
  Array.from = (function () {
    var toStr = Object.prototype.toString;
    var isCallable = function (fn) {
      return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
    };
    var toInteger = function (value) {
      var number = Number(value);
      if (isNaN(number)) { return 0; }
      if (number === 0 || !isFinite(number)) { return number; }
      return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
    };
    var maxSafeInteger = Math.pow(2, 53) - 1;
    var toLength = function (value) {
      var len = toInteger(value);
      return Math.min(Math.max(len, 0), maxSafeInteger);
    };

    // The length property of the from method is 1.
    return function from(arrayLike/*, mapFn, thisArg */) {
      // 1. Let C be the this value.
      var C = this;

      // 2. Let items be ToObject(arrayLike).
      var items = Object(arrayLike);

      // 3. ReturnIfAbrupt(items).
      if (arrayLike == null) {
        throw new TypeError("Array.from requires an array-like object - not null or undefined");
      }

      // 4. If mapfn is undefined, then let mapping be false.
      var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
      var T;
      if (typeof mapFn !== 'undefined') {
        // 5. else      
        // 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
        if (!isCallable(mapFn)) {
          throw new TypeError('Array.from: when provided, the second argument must be a function');
        }

        // 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.
        if (arguments.length > 2) {
          T = arguments[2];
        }
      }

      // 10. Let lenValue be Get(items, "length").
      // 11. Let len be ToLength(lenValue).
      var len = toLength(items.length);

      // 13. If IsConstructor(C) is true, then
      // 13. a. Let A be the result of calling the [[Construct]] internal method of C with an argument list containing the single item len.
      // 14. a. Else, Let A be ArrayCreate(len).
      var A = isCallable(C) ? Object(new C(len)) : new Array(len);

      // 16. Let k be 0.
      var k = 0;
      // 17. Repeat, while k < len… (also steps a - h)
      var kValue;
      while (k < len) {
        kValue = items[k];
        if (mapFn) {
          A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
        } else {
          A[k] = kValue;
        }
        k += 1;
      }
      // 18. Let putStatus be Put(A, "length", len, true).
      A.length = len;
      // 20. Return A.
      return A;
    };
  }());
}

// https://tc39.github.io/ecma262/#sec-array.prototype.find
if (!Array.prototype.find) {
  Object.defineProperty(Array.prototype, 'find', {
    value: function(predicate) {
     // 1. Let O be ? ToObject(this value).
      if (this == null) {
        throw new TypeError('"this" is null or not defined');
      }

      var o = Object(this);

      // 2. Let len be ? ToLength(? Get(O, "length")).
      var len = o.length >>> 0;

      // 3. If IsCallable(predicate) is false, throw a TypeError exception.
      if (typeof predicate !== 'function') {
        throw new TypeError('predicate must be a function');
      }

      // 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
      var thisArg = arguments[1];

      // 5. Let k be 0.
      var k = 0;

      // 6. Repeat, while k < len
      while (k < len) {
        // a. Let Pk be ! ToString(k).
        // b. Let kValue be ? Get(O, Pk).
        // c. Let testResult be ToBoolean(? Call(predicate, T, ≪ kValue, k, O ≫)).
        // d. If testResult is true, return kValue.
        var kValue = o[k];
        if (predicate.call(thisArg, kValue, k, o)) {
          return kValue;
        }
        // e. Increase k by 1.
        k++;
      }

      // 7. Return undefined.
      return undefined;
    },
    configurable: true,
    writable: true
  });
}

// ここまでポリフィル

function check() {
    let form = document.getElementById("hoge");
    let ok = true;
    let checked;

    // reset error message
    Array.from(form.querySelectorAll('.errormsg')).forEach(function(err) {
        err.style.display = "none";
    });

    // 会社名
    if (form.name.value == "") {
        document.getElementById("namealert").style.display="block";
        hoge.name.focus();
        ok = false;
    }

    // 選択肢A (radio)
    checked = Array.from(form.querySelectorAll('[name="hogehoge"]')).find(function(e) { return e.checked;});
    if (! checked) {
        document.getElementById("radioalert").style.display="block";
        ok = false;
    }

    // 選択肢B (checkbox)
    checked = Array.from(form.querySelectorAll('.check_b')).find(function(e) { return e.checked;});
    if (! checked) {
        document.getElementById("checkalert").style.display="block";
        ok = false;
    }

    return ok;
}

ちょっと長ったらしいですが、「ポリフィル」という古いブラウザで今どきの javascript を動かす方法を使っています。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from#Polyfill
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find#Polyfill

// ここまでポリフィル

までが、ポリフィルです。
それ以降は、回答に書いたコードとほとんど同じですが、アロー関数という書き方を function に変更しました(二ヶ所)。

e => xxx

function(e) { return xxx; }
2018/06/03 00:36:11
id:cafe-beret

ありがとうございます。ご指定のコードでやりたいことが完全に実現できました。
この度は何度もお付き合いいただきありがとうございました。感謝申し上げます。

2018/06/03 18:27:12

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません