【JavaScript】ロト6、ロト7を一つのフォームで購入したい(チェックボックスの動的作成)

# 1.はじめに

毎回思うのが、ロト6とロト7を購入するとき、
違うメニューを選択しなくてはならないのが面倒くさい。
画面がなかなかオシャレだし、

__`【継続購入】というユーザーへの計画的な投資を促す便利な仕組み`__
もあったりするが、面倒くさいのだ。


![loto67.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689780/7708fc70-8c85-1b87-54d7-ec9b0a5ef298.jpeg)

ロト6とロト7の購入は、数字の種類と、選ぶ数字の個数の違いだけなのだ。
ラジオボタンで購入する種類を切り替えて、購入できればいいのに！！
今回提案するフォームで、億万長者の近道が開けるかもしれません。

# 2.流れ

今回はラジオボタンを切り替えることで、クイックピックのロト6、クイックピックのロト7、番号選択のロト6、番号選択のロト7の4種類を一つのフォームで __`一口`__ 購入できる事を目指している。

なぜ一口？
それは、、、、、。
チェックボックスがあまりにも不細工だから。
この無機質な四角の図形を、延々と描画させるのはあまりよろしくない。
チェックボックスをオシャレにする技を私が持っていないからだ。
とはいえ今回は少しだけcssも使ってみるつもりだ。

### 2.1 ロト購入の初期画面

初期状態はロト6をクイックピックで購入する設定
![buy_loto1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689780/84b1daca-7039-5227-1fc5-2c3b46464d67.jpeg)

### 2.2 クイックピックでの番号出力
番号出力ボタンを押すと6種類または７種類の任意の番号が表示される。
![buy_loto1_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689780/dcb3d4b3-01f6-3e2d-4af6-70cafaff7bf4.jpeg)

### 2.3 番号選択を選択時(Loto6またはLoto7)

#### 番号選択のとき(Loto6)
![buy_loto2_3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689780/990896d3-be71-188f-840e-38ccdd37c848.jpeg)

#### 番号選択のとき(Loto7)
![buy_loto3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689780/a6b1bf2f-bf42-9e97-1869-98795f16f675.jpeg)

### 2.4 番号を全て選択した時 

番号を選択し終わると、番号出力ボタンが活性化。
他の番号のチェックボックスは非活性になる。

![buy_loto2_4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689780/bc3da9cc-050b-7d0d-2294-5e80ff11a21f.jpeg)



### 2.5 番号選択で選択した番号を出力

![buy_loto2_5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689780/128c9efc-874b-91d2-be60-265da9a15e0c.jpeg)

# 3.メモ

## 3-1.動的に部品を作成

### 3-1-1.動的にタグを生成

__`var element = document.createElement(tagName)`__
tagName：生成するタグ

### 3-1-2.子要素の追加

__`parent.appendChild(element)`__

element:親要素(parent)の最後に追加する子要素

## 3-2.正規表現とチェックボックスの装飾(ちょこっとcss)

__`input[id="id1"]:checked{`__
__`プロパティ=値`__
__`}`__

idがid1の要素(チェックボックス、ラジオボタン)がチェックされているときに、プロパティの設定を行う。

### 3-2-1.指定の値で始まるidの時
__`id^="abc"`__
：abcで始まる


### 3-2-2.指定の値で終わるidの時
__`id$="abc"`__
：abcで終わる

### 3-2-3.指定の値を含むidの時
__`id*="abc"`__
：abcを含む

# 4.ソース

```html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<script src="encoding.js"></script>
<title>Loto購入</title>
<style type="text/css">

input[id^="chkbox6_"]:checked{
  accent-color: #00ffff;
}
input[id^="chkbox7_"]:checked{
  accent-color: #00ff33;
}

</style>
</head>
<body>
<h1>Loto購入</h1>

<form name="loto_form">
<label><input type="radio" name="loto_r" value="6" onclick="OnRadio6Click();" checked>Loto6</label>
<label><input type="radio" name="loto_r" value="7" onclick="OnRadio7Click();">Loto7</label><br>
<label><input type="radio" name="loto_way" value="qp" onclick="OnRadioQPClick();" checked>クイックピック</label>
<label><input type="radio" name="loto_way" value="select" onclick="OnRadioSelectClick();">番号選択</label>
<div id="loto_chkbox"></div>
<input type="button" id="printbtn" value="番号出力" onclick="OnPrintBtnClick();">
<div id="retmsgdiv"></div><br>
</form>

<script> 
var retmsg_div = document.getElementById("retmsgdiv");
var radio_loto=document.getElementsByName("loto_r");
var radio_way=document.getElementsByName("loto_way");
var loto_type="";
var btn_print=document.getElementById("printbtn");

//クイックピックを選択
function OnRadioQPClick(){
 var parent = document.getElementById("loto_chkbox");
 parent.innerHTML="";
 retmsg_div.innerHTML="";
 btn_print.disabled=false;
}

//番号選択を選択
function OnRadioSelectClick(){
 //loto7のとき
 if(radio_loto.item(1).checked){
  make_checkbox(37,7);
 //loto6のとき
 }else{
  make_checkbox(43,6);
 } 
 btn_print.disabled=true;
 retmsg_div.innerHTML="";
}

//任意数のチェックボックスを動的作成する関数
function make_checkbox(num0,type0){
 var parent = document.getElementById("loto_chkbox");
 parent.innerHTML="";
 for (i=0;i<num0;i++){
  var checkbox = document.createElement('input');
  var label = document.createElement('label');
  if(i%10==0){
   var br = document.createElement('br');
  }
  var id = "chkbox"+type0+"_"+(i+1);
  var name = "loto_chk[]";
  var value = i+1;
  var chkfunc1="OnCountNumCheck();";
  checkbox.setAttribute("type", "checkbox");
  checkbox.setAttribute("id", id);
  checkbox.setAttribute("name", name);
  checkbox.setAttribute("value", value);
  checkbox.setAttribute("onchange",chkfunc1);
  label.setAttribute("for", id);
  label.textContent = value;
  if(i%10==0){
   parent.appendChild(br);
  }
  parent.appendChild(checkbox);
  parent.appendChild(label);
 }
}

//loto6を選択
function OnRadio6Click(){
 make_checkbox(43,6);
 //クイックピックを選択時
 if(radio_way.item(0).checked){
  var parent = document.getElementById("loto_chkbox");
  parent.innerHTML="";
  btn_print.disabled=false;
 }else{
  btn_print.disabled=true;
 }
 retmsg_div.innerHTML="";
}

//loto7を選択
function OnRadio7Click(){
 make_checkbox(37,7);
 //クイックピックを選択時
 if(radio_way.item(0).checked){
  var parent = document.getElementById("loto_chkbox");
  parent.innerHTML="";
  btn_print.disabled=false;
 }else{
  btn_print.disabled=true;
 }
 retmsg_div.innerHTML="";
}


function OnPrintBtnClick(){
 arr_ret=[];
 if(radio_way.item(0).checked){
  if(radio_loto.item(0).checked){
   arr_ret=QPdata(43,6);
   loto_type=6;
  }else{
   arr_ret=QPdata(37,7);
   loto_type=7;
  }
  tmpstr="<br>";
  for(i=0;i<loto_type;i++){
   if(i>0){
    tmpstr=tmpstr+","+arr_ret[i];
   }else{
    tmpstr=arr_ret[i];
   }
  }
 }else{
  if(radio_loto.item(0).checked){
   maxnum=43;
   loto_type=6;
  }else{
   maxnum=37;
   loto_type=7;
  }
  tmpstr=get_SelectData(maxnum,loto_type);
 }
 retmsg_div.innerHTML=tmpstr;
}

//クイックピックのデータ作成
function QPdata(lotomax,lototype){
 var arr_loto=[];
 var arr_qp=[];
 var arrtmp=0;
 var maxnum=lotomax;
 for(i=0;i<lotomax;i++){
  arr_loto.push(i+1);
 }
 for(i=0;i<lototype;i++){
  ran0=Math.floor(Math.random()*maxnum);
  arr_qp.push(arr_loto[ran0]);
  //配列からran0番目の要素を削除して、配列サイズを詰める
  arr_loto.splice(ran0,1);
  maxnum=maxnum-1;
 }
 for(i=0;i<lototype-1;i++){
  for(j=i+1;j<lototype;j++){
   if(Number(arr_qp[i])>Number(arr_qp[j])){
    arrtmp=arr_qp[i];
    arr_qp[i]=arr_qp[j];
    arr_qp[j]=arrtmp;
   }
  }
 }
 return arr_qp;
}

//幾つのチェックボックスが選択されているか
function OnCountNumCheck(){
 //番号出力ボタンを非活性化
 btn_print.disabled=true;
 retmsg_div.innerHTML="";
 //チェックボックスのチェックが入っている個数 
 var cnt=0;
 if(radio_loto.item(0).checked){
  lotomax=43;
  loto_type=6;
 }else{
  lotomax=37;
  loto_type=7;
 }
 //チェックが入っている個数について調べる
 for(i=0;i<lotomax;i++){
  var obj_chkbox=document.loto_form.elements['loto_chk[]'][i];
  obj_chkbox.disabled=false;
  if(obj_chkbox.checked){
   cnt=cnt+1;
   //チェック数がちょうどloto_typeになったとき
   if(cnt==loto_type){
    break;
   }
  }
 }
 //チェック数がloto_typeのとき
 if(cnt==loto_type){
  //番号出力ボタンを活性化
  btn_print.disabled=false;
  for(i=0;i<lotomax;i++){
   var obj_chkbox=document.loto_form.elements['loto_chk[]'][i];  
   if(obj_chkbox.checked==false){
    //チェックの入っていないチェックボックスを非活性にする
    obj_chkbox.disabled=true;
   }
  }
 }
}

function get_SelectData(lotomax,lototype){
 var cnt=0;
 var tmpstr="";
 for(i=0;i<lotomax;i++){
  var obj_chkbox=document.loto_form.elements['loto_chk[]'][i];
  if(obj_chkbox.checked){
   if(cnt==0){
    tmpstr=tmpstr+obj_chkbox.value;
   }else{
    tmpstr=tmpstr+","+obj_chkbox.value;
   }
   cnt=cnt+1;
  }
 }
 tmpstr=tmpstr+"<br>";
 return tmpstr;
}

</script>
</body>
</html>
```

# 5.参考サイト

### 5-1.任意の数のチェックボックスの自動生成の参考サイト

[Google Apps Script試行錯誤 Blog](https://www.pre-practice.net/2018/08/html.html)


### 5-2.cssと正規表現の使い方の参考サイト

[【CSS】実はこんなに便利！cssのセレクタ指定方法をちょっとだけ掘り起こしてみた](https://bashalog.c-brains.jp/12/03/06-235258.php)

# 6.最後に

これからも小さな便利と大きな富を追求したい。