2016-03-27 8 views
0

Ich habe ein GridView mit einer Spalte, wo ich Zahlen eingeben. Ein Javascript summiert diese Zahlen, während ich sie eintippe, und zeigt die Summe in einem Label außerhalb der GridView an. Funktioniert gut.ASP.NET Javascript Werte in GridView verloren zwischen Postbacks

Irgendwo auf der Seite gibt es eine Schaltfläche, die ein Postback verursacht, wenn geklickt wird, und um den Wert der Gesamtbeschriftung nicht zu verlieren, speichert das Javascript auch die Summe in einem HiddenField, und auf page_load kopiere ich es aus dem HiddenField zurück zum Total Label. Das funktioniert auch.

Aber wenn ich nach dem Postback zurück bin und ich eine Zahl in einer der Zellen eintippe, würde die Summe nur diese Nummer widerspiegeln und die Werte in allen anderen Zellen ignorieren. Diese sind zwischen Postbacks verloren.

Ich denke, das Javascript sollte nicht nur die Total-Label, sondern alle Werte aller Zellen in dieser Spalte, aber mein Wissen über JS ist nahe bei Null (vorerst ...).

Mein 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> 

Mein 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> 

Mein C# -Code-behind:

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"; 
    } 

(Die Javascript wahrscheinlich schrecklich ineffizient und chaotisch ist, weil ich einfach kopieren Dinge, die ich im Internet finde, ohne es wirklich zu verstehen. Jede Bemerkung zu diesem Code wäre sehr nützlich für mich auch).
EDIT:
Diese Seite soll, als Quittung enden, wo der Benutzer (die den Empfang der Herstellung) eine oder mehrere Zahlen in der richtigen Zelle in der Grid Zeile eingeben wird, und die Anwendung muss diese summieren Zahlen, damit der Benutzer die Summe sehen kann, während er die Zahlen eintippt. In der Zeile wird es mehr Zeilen mit mehr Informationen geben. Ich habe es auf das Minimum zum Zweck der Eröffnung dieser Q.
(der Begriff "Menge" im Code war irreführend und ich änderte es in "Payed". Auch, wie @Fnostro vorgeschlagen, nahm ich die UpdatePanel aus der Seite).
Dies ist, was ich zuerst bekommen:
enter image description here
I 45 dann in der ersten Zeile eingeben und wie ich es eingeben Ich sehe die Gesamt I 30 eingeben, um 45 aktualisiert werden und die Gesamt aktualisiert wird sofort auf 75:
enter image description here
ich dann auf den Button, und erhalten:
enter image description here
Jetzt lege ich den Cursor auf die letzte Zeile, und geben Sie 5 und die Gesamt zeigt 5 auch. Das Javascript ignoriert die anderen beiden Werte:
enter image description here
Ich hoffe, ich war jetzt klarer und würde jede Hilfe zu schätzen wissen.

+0

Ich bin nicht sehr vertraut mit jQuery, aber ich denke, dass die Antwort auf Ihre Frage in diesem Beitrag ist: http://StackOverflow.com/Questions/256195/Jquery-Document-Ready-and-Updatepanels – ConnorsFan

+0

@ConnorsFan - danke 4 der Link. Ich habe es versucht, bevor ich meine Frage gepostet habe, aber das hat nicht geholfen. – gadi

+0

Frage zu fnostro Antwort: funktioniert es ohne das UpdatePanel? Und nur um sicher zu sein: Sind die Felder nach dem Postback leer oder werden sie bei der Berechnung der Summe ignoriert? – ConnorsFan

Antwort

0

Ich habe eine GridView (innerhalb eines UpdatePanel) mit einer Spalte, wo ich Zahlen eingeben.

Ich würde keine UpdatePanel vorstellen, bis Sie den Code haben, ohne es zu arbeiten. Partielle Seitenpostbacks wirken sich auf JS/JQ aus und Sie müssen wissen, wie Sie damit umgehen. Wenn mit Update Umgang benutze ich JS/JQuery-Code ähnlich wie diesen:

// 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 
} 

In dem obigen Code, ich den Präfix Text zu ersetzen, FullAndPartialPostback mit dem Seitennamen Klasse (oder Benutzerkontrolle), so dass es so etwas wie Default_EventHandler liest und es ist klar, zu welcher Klasse dieser Handler gehört.

A Javascript fasst diese Zahlen, wie ich sie in ein und zeigt die Summe in einem Etikett außerhalb des Gridview. Funktioniert gut. Irgendwo auf der der Seite gibt es eine Schaltfläche, die ein Postback verursacht, wenn darauf geklickt,

meisten Jede ASP.NET-Serversteuertaste bewirkt, dass ein Postback. Sie haben die UpdatePanel Standardwerte beibehalten, so dass ChildrenAsTriggers=true bedeutet, dass Schaltflächen zurück posten werden.

und um nicht den Wert des Gesamt Etikett zu verlieren, speichert der Javascript auch die Summe in einem Hidden und auf page_load Ich kopiere es aus die Hidden auf das Gesamt Label zurück. Das funktioniert auch.

Das ist gut - für Hidden, die gut sind, aber ...

Aber ... wenn, nachdem ich von der Postbacks bin wieder da und ich eine Zahl in jedem der Zellen geben, die Total würde nur diese Zahl reflektieren und die Werte in allen anderen Zellen ignorieren. Diese sind zwischen Postbacks verloren.

Sind die Zahlen im wahrsten Sinne des Wortes verloren oder wurden zu den vorherigen addiert? Wenn die Textboxwerte beibehalten werden, müssen Sie die Gesamtmenge nicht speichern, sondern nur neu berechnen. Wenn sie verloren sind, hat das Erhalten des Gesamtwerts keine Bedeutung.

Ohne Ihr endgültiges Ziel zu kennen, habe ich keine Ratschläge, wie Sie am besten vorgehen sollten. In der Regel werden keine clientseitigen JS/JQ-berechneten Daten veröffentlicht, wenn alle Quelldaten zum Server zurückgesendet werden, sondern die Summe auf der Serverseite neu berechnet wird.

Nachtrag 2016.02.29: Erläuterung folgt Snippet

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>

Server-Steuerelemente werden wieder auf jeden Beitrag geschrieben. Dasselbe gilt für Felder, die in einer Gridview enthalten sind. Der Trick besteht darin, die Eingabefelder nicht mit gebundenen Daten zu überschreiben.

Sie sollten kein verstecktes Feld zum Speichern der Gesamtsumme benötigen, da es nach jedem Postback einfach neu berechnet werden kann.

Es ist auch erwähnenswert, die Verwendung von "anonyme Klassen." Die Klassen GrandTotal und InputField sind keine definierten Stile in einem CSS, obwohl sie dies können. Aber sie werden hier verwendet, um das Auffinden der Felder zu erleichtern, die jquery für die Berechnung benötigt. Dies ist viel einfacher, wenn Sie herausfinden möchten, welche Art von Fehlern ASP.NET mit den Control-IDs zu tun hat. Sie sollten selten, wenn überhaupt, *= verwenden, z. B. $("input[id*='some_id']"), um ein Feld zu finden.

Da alle Eingaben und Berechnungen in den Serversteuerelementen enthalten sind, müssen keine ausgeblendeten Felder verwendet werden, da die Serversteuerelemente ihre Werte während des Roundtrips beibehalten und die Summierung auf der Clientseite problemlos erneut durchgeführt werden kann geladen.

FYI: jquery live() Funktion ist veraltet.

+0

Ich bearbeite meine Frage. – gadi

+0

danke für deine zeit. Ihr Snippet enthält jedoch kein Postback. Es ist eine andere Art zu programmieren, was ich bereits habe. Meine App wird eine Schaltfläche haben, um eine Zeile in der Gridview hinzuzufügen, die ein Postback verursacht. Nach was ich suche, ist ein Weg, die "summierende" Funktionalität zwischen Postbacks zu bewahren. – gadi

Verwandte Themen