I've this javascript function:
function modifica(txtValoreID, txtRicalcolatoID, lblDeltaID) {
// Ricalcolo il valore aggiornato
var Valore = parseFloat($("#" + txtValoreID).val()).toFixed(2);
var Ricalcolato = parseFloat($("#" + txtRicalcolatoID).val()).toFixed(2);
$("#" + lblDeltaID).html(parseFloat(Valore - Ricalcolato).toFixed(2).replace('.', ','));
}
That refers to textbox and label in a gridview:
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="txtValore" Width="90%" Text='<%# string.Format("{0:N}", Eval("Valore"))%>' runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="txtRicalcolato" Text='<%# string.Format("{0:N}", Eval("Ricalcolato")) %>' runat="server" />
</ItemTemplate>
</asp:TemplateField>
(...)
<asp:TemplateField HeaderText="Delta">
<ItemTemplate>
<asp:Label ID="lblDelta" Text='<%# string.Format("{0:N}", Eval("Delta"))%>' runat="server" />
</ItemTemplate>
</asp:TemplateField>
And I'm assigning it in the DataBound:
txtValore.Attributes.Add("onchange", "modifica('" + txtValore.ClientID + "', '" + txtRicalcolato.ClientID + "','" + lblDelta.ClientID + "')");
txtRicalcolato.Attributes.Add("onchange", "modifica('" + txtDaLiquidare.ClientID + "', '" + txtRicalcolato.ClientID + "','" + lblDelta.ClientID + "')");
and it's working perfectly. The problem is that when the gridview have a lot of records, databound is affecting the performance, so my first question is, am I improving this performance moving the assignment from databound server code to aspx page? And if yes, how can I do that? Because I'm trying like this:
asp:TextBox ID="txtValore" onchange="test(this.id)" Text='<%# string.Format("{0:N}", Eval("PremioLiquidare"))%>' runat="server" />
and this:
function test(txtID) {
alert('TEST ' + $(this));
alert('TEST ' + $(this).val());
alert('TEST ' + $("#" + txtID).val());
alert('TEST ' + $("#" + txtID).find("[id*='txtRicalcolato']").val());
alert('TEST ' + $("#" + txtID).closest("[id*='txtRicalcolato']").val());
alert('TEST ' + $(this).find("[id*='txtRicalcolato']").val());
alert('TEST ' + $(this).closest("[id*='txtRicalcolato']").val());
}
But the first is printing TEST Object object, the second blank and the third the correct value, but the others are undefined.. What I'm doing wrong?
The rendered HTML is:
<table class="mGrid" id="ctl00_MainContent_grid">
<tbody>
(...)
<tr>
(...)
<td>
<input name="ctl00$MainContent$grid$ctl03$txtValore" value="1.693,44" id="ctl00_MainContent_grid_ctl03_txtValore" onchange="test(this.id)" type="text">
</td>
<td>
<input name="ctl00$MainContent$grid$ctl03$txtRicalcolato" value="169,34" id="ctl00_MainContent_grid_ctl03_txtRicalcolato" onchange="test(this.id)" type="text">
</td>
(...)
<td>
<span id="ctl00_MainContent_grid_ctl03_lblDelta">-1.524,10</span>
</td>
(...)
</tr>
(...)
</tbody>
</table>
You are trying to search from the element down with
find
, and the element upwards withclosest
but the target element is in another branch of the DOM.find
only searches from the element downwards (its descendants)closest
searches the ancestors only (not literally the closest match).You need to search up with
closest
, thenfind
down:e.g. the 3rd and 4th ones should be:
Suggestion: Use a single Delegated Event Handler
Instead of adding attribute-based change handlers, use a single delegated event handler attached to a non-changing ancestor element (e.g. a surrounding
table
ordiv
). This has a much lower overhead and keeps all the code in one place.Based on your new HTML example, a delegated event handler would go something like this:
Notes:
onChange
attributes from your inputs.$('.mGrid input[id$="txtValore"]').on('change', function(){
or$('.mGrid input[id$="txtValore"]').change(function(){
but delegated events are more flexible.[id$=""]
selector is an ends-with selector as your actual IDs start with a generate prefix..mGrid
), then applying the jQuery selector to the elements in the bubble-chain that caused the event, then applying the function. This works for dynamically added elements too as the selector is run at event time and not event-registration time.Update: ID generation changed
In comment you mention the ID generation changed so that the suffix was no longer at the end of the id (a underscore and number was appended). jQuery also has an attribute contains selector
*=
which would change the example code to: