使いどころ
サーバー側で処理するまでもないちょっとした処理をjsで行いたいことがよくあります。
例えば下記のように、ユーザーが購入数(TextBox)の数字を変えると、合計金額(Label)の値が自動的に「単価 x 購入数」の金額になるような表示を作りたいとします。
購入数 :[ 3]個 ←TextBox
単価 :100円 ←Label
合計金額:300円 ←Label
購入数 :<input type="text" id="購入数" onchange="calcTotal();" />個
単価 :<asp:Label ID="単価" Text="100" runat="server" /> 円
合計金額:<asp:Label ID="合計金額" runat="server" />円
<script>
function calcTotal() {
/*合計金額*/.innerText = /*購入数*/.value * /*単価*/.innerText
}
</script>
ところが、javascriptでラベルの値を変えても、何らかのポストバックが発生すると元に戻ってしまいます。
ポストバックの仕様
実はポストバック時に現在の値が送信されるものとされないものがあり、それはその要素の種類によって決まっています。
例えばTextBoxなどは、ユーザーによって値が書き換えられることが想定されるため、ポストバック時に現在値が送信されます。そのため、特に何もプログラミングしなくても最新の値が適用されます。
逆にLabelなどは、基本的に値が変わることはありえないと想定されているため、ポストバック時に現在の値が送信されません。そのため、初期値が適用されます。
HiddenFieldを使う
ということで、ポストバック時に現在の値が送信される種類のコントロールであるHiddenFieldを使います。
クライアント側ではラベルと隠しフィールドの両方の値を変更します。
サーバー側ではPageLoadイベントの中でラベルの文字列を隠しフィールドの値で上書きします。
購入数 :<input type="text" id="購入数" onchange="calcTotal();" />個
単価 :<asp:Label ID="単価" Text="100" runat="server" /> 円
合計金額:<asp:Label ID="Label合計金額" runat="server" />円
<asp:HiddenField ID="Hidden合計金額" runat="server" />
function calcTotal() {
const total =
parseInt(document.getElementById('購入数').value, 10)
* parseInt(document.getElementById('<%= 単価.ClientID %>').textContent, 10);
document.getElementById('<%= Label合計金額.ClientID %>').innerText = total;
document.getElementById('<%= Hidden合計金額.ClientID %>').value = total;
}
protected void Page_Load(object sender, EventArgs e)
{
Label合計金額.Text = Hidden合計金額.Value;
}