How to stubbornly keep an old JavaScript event handler in a webform page ported to ASP.NET MVC?

0

Considering a single line of markup in an .ASPX file as follows:

<asp:DropDownList ID="drpdownPayPlan" runat="server" onchange="javascript: document.getElementById('txtPayAmount').value = document.getElementById('drpdownPayPlan').value.replace(',', '');">

May I keep my embedded JavaScript handler code and how? I understand there are lots of other issues when porting a WebForms application to ASP.NET MVC, but I'd like to keep it simple and just focus on this one line. Currently, the error I get on this line is:

Unhandled exception at line 410, column 115 in http://localhost:3835/Policy/QuotePayments?QN=XYZ-1234567&PN=ABCDEFGHIJ&AC=123456789

0x800a138f - JavaScript runtime error: Unable to get property 'value' of undefined or null reference

When rendered, the source code actually reads as follows on line 410 (I understand the reason for mangled names):

    <select name="ctl00$MainContent$drpdownPayPlan" id="MainContent_drpdownPayPlan" onchange="javascript: document.getElementById(&#39;txtPayAmount&#39;).value = document.getElementById(&#39;drpdownPayPlan&#39;).value.replace(&#39;,&#39;, &#39;&#39;);">

So, with all due respect--without giving me a sermon on how to properly port a WebForms project to MVC (sorry for sounding like a rebellious and uncooperative teenager!)--how can I resolve the issue I'm having with this one line of markup?

javascript
asp.net-mvc
event-handling
porting
asked on Stack Overflow Apr 6, 2017 by ShieldOfSalvation • edited Apr 6, 2017 by ShieldOfSalvation

1 Answer

1

The 0x800a138f error in ASPX page often occurs when trying to assign server-side control name (which doesn't exist in client-side due to default server control behavior assigning AutoID) instead of client-side name, therefore document.getElementById('drpdownPayPlan') returns undefined.

There are 2 ways to resolve it:

  1. Assign ClientIDMode="Static" to every server control involved (I assumed that txtPayAmount is a TextBox server control, if you're using literal input text box leave txtPayAmount as is).

    <asp:TextBox ID="txtPayAmount" runat="server" ClientIDMode="Static" />
    <asp:DropDownList ID="drpdownPayPlan" runat="server" ClientIDMode="Static" onchange="javascript: document.getElementById('txtPayAmount').value = document.getElementById('drpdownPayPlan').value.replace(',', '');">
    

    NB: The ClientIDMode attribute available in .NET version 4.0 and later.

  2. Use <%= drpdownPayPlan.ClientID %> to refer client-side ID while keeping control IDs in AutoID state (again I assumed txtPayAmount is a TextBox control here, leave it if txtPayAmount is a literal text box).

    <asp:DropDownList ID="drpdownPayPlan" runat="server" onchange="javascript: document.getElementById('<%= txtPayAmount.ClientID %>').value = document.getElementById('<%= drpdownPayPlan.ClientID %>').value.replace(',', '');">
    

Note that I recommend you to separate the JS part from server control in a function and call the function name as given below:

<asp:DropDownList ID="drpdownPayPlan" runat="server" onchange="changePayAmount();">

<script type="text/javascript">
function changePayAmount() {
    document.getElementById('<%= txtPayAmount.ClientID %>').value = document.getElementById('<%= drpdownPayPlan.ClientID %>').value.replace(',', '');
}
</script>

PS: In MVC context, the id for every HTML helper element can be easily defined in HTML attributes part like this:

@Html.DropDownListFor(model => model.PayPlan, Model.PayPlanList as SelectList, new { id = "drpdownPayPlan" })

Similar issues:

0x800a138f - JavaScript runtime error: Unable to get property 'value' of undefined or null reference

JavaScript runtime error: Unable to get property 'value' of undefined or null reference

answered on Stack Overflow Apr 7, 2017 by Tetsuya Yamamoto • edited May 23, 2017 by Community

User contributions licensed under CC BY-SA 3.0