Hi, I’m the developer who had to chase down this bug for our latest Web Forms project. Below is the exact path I took from seeing the red error line in IE to pushing a cleaner, user-friendly page into production. I’m sharing every step so the next person (maybe future-me) can fix it in minutes instead of hours.
Error Show:
<script type="text/javascript">
//<![CDATA[
var theForm = document.forms['ctl01'];
if (!theForm) {
theForm = document.ctl01;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
//]]>
</script>
Asp.Net/HTML:
<asp:ScriptManager ID="manager" runat="server" ></asp:ScriptManager>
<asp:UpdatePanel ID="platformOutputTypes" runat="server" UpdateMode="Always" >
<ContentTemplate >
<p>
<label>Platform</label>
<asp:DropDownList ID="platform" AutoPostBack="true" runat="server" onselectedindexchanged="PlatformSelectedIndexChanged" ></asp:DropDownList>
</p>
<asp:CheckBoxList TextAlign="Left" ID="reportOutputTypes" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
I’m also using jQuery on the page.
The Code That Explode
I started with a bare bones test page so I could reproduce the problem without the noise of our full master page. Paste this into a brand-new Web Forms site and pick a value in the drop-down you’ll slam straight into theForm.submit();
.
<%@ Page Language="C#" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title>UpdatePanel test</title>
</head>
<body>
<form id="ctl01" runat="server">
<asp:ScriptManager ID="manager" runat="server" />
<asp:UpdatePanel ID="platformOutputTypes" runat="server" UpdateMode="Always">
<ContentTemplate>
<p>
<label>Platform </label>
<asp:DropDownList
ID="platform"
AutoPostBack="true"
OnSelectedIndexChanged="PlatformSelectedIndexChanged"
runat="server">
</asp:DropDownList>
</p>
<asp:CheckBoxList ID="reportOutputTypes" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>
And here’s the little script ASP.NET pushes into the page submit()
is where IE trips:
<script type="text/javascript">
var theForm = document.forms['ctl01'];
if (!theForm) { theForm = document.ctl01; }
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit(); <!-- boom -->
}
}
</script>
Why IE Screams “Member not found”
- Straight fact:
theForm
is the real<form>
. - JavaScript expects
theForm.submit
to be a function. - Ancient IE has a quirk any control called
submit
inside that form hides the real function. - So when the script calls
submit()
, IE finds an<input>
element instead of the built-in method and raises Member not found.
Sneaky Ways The Name Slips in
Culprit | What it looks like in HTML |
---|---|
A later button | <input type="button" id="submit" …> |
A jQuery plug-in | <input type="hidden" name="submit" …> |
A poorly-named server control | <asp:Button ID="submit" …> |
My Quick Rescue Checklist
- View the generated HTML (F12 ➜ Elements ➜ search
submit
). - Rename every
id
/name
that collides—submit
➜btnSubmit
,reset
➜btnReset
, etc. - Re-load, smile, zero errors.
Tip: In ASP.NET 4+ set ClientIDMode="Static"
and take full control of client IDs.
The Cleaned Up
I rewired the markup so no control shadows a form method and split the logic into tidy pieces.
<asp:ScriptManager runat="server" />
<asp:UpdatePanel ID="upMain" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<!-- platform selector -->
<asp:DropDownList
ID="ddlPlatform"
runat="server"
AutoPostBack="true"
OnSelectedIndexChanged="PlatformChanged">
</asp:DropDownList>
<!-- a real button, safely named -->
<asp:Button ID="btnGo" runat="server"
Text="Refresh" CssClass="btn"
OnClick="BtnGo_Click" />
<!-- outputs that depend on the platform -->
<asp:CheckBoxList ID="cblOutputs" runat="server" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ddlPlatform"
EventName="SelectedIndexChanged" />
<asp:AsyncPostBackTrigger ControlID="btnGo"
EventName="Click" />
</Triggers>
</asp:UpdatePanel>
Code-behind (C#):
Protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ddlPlatform.DataSource = GetPlatforms();
ddlPlatform.DataBind();
}
}
protected void PlatformChanged(object sender, EventArgs e) => ReloadOutputs();
protected void BtnGo_Click(object sender, EventArgs e) => ReloadOutputs();
private void ReloadOutputs()
{
cblOutputs.DataSource = GetOutputs(ddlPlatform.SelectedValue);
cblOutputs.DataBind();
}
Result: the page posts back smoothly, no JavaScript crash, and our QA team finally closed the ticket.
Little UX Booster
All front-end only drop each snippet in Site.js and register it with ScriptManager
.
Loading Spinner During async
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(() => $('#spinner').show());
Sys.WebForms.PageRequestManager.getInstance().add_endRequest (() => $('#spinner').hide());
<div id="spinner" style="display:none">Loading…</div>
Remember The Last Chosen Platform
$(function () {
const key = 'lastPlatform';
const $ddl = $('#<%= ddlPlatform.ClientID %>');
$ddl.val(localStorage.getItem(key) || $ddl.val());
$ddl.change(() => localStorage.setItem(key, $ddl.val()));
});
Instant Client Side Filter for The Check Box List
$(function () {
const $list = $('#<%= cblOutputs.ClientID %>');
const $search = $('<input type="text" placeholder="Filter…">').insertBefore($list);
$search.on('input', function () {
const q = this.value.toLowerCase();
$list.find('input[type=checkbox]').each(function () {
const $item = $(this).parent();
$item.toggle($item.text().toLowerCase().includes(q));
});
});
});
Final Thought
That’s the one-line lesson this bug hammered into my brain. The fix was nothing more than a rename, yet it burned a chunk of my afternoon because I chased the Update Panel, jQuery, even the network tab before I opened the raw HTML.