チェックボックスで合計を求める
2023年6月25日
みなさんこんにちは。
ケミストのWeb担当みやのです。
「Web」記事では、これまでに得たWebに関する知識を記録として残していきたいと思います。
今回はチェックボックスを使って数値の合計を計算する機能を作ってみました。
参考:JavaScript素材集|チェックボックスで合計金額を計算します
参考:うどん県ウェブディレクター日記|チェックシートで合計点を計算するサンプル
つくってみよう
チェックボックスと出力欄を設置します。
formのnameを"myform"
formのonsubmitを"return false;"
inputのonclickを"keisan()"
outputのnameを"total"としておきます。
inputのvalueに価格を入れます。
<form name="myform" onsubmit="return false;">
<input type="checkbox" onclick="keisan()" value="200">ハンバーガー
<input type="checkbox" onclick="keisan()" value="150">ポテトS
<input type="checkbox" onclick="keisan()" value="100">ドリンクS
<output type="text" name="total" value="0"></output>円
</form>
以下のスクリプトを記述します。
function keisan(){
goukei = 0
for(i=0; i<num; i++){
if(document.forms[0].elements[i].checked==true){
goukei = goukei + parseInt(document.forms[0].elements[i].value)
}
}
document.forms[0].total.value = goukei
}
var num = document.forms[0].length-1
理由はわかりませんが(たぶん最後の行のせい)ヘッダー内に記述するとうまく動かないので、</body>の直上に記述します。
チェックボックスのアニメーションの挙動がちょっとおかしい気がしますが、とりあえず動いたからいいや。
2個を連結
2つのformでそれぞれの合計を出して、さらにその結果どうしの合計を出してみます。
formを2つ(myform2とmyform3)設置します。
inputのonclickはそれぞれkeisan2()、keisan3()として、さらにkeisanx()を追加します。
それぞれのoutputにIDを振っておきます(t2、t3)
<form name="myform2" onsubmit="return false;">
<input type="checkbox" onclick="keisan2(),keisanx()" value="250">チーズバーガー
<input type="checkbox" onclick="keisan2(),keisanx()" value="200">ポテトM
<input type="checkbox" onclick="keisan2(),keisanx()" value="150">ドリンクM
<output type="text" name="total2" value="0" id="t2"></output>円
</form>
<form name="myform3" onsubmit="return false;">
<input type="checkbox" onclick="keisan3(),keisanx()" value="300">てりやきバーガー
<input type="checkbox" onclick="keisan3(),keisanx()" value="250">ポテトL
<input type="checkbox" onclick="keisan3(),keisanx()" value="200">ドリンクL
<output type="text" name="total3" value="0" id="t3"></output>円
</form>
結果どうしの合計出力欄を設置します。
formのnameを"myformx"
outputのnameを"totalx"としておきます。
<form name="myformx">
<output type="text" name="totalx" value="0"></output>円
</form>
スクリプトに追記します。
function keisan2(){
goukei2 = 0
for(i=0; i<num; i++){
if(document.forms[1].elements[i].checked==true){
goukei2 = goukei2 + parseInt(document.forms[1].elements[i].value)
}
}
document.forms[1].total2.value = goukei2
}
function keisan3(){
goukei3 = 0
for(i=0; i<num; i++){
if(document.forms[2].elements[i].checked==true){
goukei3 = goukei3 + parseInt(document.forms[2].elements[i].value)
}
}
document.forms[2].total3.value = goukei3
}
function keisanx(){
goukeix = 0
for(i=0; i<num; i++){
if(document.forms[1].elements[i].checked==true||document.forms[2].elements[i].checked==true){
goukeix = Number(t2.value) + Number(t3.value)
}
}
document.myformx.totalx.value = goukeix
}
var num = document.forms[0].length-1
if文の条件で「AまたはB」としたい時はA||Bと書くのだそうです。
セレクトで切り替える
まずは完成品(一応)をご覧ください。
初心者なりに試行錯誤してみました。
「そこはもっと簡単に記述できるよ」というご指摘があればよろしくお願いします。
HTMLはこんな感じです。長ェ!
チェックボックス3個組×3セット×2セット用意して、各チェックボックスに固有のIDとリストごとのname(cb、cb2)を振って、チェックボックスのonclickにkeisanx2()を追加します。
各チェックリストの小計にname(totals、totals2)をつけます。
セレクトボックスで表示を切り替えるの記事でやったように、セレクトボックスの選択結果によって表示されるリストを切り替えるようにします。
セレクトボックスのIDをselect1、select2
onchangeを "change1(),keisanx2()" "change2(),keisanx2()"とします。
合計出力欄のoutputのnameをtotalx2
IDをtx2としておきます。
<select id="select1" onchange="change1(),keisanx2()">
<option value="" selected>未選択</option>
<option value="sset">Sセット</option>
<option value="mset">Mセット</option>
<option value="lset">Lセット</option>
</select>
<dl id="s1">
<dt id="dummy"></dt>
<dt id="sset">
<form name="myform4" onsubmit="return false;">
<input type="checkbox" id="cb10" name="cb" onclick="keisan4(),keisanx2()" value="200">ハンバーガー
<input type="checkbox" id="cb11" name="cb" onclick="keisan4(),keisanx2()" value="150">ポテトS
<input type="checkbox" id="cb12" name="cb" onclick="keisan4(),keisanx2()" value="100">ドリンクS
<output type="text" name="totals" value="0" id="t4"></output>円
</form>
</dt>
<dt id="mset">
<form name="myform5" onsubmit="return false;">
<input type="checkbox" id="cb13" name="cb" onclick="keisan5(),keisanx2()" value="250">チーズバーガー
<input type="checkbox" id="cb14" name="cb" onclick="keisan5(),keisanx2()" value="200">ポテトM
<input type="checkbox" id="cb15" name="cb" onclick="keisan5(),keisanx2()" value="150">ドリンクM
<output type="text" name="totals" value="0" id="t5"></output>円
</form>
</dt>
<dt id="lset">
<form name="myform6" onsubmit="return false;">
<input type="checkbox" id="cb16" name="cb" onclick="keisan6(),keisanx2()" value="300">てりやきバーガー
<input type="checkbox" id="cb17" name="cb" onclick="keisan6(),keisanx2()" value="250">ポテトL
<input type="checkbox" id="cb18" name="cb" onclick="keisan6(),keisanx2()" value="200">ドリンクL
<output type="text" name="totals" value="0" id="t6"></output>円
</form>
</dt>
</dl>
<select id="select2" onchange="change2(),keisanx2()">
<option value="" selected>未選択</option>
<option value="sset2">Sセット</option>
<option value="mset2">Mセット</option>
<option value="lset2">Lセット</option>
</select>
<dl id="s2">
<dt id="dummy2"></dt>
<dt id="sset2">
<form name="myform7" onsubmit="return false;">
<input type="checkbox" id="cb19" name="cb2" onclick="keisan7(),keisanx2()" value="200">ハンバーガー
<input type="checkbox" id="cb20" name="cb2" onclick="keisan7(),keisanx2()" value="150">ポテトS
<input type="checkbox" id="cb21" name="cb2" onclick="keisan7(),keisanx2()" value="100">ドリンクS
<output type="text" name="totals2" value="0" id="t7"></output>円
</form>
</dt>
<dt id="mset2">
<form name="myform8" onsubmit="return false;">
<input type="checkbox" id="cb22" name="cb2" onclick="keisan8(),keisanx2()" value="250">チーズバーガー
<input type="checkbox" id="cb23" name="cb2" onclick="keisan8(),keisanx2()" value="200">ポテトM
<input type="checkbox" id="cb24" name="cb2" onclick="keisan8(),keisanx2()" value="150">ドリンクM
<output type="text" name="totals2" value="0" id="t8"></output>円
</form>
</dt>
<dt id="lset2">
<form name="myform9" onsubmit="return false;">
<input type="checkbox" id="cb25" name="cb2" onclick="keisan9(),keisanx2()" value="300">てりやきバーガー
<input type="checkbox" id="cb26" name="cb2" onclick="keisan9(),keisanx2()" value="250">ポテトL
<input type="checkbox" id="cb27" name="cb2" onclick="keisan9(),keisanx2()" value="200">ドリンクL
<output type="text" name="totals2" value="0" id="t9"></output>円
</form>
</dt>
</dl>
<output type="text" name="totalx2" value="0" id="tx2"></output>
CSSは、セレクトボックスの非表示に関する記述のみです。
#s1 dt:nth-of-type(n+2) {
display: none;
}
#s2 dt:nth-of-type(n+2) {
display: none;
}
スクリプトは以下の通りです。
まずは計算に関する記述 凄ェ長ェぞ!?
function keisan4(){
goukei4 = 0
for(i=0; i<num; i++){
if(document.forms[4].elements[i].checked==true){
goukei4 = goukei4 + parseInt(document.forms[4].elements[i].value)
}
}
document.forms[4].totals.value = goukei4
}
function keisan5(){
goukei5 = 0
for(i=0; i<num; i++){
if(document.forms[5].elements[i].checked==true){
goukei5 = goukei5 + parseInt(document.forms[5].elements[i].value)
}
}
document.forms[5].totals.value = goukei5
}
function keisan6(){
goukei6 = 0
for(i=0; i<num; i++){
if(document.forms[6].elements[i].checked==true){
goukei6 = goukei6 + parseInt(document.forms[6].elements[i].value)
}
}
document.forms[6].totals.value = goukei6
}
function keisan7(){
goukei7 = 0
for(i=0; i<num; i++){
if(document.forms[7].elements[i].checked==true){
goukei7 = goukei7 + parseInt(document.forms[7].elements[i].value)
}
}
document.forms[7].totals2.value = goukei7
}
function keisan8(){
goukei8 = 0
for(i=0; i<num; i++){
if(document.forms[8].elements[i].checked==true){
goukei8 = goukei8 + parseInt(document.forms[8].elements[i].value)
}
}
document.forms[8].totals2.value = goukei8
}
function keisan9(){
goukei9 = 0
for(i=0; i<num; i++){
if(document.forms[9].elements[i].checked==true){
goukei9 = goukei9 + parseInt(document.forms[9].elements[i].value)
}
}
document.forms[9].totals2.value = goukei9
}
function keisanx2(){
const cb = document.getElementsByName("cb");
const cb2 = document.getElementsByName("cb2");
goukeix2 = 0
for(let i = 0; i < cb.length; i++){
if(cb[i].checked||cb2[i].checked){
goukeix2 = Number(t4.value) + Number(t5.value) + Number(t6.value) + Number(t7.value) + Number(t8.value) + Number(t9.value)
}
}
document.myformx2.totalx2.value = goukeix2
}
var num = document.forms[0].length-1
次に、セレクトボックスによる表示・非表示のスクリプトです。
$(function(){
$('#select1').change(function(){
var val = $(this).val();
var selectId = '#' + val;
$('#s1 dt').hide();
$(selectId).show();
});
});
$(function(){
$('#select2').change(function(){
var val = $(this).val();
var selectId = '#' + val;
$('#s2 dt').hide();
$(selectId).show();
});
});
非表示にするだけでは、見えていないチェックボックスにもチェックが入っていてそれも合計されてしまうので、セレクトボックスを切り替えると当該リストのチェックがすべて外れて、その後で再計算してくれるように設定しました。
function change1(){
let cb = document.querySelectorAll(`[name='cb']`);
let totals = document.querySelectorAll(`[name='totals']`);
for(const i of cb){
i.checked = false;
}
for(const i of totals){
i.innerHTML = "";
}
}
function change2(){
let cb2 = document.querySelectorAll(`[name='cb2']`);
let totals2 = document.querySelectorAll(`[name='totals2']`);
for(const i of cb2){
i.checked = false;
}
for(const i of totals2){
i.innerHTML = "";
}
}
本当はもっとこう、+マークとかがあって、そこをクリックするとリストがにゅって追加される感じにしたかったのですが、難しそうなのでまた今度挑戦します!
まとめ
このしくみを使って、何か普段の仕事に役立つツールが作れないか考え中です。
たとえば漢方薬を併用したときのカンゾウの量を計算したりとか(それ役に立つの...?)
スクリプトが長すぎたのか、ダークモードに変更するときちょっと動作が重いです。ハンバーガーメニューをハンバーガーにしてる場合ではなかった