I have the following ASCX control:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="CalendarDay.ascx.cs"
Inherits="MVP.Calendar.CalendarDay" %>
<asp:Panel ID="DayWrapper" runat="server"
CssClass="day col p-2 border border-left-0 border-top-0 text-truncate">
<div class="date d-flex align-items-center justify-content-center <%= CurrentDayTag %>">
<%= DayText %>
</div>
<div class="row pl-3 pr-3 d-none d-sm-block">
<p class="info"><%= InfoText %></p>
<a class="d-block rounded small align-self-start" title="Test 1"><%= PriceText %></a>
</div>
</asp:Panel>
Here's part of its code-behind:
public partial class CalendarDay : UserControl, IPostBackEventHandler
{
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
DayWrapper.CssClass += DayBackgroundTag;
DayWrapper.Attributes["onclick"] = "javascript:__doPostBack('" + UniqueID + "', '')";
}
void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
{
OnDayClicked();
}
}
Here's the DOM that's rendered:
<div id="MainContent_CalDate_WeekRepeater_DayRepeater_3_CalendarDay_1_DayWrapper_1"
class="day col p-2 border border-left-0 border-top-0 text-truncate day--fully-available"
onclick="javascript:__doPostBack('ctl00$MainContent$CalDate$WeekRepeater$ctl03$DayRepeater$ctl01$CalendarDay', '')">
<div class="date d-flex align-items-center justify-content-center ">17</div>
<div class="row pl-3 pr-3 d-none d-sm-block">
<p class="info"></p>
<a class="d-block rounded small align-self-start" title="Test 1">10€</a>
</div>
</div>
This ASCX control is inside a rather complex hierarchy, but ultimately, all of this is inside an UpdatePanel
.
On that rendered HTML, if I click on the 17 or on the 10€ text, I get a full page postback, but if I click anywhere else within the top div, I get an AJAX call from my UpdatePanel
. Both these calls are triggering the RaisePostBackEvent
function correctly.
I want and would expect to get the AJAX call every time.
Why is this happening, and how can I fix it?
You may need to register the control for async postback. Try changing this;
DayWrapper.Attributes["onclick"] = "javascript:__doPostBack('" + UniqueID + "', '')";
To this:
DayWrapper.Attributes["onclick"] = Page.ClientScript.GetPostBackEventReference(new PostBackOptions(this));
ScriptManager.GetCurrent(Page).RegisterAsyncPostBackControl(this);
The main difference here the call to RegisterAsyncPostBackControl
which tells the ScriptManager
that the control should indeed be used for async postback. I am also changing the way that the postback link is generated. This might not actually be necessary, but it seems cleaner than manually generating the JavaScript.