【JavaScript】ラベルから表示値を取得して計算

先週金曜日に、「水曜日までに修正してねー」と言われた設計書(もういない人が作ったやつ)で疑問に感じたことについて。なんか不要な画面項目が定義されているなー?と感じたので、修正作業に入る前にJavaScriptで動作確認しておきます。


デモ用HTML(修正前)

<body>
<div>
    全体の予定人数:<label id="total">40</label><input type="hidden" id="prevTotal" value="40"><br>

    第一事業部の予定人数:<input type="text" id="div1" value="10"><br>
    <input type="hidden" id="prevDiv1" value="10">

    <input type="button" value="計算(Jquery)" onclick="calcForJquery()">
    <input type="button" value="計算(Js)" onclick="calcForJs()">
</div>
</body>

処理概要

  • 計算ボタンを押下すると、テキストボックス("div1")に入力された値をもとに計算を行い、ラベル("total")を再表示する
  • 再表示するラベルの値は (変更後のテキストボックスの値 - 変更前のテキストボックスの値) + ボタン押下前のラベルの表示値で算出する

    例1:
    第一事業部("div1")の予定人数を20人に変更した場合、
    全体の予定人数("total")には(20-10)+40=50が表示される

  • 計算ボタンを押下する度に、ラベルの表示値は再計算される

    例2:
    例1の後、第一事業部の予定人数を5人に変更した場合、
    全体の予定人数には(5-20)+50=35が表示される

設計書で「うーん…」ってなっているのは、ラベルの表示値と同じ値をもつhidden項目("prevTotal")が定義されちゃってることなんですよね。
Submitしてサーバ側で処理するならともかく、JavaScriptだと別に必要ないよなーってことを念のため。

デモ用HTML(修正後)

ラベルと対になるhidden項目("prevTotal")は削除しちゃいます。
"prevDiv1"の方は、変更前の"div1"の値を保持する必要があるため残しておきます。

<body>
<div>
    全体の予定人数:<label id="total">40</label><br>

    第一事業部の予定人数:<input type="text" id="div1" value="10"><br>
    <input type="hidden" id="prevDiv1" value="10">

    <input type="button" value="計算(Jquery)" onclick="calcForJquery()">
    <input type="button" value="計算(Js)" onclick="calcForJs()">
</div>
</body>

その1:JQueryでお試し実装

function calcForJquery() {
    var total = $("#total");
    var inputDiv = $("#div1");
    var prevDiv = $("#prevDiv1");

    var diffDiv = parseInt(inputDiv.val()) - parseInt(prevDiv.val());
    total.text(parseInt(total.text()) + diffDiv);
    prevDiv.val(inputDiv.val());
}

うむ、textメソッドを使えばラベルを直接操作できますね。

その2:素のJavaScriptでお試し実装

function calcForJs() {
    var total = document.getElementById("total");
    var inputDiv = document.getElementById("div1");
    var prevDiv = document.getElementById("prevDiv1");

    var diffDiv = parseInt(inputDiv.value) - parseInt(prevDiv.value);
    total.textContent = parseInt(total.textContent) + diffDiv;
    prevDiv.value = inputDiv.value;
}

プロパーの方にJQueryを使えるか確認したところ、曖昧な反応を返されたのでJQueryを使わない版でも。
こっちはtextContentプロパティでラベルの表示値を操作します。
JQueryを引きずってメソッドと勘違いしてエラーを出しまくったのはご愛敬。。

各要素とプロパティにアクセスする方法が変わるだけですね。(そりゃそうか、JQueryで実現できるんだし…)
万が一のため、こちらの書き方も忘れないようにメモしておきます。


無事にラベルの項目を直接操作する方法が確認できました。
ですよねー!って感じですが。

こうやって確認するのはそんなに時間がかからないんですけど…
あちこちの人に説明しなくちゃいけないから、設計書を直すのは何倍も時間がかかっちゃうんですよね…あううう。

参考