ASP.NET ReadonlyのTextBoxをjQueryで変更した場合、サーバー側で値が取得できない
概要
新年早々バグ修正しました。ReadonlyのTextBoxサーバコントロールはjQueryで見た目だけ変更してもサーバー側では値が取得出来ないので、見た目と違う値が登録されてしまいました。しかもシステム的に特殊なオペレーションを行った場合のみ出現するので見逃されていたようです。
環境
Visual Studio 2010
ASP.NET
.NET Framework 4
数量、金額を入力するとjQueryによりReadonlyのTextBox合計値が計算され表示されます。
保存ボタンを押下してサーバー側に処理が移った際、合計値は計算後ではなく初期値"0"が取得されます。
■Bug001.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Bug001.aspx.cs" Inherits="TodaysBugs.Bug001" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Bug001</title> <script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script> </head> <body> <form id="form1" runat="server"> <div> <asp:Label ID="Label1" runat="server" Text="数量" Width="50px"></asp:Label> <asp:TextBox ID="txtQuantity" runat="server"></asp:TextBox> <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ErrorMessage="必須" ControlToValidate="txtQuantity" Display="Dynamic" ForeColor="Red"></asp:RequiredFieldValidator> <asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server" ErrorMessage="数値を入力してください。" ValidationExpression="^[0-9]+$" ControlToValidate="txtQuantity" Display="Dynamic" ForeColor="Red"></asp:RegularExpressionValidator> </div> <div> <asp:Label ID="Label2" runat="server" Text="金額" Width="50px"></asp:Label> <asp:TextBox ID="txtAmount" runat="server"></asp:TextBox> <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ErrorMessage="必須" ControlToValidate="txtAmount" Display="Dynamic" ForeColor="Red"></asp:RequiredFieldValidator> <asp:RegularExpressionValidator ID="RegularExpressionValidator2" runat="server" ErrorMessage="数値を入力してください。" ValidationExpression="^[0-9]+$" ControlToValidate="txtAmount" Display="Dynamic" ForeColor="Red"></asp:RegularExpressionValidator> </div> <div> <asp:Label ID="Label3" runat="server" Text="合計" Width="50px"></asp:Label> <asp:TextBox ID="txtTotal" runat="server" ReadOnly="true" BackColor="Gray">0</asp:TextBox> </div> <div> <asp:Button ID="btnSave" runat="server" Text="保存" onclick="btnSave_Click" /> <asp:Label ID="lblResult" runat="server" Text=""></asp:Label> </div> <div> <asp:Button ID="btnClear" runat="server" Text="クリア" onclick="btnClear_Click" /> </div> </form> </body> <script language="javascript" type="text/javascript"> $(function () { $('#<%= txtQuantity.ClientID%>').focusout(function (e) { setTotal(); }); $('#<%= txtAmount.ClientID%>').focusout(function (e) { setTotal(); }); }); function setTotal() { var total = $('#<%= txtQuantity.ClientID%>').val() * $('#<%= txtAmount.ClientID%>').val(); $('#<%= txtTotal.ClientID%>').val(total); } </script> </html>
■Bug001.aspx.cs
using System; namespace TodaysBugs { public partial class Bug001 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { //aspx側のReadOnly属性は"false"にする //txtTotal.Attributes.Add("readonly", "true"); } protected void btnSave_Click(object sender, EventArgs e) { var total = txtTotal.Text; lblResult.Text = "登録しました。 → 合計値:" + total.ToString(); } protected void btnClear_Click(object sender, EventArgs e) { txtQuantity.Text = string.Empty; txtAmount.Text = string.Empty; txtTotal.Text = "0"; lblResult.Text = string.Empty; } } }
対応
Readonly属性を後から付与するとサーバー側でも合計値が計算後の値が取得できるようですが、今回はシンプルに数量と金額のTextBoxの値を取得し、サーバー側で再計算するよう修正することで対応しました。
参考
TextBox.ReadOnly プロパティ
TextBox.ReadOnly プロパティ (System.Web.UI.WebControls)