Question

I am having a strange problem with my Ektron pagebuilder widgets.

For whatever reason, when i do a postback to the server from any button inside the widget that switches the widget's views, the scripts within these views do not execute.

The multiview that controls what 'mode' the widget is in seems to be a regular multiview at face value, so I am not sure why it would behave this way. I have tested this by adding a second multiview to the page which does nothing but swap views and alert, which works as expected when placed on the template outside of the widget, but fails to execute its scripts while inside of the widget. Additionally, when any button is clicked inside the widget, ektron opens a loading image that disappears when the server posts back, regardless of which multiview is clicked. This leads me to believe that Ektron is actively doing something to suppress the execution of these widget scripts, though I am not even sure how it would go about it, given that the scripts appear correctly in the view once it renders.

widget code:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="TestWidget.ascx.cs" Inherits="widgets_TestWidget" %>

<asp:MultiView ID="ViewSet" runat="server" ActiveViewIndex="0">
    <asp:View ID="View" runat="server">
        <script>alert('this runs');</script>
        <asp:Label ID="OutputLabel" runat="server"></asp:Label>
    </asp:View>
    <asp:View ID="Edit" runat="server">
        <div id="<%=ClientID%>_edit">
            <script>alert('but for some reason, this does not run');</script>
            <asp:TextBox ID="HelloTextBox" runat="server" Style="width: 95%"> </asp:TextBox>
            <asp:Button ID="CancelButton" runat="server" Text="Cancel" OnClick="CancelButton_Click" />
            &nbsp;&nbsp;
                <asp:Button ID="SaveButton" runat="server" Text="Save" OnClick="SaveButton_Click" />
        </div>
    </asp:View>

</asp:MultiView>

<!--code below works properly outside of the widget and fails inside of it -->

<asp:MultiView ID="uxmulti" runat="server" ActiveViewIndex="0">
    <asp:View ID="view1" runat="server">
        <script>alert('this runs');</script>
        <asp:Button ID="ux_b1" runat="server" OnClick="ux_b1_Click" Text="to edit" />
    </asp:View>
    <asp:View ID="edit1" runat="server">
        <script>alert('as does this, but not inside the widget');</script>
        <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="to view" />
    </asp:View>
</asp:MultiView>

Widget codebehind:

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using Ektron.Cms.Widget;
using Ektron.Cms;
using Ektron.Cms.API;
using Ektron.Cms.Common;
using Ektron.Cms.PageBuilder;
using System.Configuration;

public partial class widgets_TestWidget : System.Web.UI.UserControl, IWidget
{
    #region properties
    private string _HelloString;
    [WidgetDataMember("Hello World")]
    public string HelloString { get { return _HelloString; } set { _HelloString = value; } }
    #endregion

    IWidgetHost _host;
    protected ContentAPI m_refContentApi = new ContentAPI();
    protected EkMessageHelper m_refMsg;

    protected void Page_Init(object sender, EventArgs e)
    {
        string sitepath = new CommonApi().SitePath;
        JS.RegisterJSInclude(this, JS.ManagedScript.EktronJS);
        JS.RegisterJSInclude(this, JS.ManagedScript.EktronModalJS);
        Css.RegisterCss(this, Css.ManagedStyleSheet.EktronModalCss);
        _host = Ektron.Cms.Widget.WidgetHost.GetHost(this);
        m_refMsg = m_refContentApi.EkMsgRef;
        _host.Title = m_refMsg.GetMessage("lbl hello world widget");
        _host.Edit += new EditDelegate(EditEvent);
        _host.Maximize += new MaximizeDelegate(delegate() { Visible = true; });
        _host.Minimize += new MinimizeDelegate(delegate() { Visible = false; });
        _host.Create += new CreateDelegate(delegate() { EditEvent(""); });
        CancelButton.Text = m_refMsg.GetMessage("btn cancel");
        SaveButton.Text = m_refMsg.GetMessage("btn save");
        PreRender += new EventHandler(delegate(object PreRenderSender, EventArgs Evt) { SetOutput(); });
        string myPath = string.Empty;
        if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["ek_helpDomainPrefix"]))
        {
            string helpDomain = ConfigurationManager.AppSettings["ek_helpDomainPrefix"];
            if ((helpDomain.IndexOf("[ek_cmsversion]") > 1))
            {
                myPath = helpDomain.Replace("[ek_cmsversion]", new CommonApi().RequestInformationRef.Version);
            }
            else
            {
                myPath = ConfigurationManager.AppSettings["ek_helpDomainPrefix"];
            }
        }
        else
        {
            myPath = sitepath + "Workarea/help";
        }
        _host.HelpFile = myPath + "EktronReferenceWeb.html#Widgets/Creating_the_Hello_World_Widget.htm";
        ViewSet.SetActiveView(View);
    }

    protected void SetOutput()
    {
        OutputLabel.Text = HelloString;
    }

    void EditEvent(string settings)
    {
        HelloTextBox.Text = HelloString;
        ViewSet.SetActiveView(Edit);
    }
    protected void SaveButton_Click(object sender, EventArgs e)
    {
        HelloString = HelloTextBox.Text;
        _host.SaveWidgetDataMembers();
        ViewSet.SetActiveView(View);
    }
    protected void CancelButton_Click(object sender, EventArgs e)
    {
        ViewSet.SetActiveView(View);
    }
    protected void ux_b1_Click(object sender, EventArgs e)
    {
        uxmulti.SetActiveView(edit1);
    }
    protected void Button1_Click(object sender, EventArgs e)
    {
        uxmulti.SetActiveView(view1);
    }

}

This can be worked around using a dirty eval statement, but that is far from ideal. Any ideas as to why this would behave this way or how to resolve it?

Ektron 8.6.1, Server 2008 R2, SQL Server 2008.

Was it helpful?

Solution

When the widget switches between views (i.e. from View to Edit) it does this using an Ajax postback (I believe inside an UpdatePanel). This means any inline scripts or any scripts set to run "onload" will not execute due to the partial postback.

So, you need to focus on how to make javascript code execute after an UpdatePanel refreshes. You could try something like this:

function foo()
{
    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequestHandler);
}
function endRequestHandler(sender, args)
{
    // Do your stuff
    alert('Update Panel routine is now complete');
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top