I have an ASP.NET
page that loads a bunch of data from the db into a ListView
with a LayoutTemplate
and ItemTemplate
. When the user hovers over a row, the last column switches its content for a textbox containing the same value, making it editable. This works in Chrome and now I almost got it to work in IE10
as well.
What issue remains, is that when backspacing in the textbox, the first keystroke seems to remove the textbox itself but leaves the content and a second keystroke renders both the textbox and the content invisible. Clicking inside the textbox renders it visible again and so does moving the mouse cursor outside the textbox area.
I was unable to make a Snaggit of this, I tried.
Sadly, the jsfiddle here does NOT reproduce the issue in IE10
so, risking the old wall of text, I'm including the entire ASP.NET Page
in the hopes that someone else can reproduce this and figure out what I have not been able to in two days. Don't worry, it's not huge. I've tested this code on another machine (using the same version of IE10
as well) and the issue is identical.
As usual: any insights into the why and how of this problem are appreciated.
<%@ Page Title="EditInvoiceNumberFormat" Language="C#" MasterPageFile="~/myApplication.master" AutoEventWireup="true" CodeBehind="EditInvoiceNumberFormat.aspx.cs" Inherits="myApplication.EditInvoiceNumberFormat" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<script src="http://code.jquery.com/jquery-1.9.1.js" type="text/javascript"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js" type="text/javascript"></script>
<asp:ScriptManager ID="ScriptManager" runat="server" EnablePageMethods="true"></asp:ScriptManager>
<script type="text/javascript">
$(document).ready(function () {
$('input[id$="txtBoxInvoiceNumber"]').width($('span[id$="lblInvoiceNumber"]').closest('td').width() - 5);
$('tr[id*="itemRow"]').mouseenter(function () {
$clickedRow = $(this);
var invNr = $clickedRow.find('span[id$="lblInvoiceNumber"]').text();
//if the label/span is still visible
if ($clickedRow.find('input[id$="txtBoxInvoiceNumber"]').is(':hidden')) {
//switch to edit mode
$clickedRow.find('span[id$="lblInvoiceNumber"]').hide();
$clickedRow.find('input[id$="txtBoxInvoiceNumber"]').show();
//copy over the value and focus the cursor
$clickedRow.find('input[id$="txtBoxInvoiceNumber"]').val(invNr).focus();
//if the value changes
$clickedRow.find('input[id$="txtBoxInvoiceNumber"]').on('input propertychange', function () {
//if the button was already visible, leave it that way
if ($clickedRow.find('input[id$="btnSaveInvNrFormat"]').is(':hidden')) {
$clickedRow.find('td[id$="SaveOption"]').show();
$clickedRow.find('input[id$="btnSaveInvNrFormat"]').show();
}
//but if it changes back to what it was within the same 'mouseenter' moment
if ($clickedRow.find('input[id$="txtBoxInvoiceNumber"]').val() == $clickedRow.find('span[id$="lblInvoiceNumber"]').text()) {
$clickedRow.find('td[id$="SaveOption"]').hide();
$clickedRow.find('input[id$="btnSaveInvNrFormat"]').hide();
}
});
}
});
$('tr[id*="itemRow"]').mouseleave(function () {
$rowLosingFocus = $(this);
//if the save button isn't visible
if ($rowLosingFocus.find('input[id$="btnSaveInvNrFormat"]').is(':hidden')) {
$rowLosingFocus.find('span[id$="lblInvoiceNumber"]').text($rowLosingFocus.find('input[id$="txtBoxInvoiceNumber"]').val()).show();
$rowLosingFocus.find('input[id$="txtBoxInvoiceNumber"]').hide();
}
});
//prevent page postback on button click
$('input[id$="btnSaveInvNrFormat"]').click(function (e) {
e.preventDefault();
//update the value to the db
UpdateInvoiceNrFormat($(this));
});
//prevent postback on enter
$('input[id$="txtBoxInvoiceNumber"]').on('keydown', function (e) {
if (e.keyCode == 13) { //if 'enter' key
e.preventDefault();
return false;
}
else return true;
});
//prevent backspace to navigate back
var rx = /INPUT|SELECT|TEXTAREA/i;
$(document).bind("keydown keypress", function (e) {
if (e.which == 8) { // 8 == backspace
if (!rx.test(e.target.tagName) || e.target.disabled || e.target.readOnly) {
e.preventDefault();
}
}
});
});
function UpdateInvoiceNrFormat(leButton) {
$buttonClicked = $(leButton);
//$buttonClicked.focus();
$closestRow = $buttonClicked.closest('tr');
$saveResultMsg = $closestRow.find('span[id$="SaveResultMsg"]');
var invNrFormat = $closestRow.find('input[id$="txtBoxInvoiceNumber"]').val(),
companyName = $closestRow.find('span[id$="lblCompanyName"]').text(),
invoiceType = $closestRow.find('span[id$="lblInvoiceType"]').text();
//page method that actually updates the value to the db
PageMethods.UpdateInvoiceNumberFormat(companyName, invoiceType, invNrFormat, onSuccess, onError);
function onSuccess(result) {
$buttonClicked.hide();
$closestRow.find('span[id$="SaveResultMsg"]').text(result).show().fadeOut(1500, function () {
$(this).hide();
$(this).closest('td').hide();
});
}
function onError(result) {
$buttonClicked.hide();
$closestRow.find('span[id$="SaveResultMsg"]').text('Error:' + result).show();
}
}
</script>
<asp:ListView ID="InvoiceNumberFormatList" runat="server">
<LayoutTemplate>
<div runat="server" class="AltRow">
<p>Select a row to edit the invoice number format.</p>
<table id="InvoiceNumberFormatTable" runat="server">
<tr>
<th>Company Name</th>
<th>Invoice Type</th>
<th>Invoice Number Format</th>
<th></th>
</tr>
<tr id="itemPlaceholder" runat="server"></tr>
</table>
</div>
</LayoutTemplate>
<ItemTemplate>
<tr id="itemRow" runat="server">
<td style="padding:6px">
<asp:Label ID="lblCompanyName" runat="server" Text='<%# Bind("CompanyName") %>' />
</td>
<td style="padding:6px">
<asp:Label ID="lblInvoiceType" runat="server" Text='<%# Bind("InvoiceType") %>' />
</td>
<td>
<asp:Label ID="lblInvoiceNumber" runat="server" Text='<%# Bind("InvoiceNumber") %>' />
<asp:TextBox ID="txtBoxInvoiceNumber" runat="server" style="display:none"></asp:TextBox>
</td>
<td id="SaveOption" style="display:none">
<asp:Button ID="btnSaveInvNrFormat" runat="server" Text="Save" />
<span id="SaveResultMsg"></span>
</td>
</tr>
</ItemTemplate>
</asp:ListView>
<div id="EditWindow" title="Edit Invoice Number Format">
</div>
</asp:Content>