2016-03-27 32 views
0

私は数字を入力する列を持つGridViewを持っています。 Javascriptは、これらの数値を入力するときにこれらの数値を合計し、GridView外のラベルに合計を表示します。正常に動作します。ASP.NET GridViewのJavascript値がポストバック間で失われました

ページ上には、クリックするとポストバックが発生するボタンがあります。また、合計ラベルの値を失わないために、Javascriptは合計をHiddenFieldに保存し、page_loadにはHiddenFieldをTotalラベルに戻します。それも動作します。

しかし、私がポストバックから戻って、いずれかのセルに数値を入力した場合、合計はその数値がにしか反映されず、他のすべてのセルの値は無視されます。それらはポストバックの間に失われます。

私はJavaScriptがTotalラベルだけでなく、その列にあるすべてのセルの値を保持するべきだと思うが、私のJSの知識は今のところはゼロに近い。

マイHTML:

 <table> 
     <tr> 
      <td> 
       <asp:Button ID="btn" runat="server" OnClick="btn_Click" Text="Click me" /> 
       <asp:Label ID="lbl_Message" runat="server"></asp:Label> 
      </td> 
     </tr> 
     <tr> 
      <td> 
       <div> 
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false"> 
         <Columns> 
          <asp:BoundField DataField="Something" HeaderText="Something" /> 
          <asp:TemplateField HeaderText="Payed"> 
           <ItemTemplate> 
            <asp:TextBox ID="txb_Payed" runat="server"></asp:TextBox> 
           </ItemTemplate> 
          </asp:TemplateField> 
          <asp:TemplateField HeaderStyle-CssClass="myHidden" ItemStyle-CssClass="myHidden"> 
           <ItemTemplate> 
            <asp:Label ID="lbl_Temp_Payed" runat="server" Text="0"></asp:Label> 
           </ItemTemplate> 
          </asp:TemplateField> 
         </Columns> 
        </asp:GridView> 
        Grand Total: 
          <asp:Label ID="lbl_Grand_Total" runat="server" Text="0"></asp:Label> 
        <asp:HiddenField ID="hdf_Keep_Total" runat="server" /> 
       </div> 
      </td> 
     </tr> 
    </table> 

マイJavascriptを:

<script type="text/javascript"> 
    $("[id *= txb_Payed]").live("change", function() { 
     if (isNaN(parseInt($(this).val()))) { 
      $(this).val('0'); 
     } else { 
      $(this).val(parseInt($(this).val()).toString()); 
     } 
    }); 
    $("[id *= txb_Payed]").live("keyup", function() { 
     if (!jQuery.trim($(this).val()) == '') { 
      if (!isNaN(parseFloat($(this).val()))) { 
       var row = $(this).closest("tr"); 
       $("[id *= lbl_Temp_Payed]", row).html(parseFloat($(this).val())); 
      } 
     } else { 
      $(this).val(''); 
     } 
     var my_Total = 0; 
     $("[id *= lbl_Temp_Payed]").each(function() { 
      my_Total = my_Total + parseFloat($(this).html()); 
     }); 
     $("[id *= lbl_Grand_Total]").html(my_Total.toString()); 
     var my_hdf_Keep_Total = '<%= hdf_Keep_Total.ClientID %>'; 
      document.getElementById(my_hdf_Keep_Total).value = my_Total; 
     }); 
</script> 

私のC#のコードビハインド:

protected void Page_Load(object sender, EventArgs e) 
    { 
     lbl_Grand_Total.Text = hdf_Keep_Total.Value; 
     if (!Page.IsPostBack) 
     { 
      Bind_Sample_Data_To_Grid(); 
     } 
    } 
    private void Bind_Sample_Data_To_Grid() 
    { 
     DataTable dt = new DataTable(); 
     dt.Columns.AddRange(new DataColumn[1] { new DataColumn("Something") }); 
     dt.Rows.Add("aaaaa"); 
     dt.Rows.Add("bbbbb"); 
     dt.Rows.Add("ccccc"); 
     GridView1.DataSource = dt; 
     GridView1.DataBind(); 
    } 
    protected void btn_Click(object sender, EventArgs e) 
    { 
     lbl_Message.Text = "U clicked"; 
    } 

私はちょうどコピーしているため(Javascriptがおそらくひどく非効率的かつ厄介です私は本当にそれを理解することなくネット上で見つけることができます。そのコード上の任意の発言は非常に有益だろう私にも)。
EDIT:
このページは、ユーザー(レシートを生成するもの)GridViewの行の適切なセルに1つ以上の数字を入力しますレシートとして終わることを意図し、そしてアプリケーションがこれらを合計する必要があります数字を入力すると、ユーザーは数字を入力するとその合計を見ることができます。その行には、より多くの情報を含む行があります。このQを開くために最小限に簡略化しました。
(コード中の「数量」という用語は誤解を招き、「Payed」に変更しました)また、@ Fnostroが示唆したように、私はUpdatePanelをページ)。
これは私が最初に得るものです:
enter image description here
私はその後、1行目で45を入力し、私はそれを入力すると、私は45に更新されている合計が、私は30を入力し、合計がすぐに75に更新されて参照してください。
enter image description here
私は、ボタンをクリックして、入手:
enter image description here
は今、私も最後の行にカーソルを置き、5を入力して、合計のショー5。 Javascriptは他の2つの値を無視します:
enter image description here
私は今、より明確になり、助けていただければ幸いです。

+0

私はjQueryに慣れていませんが、あなたの質問に対する答えはこの記事にあります:http://stackoverflow.com/questions/256195/jquery-document-ready-and-updatepanels – ConnorsFan

+0

@ConnorsFan - ありがとう4リンク。私の質問を投稿する前にそれを試してみましたが、それは助けになりませんでした。 – gadi

+0

fnostroの答えに関連する質問:それはUpdatePanelなしでも機能しますか?そして、ちょうど確かめてください:ポストバック後のフィールドは空白ですか、または合計の計算で無視されますか? – ConnorsFan

答えて

0

GridView(UpdatePanel内)には、 の数字を入力する列があります。

コードなしで作業するまではUpdatePanelを紹介しません。部分ページポストバックはJS/JQに影響し、その処理方法を知っておく必要があります。それはDefault_EventHandlerようなものを読み込むよう

// Handle Full Postback 
$(function() { 
    FullAndPartialPostback_EventHandler(true, null, null); 
}); 

// Handle Partial Postback 
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function(sender, args) { 
    FullAndPartialPostback_EventHandler(false, sender, args); 
}); 


function FullAndPartialPostback_EventHandler(isFullPostBack, sender, args) { 
    // Do stuff common to both Full/Partial postbacks here 

    if(isFullPostBack){ 
     // Do Full postback specific stuff here 
    } 
    else { 
     // Do Partial postback specific stuff here 
    } 

    // Do more stuff common to both here 
} 

は、上記のコードでは、私はページ(またはユーザーコントロール)クラス名に接頭辞テキスト、FullAndPartialPostbackを交換

:UpdatePanelsを扱う場合 は、私は次のようにJS/jQueryのコードを使用しますこのハンドラがどのクラスに属するのかは明らかです。

A Javascriptが、私はそれらを入力として、これらの数値を合計して、GridViewの外側のラベルに 合計を示しています。正常に動作します。どこかにある ページには、クリックするとポストバックが発生するボタンがあります。

ほとんどすべてのASP.NETサーバーコントロールボタンはポストバックを引き起こします。 UpdatePanelをデフォルトにしたままにしておくと、ChildrenAsTriggers=trueのままにするとボタンがポストバックします。

と合計ラベルの値を失うしないようにするためには、Javascriptを ものHiddenFieldで合計を保存し、Page_Loadの上で、私は戻って合計ラベルに からのHiddenFieldをコピーします。それも動作します。良いことだ

- HiddenFieldsしかし、そのために良いです...

しかし...もし私が戻ってポストバックからだと私は、細胞の任意の に数値を入力した後、合計はその数値だけを反映し、他のすべてのセルの値はを無視します。それらはポストバックの間に失われます。

数値が文字通り失われているか、前の合計に加算されていますか? テキストボックスの値が保存されている場合は、合計を保存する必要はありません - 再計算のみ。それらが失われた場合、Totalを保存することは意味を持ちません。

あなたの最終目標を知らずに、私はどのように最善の方法をアドバイスする必要はありません。通常、すべてのソース・データがサーバーにポストバックされ、サーバー側で合計を再計算するだけであれば、クライアント側JS/JQ計算データをポストしません。

補遺2016年2月29日:説明を次のスニペット

var $GrandTotal = null; 
 
var $InputFields = null; 
 

 
$(function() { 
 
    $GrandTotal = $(".GrandTotal"); 
 
    $InputFields = $(".InputField"); 
 
    
 
    $InputFields.on("keyup", SumRows); 
 

 
    SumRows(); 
 
}); 
 

 
function SumRows() { 
 
    var SubTotal = 0.0; 
 
    
 
    $InputFields.each(function(){ 
 
    if($.isNumeric($(this).val())) 
 
     SubTotal += parseFloat($(this).val()); 
 
    }); 
 
    
 
    $GrandTotal.text(SubTotal); 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 
<table> 
 
    <thead> 
 
    <tr><td>Something</td><td>Payed</td></tr> 
 
    </thead> 
 
    <tbody> 
 
    <tr><td>aaaaa</td><td><input id="tbx_Payed_1" class="InputField" type="number"></td></tr> 
 
    <tr><td>bbbbb</td><td><input id="tbx_Payed_2" class="InputField" type="number"></td></tr> 
 
    <tr><td>ccccc</td><td><input id="tbx_Payed_3" class="InputField" type="number"></td></tr> 
 
    <tr><td>ddddd</td><td><input id="tbx_Payed_4" class="InputField" type="number"></td></tr> 
 
    </tbody> 
 
    <tfoot> 
 
    <tr><td>Sum</td><td><span id='lbl_Grand_Total' class="GrandTotal" >0</span></td></tr> 
 
    </tfoot> 
 
</table>

サーバーのコントロールは、すべてのポストに戻って掲載されています。同じことが、Gridview内に含まれるフィールドにも適用されます。トリックは、入力フィールドをバインドされたデータで上書きしないことです。

ポストバック後に簡単に再計算できるため、総計を保持するために非表示フィールドは必要ありません。

「匿名クラス」の使用にも注意する価値があります。 GrandTotalおよびInputFieldのクラスは、CSSには定義されていませんが、どのCSSでも使用できます。しかし、ここでは、jqueryが計算を行うために必要なフィールドを簡単に見つけるために使用されます。これは、どのような悪質なASP.NETがコントロールIDに行うのかを理解しようとする方がはるかに簡単です。フィールドを見つけるには、*=(例:$("input[id*='some_id']"))を使用する必要はほとんどありません。

すべての入力と計算がサーバーコントロール内に含まれているため、サーバーコントロールはラウンドトリップ中に値を保持し、ページが表示されたらクライアント側で合計を簡単に再実行できるため、非表示フィールドを使用する必要はありません。ロードされる。

FYI:jqueryのlive()関数は推奨されていません。

+0

私の質問を編集します。 – gadi

+0

お時間をいただきありがとうございます。しかし、スニペットにはポストバックがありません。私がすでに持っているものをコード化する別の方法です。私のアプリには、グリッドビューに行を追加するボタンがあり、ポストバックが発生します。私が探しているのは、ポストバック間の '合計'機能を保持する方法です。 – gadi

関連する問題