The problem with postbacks inside a custom property control
Custom property types in EPiServer are often used to present an editor with fairly complex user interfaces. Such interfaces often include several actions that require postbacks to the server before the page is saved.
However, by default EPiServer checks if the user is about to leave a page when one or more properties have been modified but not saved – simply to avoid an editor editing content and then accidentally browsing to another page without saving it.
This causes an alert box to pop up asking the user “Are you sure you want to navigate from this page? You have made changes to this page”. Although useful at times we need a way to suppress this message for intended postbacks when editing a page.
An example
Here’s a simple custom property user control (created using the EPiServer user control custom property framework in EPiServer Template Foundation) which allows the editor to add a list of strings:
<asp:Repeater ID="ListOfStringsRepeater" runat="server">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li><%# Container.DataItem %></li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
<asp:Label AssociatedControlID="NewItemName" runat="server">Enter name for the new item:</asp:Label>
<asp:TextBox ID="NewItemName" runat="server" />
<asp:Button Text="Add" OnClick="NewItemButtonClicked" runat="server" />
The Add button is wired up to a simple event handler which adds the string to the property value (our user control custom property is typed as List<string>):
protected void NewItemButtonClicked(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(NewItemName.Text))
{
return;
}
Value.Add(NewItemName.Text.Trim());
ListOfStringsRepeater.DataSource = Value;
ListOfStringsRepeater.DataBind();
}
It presents the editor with this rudimentary user interface:
However, if we click the Add button we’ll get a message dialog warning us that we’re about to leave the page:
Obviously we want to suppress this message for when our Add button is clicked.
The solution
There are two main ways to resolve this and suppress the page-leave check.
Using the EPiServer ToolButton control
The first one would be to use EPiServer’s ToolButton control instead of the standard ASP.NET Button control. This makes it easy to disable the page-leave check by setting the DisablePageLeaveCheck property. It also has the added advantage of providing us with a visual style loyal to the native EPiServer UI.
The following markup…
<EPiServerUI:ToolButton Text="Add" SkinID="Add" DisablePageLeaveCheck="true" OnClick="NewItemButtonClicked" runat="server" />
…renders a nice Add button that looks a lot more like EPiServer:
And since we hooked it up to the same click event it will do the exact same thing as our previous Button control – but without the annoying alert message when we click it!
Note that you need to add a tag prefix for the EPiServer UI controls in web.config if you want to use them:
<pages>
<controls>
<add tagPrefix="EPiServerUI" namespace="EPiServer.UI.WebControls" assembly="EPiServer.UI"/>
<!-- Additional tag prefixes here -->
</controls>
</pages>
Using the ScriptDisablePageLeaveEvent control
There are times when using EPiServer’s UI controls isn't suitable, and for those cases you need to disable the page-leave check in some other way. One way to do that is to use EPiServer’s ScriptDisablePageLeaveEvent control.
Reverting to our previous Button control, we could use the following to disable the page-leave check for it:
<EPiServerScript:ScriptDisablePageLeaveEvent EventTargetId="NewItemButton" EventType="Click" runat="server" />
<asp:Button Text="Add" OnClick="NewItemButtonClicked" ID="NewItemButton" runat="server" />
The ScriptDisablePageLeaveEvent has two properties for specifying for which control and event the page-leave check should be disabled. In this case we disable the page-leave check for the Click event of the NewItemButton control.
Now we’re able to click the Add button without the page-leave prompt.
In order to use the ScriptDisablePageLeaveEvent control you need to add two tag prefixes to web.config:
<add tagPrefix="EPiServerScript" namespace="EPiServer.ClientScript.WebControls" assembly="EPiServer" />
<add tagPrefix="EPiServerScript" namespace="EPiServer.UI.ClientScript.WebControls" assembly="EPiServer.UI" />