locked
LinkButton in User Control's click event verification on client side RRS feed

  • Question

  • User-809368424 posted
    Hi. I have a navigation menu user control that stays on top of every aspx page with linkbuttons in it. 
    I am using a Master page that has the navigation user control at the top and web forms right below it. 
    What I am trying to accomplish is as follows: I have a webform with save/update functionality. My client 
    wants a javascript confirmation box ('are you sure you want to exit without saving your changes') for 
    users who makes changes in that form and before saving their changes, clicking on one of those 
    navigation user control's link buttons. My code is still work-in-progress, I have not written the IsDirty 
    functionality yet, but I am having trouble to show the confirm box if I have the PostBackUrl in the acsx 
    page. The click event simply navigates to the PostBackUrl page. I am thinking, the best way is to create an 
    event and in the aspx page (by bubbling the event in master page) I will have to remove the PostBackUrl and 
    pass a confirmation javascript code via a public attribute defined in the ascx. (I am open to any ideas if 
    I am thinking this wrong).
    
    
    Below are some partial codes that are related to my problem:

    User Control (ascx):

    <asp:LinkButton ID="m_lbInvestigationList" runat="server" Text="Investigation List" OnClick="InvestigationList_OnClick" 
    CausesValidation="false" />

    User Control Code-Behind:

    public partial class NavControl : System.Web.UI.UserControl
    {
    public string LinkButtonURL
    {
    get { return m_lbInvestigationList.PostBackUrl; }
    set { m_lbInvestigationList.PostBackUrl = value; }
    }
    public string LinkButtonConfirm
    {
    set { m_lbInvestigationList.OnClientClick = value; }
    }

    protected override void OnInit(EventArgs e)
    {
    //m_lbInvestigationList.Attributes.Add("PostBackUrl", "~/Investigations.aspx");
    m_lbInvestigationList.PostBackUrl = "~/Investigations.aspx";
    base.OnInit(e);
    }
    public delegate void OnInvestigationListClickDelegate(string _string);

    public event OnInvestigationListClickDelegate OnInvestigationListClick;

    protected void InvestigationList_OnClick(object sender, EventArgs e)
    {
    if (OnInvestigationListClick != null)
    {
    this.OnInvestigationListClick(string.Empty);
    }
    else
    {
    Response.Redirect("Investigations.aspx");
    }
    }
    }
    In the Master Page, I have written the following:
    public string NavLinkURL
    {
    get { return NavBox1.LinkButtonURL; }
    set { NavBox1.LinkButtonURL = value; }
    }
    public string NavLinkConfirm
    {
    set { NavBox1.LinkButtonConfirm = value; }
    }

    public delegate void MasterInvestigationListClickDelegate(string _string);
    public event MasterInvestigationListClickDelegate MasterInvestigationListClick;

    protected void Page_Load(object sender, EventArgs e)
    {
    this.NavBox1.OnInvestigationListClick += 
    new Compliance.Web.Controls.NavControl.OnInvestigationListClickDelegate(NavBox1_OnInvestigationListClick);
    }

    void NavBox1_OnInvestigationListClick(string _string)
    {
    if (MasterInvestigationListClick != null)
    {
    this.MasterInvestigationListClick(string.Empty);
    }
    }
    And finally, in the aspx page, I have the following code:
    protected override void OnLoad(EventArgs e)
    {
    base.OnLoad(e);
    Master.MasterInvestigationListClick += 
    new SiteTemplate.MasterInvestigationListClickDelegate(Master_MasterInvestigationListClick);
    }
    ..
    public void Master_MasterInvestigationListClick(string _string)
    {
    Master.NavLinkURL = "~/Investigations.aspx";
    Master.NavLinkConfirm = "return confirm('test');";
    //Response.Write("<script>confirm('Leave without saving your changes?');</script>");
    }
    But the Master_MasterInvestigationListClick function is useless, it never gets called. Please tell me if I am
    missing anything or if I am approaching this issue completely wrong. I am out of ideas.
    Thanks,
    yardim
    Saturday, November 19, 2011 12:17 PM

Answers

  • User-809368424 posted

    Thanks JKirkerx,

    I decided to go with a less functional but enough logic and wrote a function in code-behind that uses ClientScriptManager type and adds a "window.onbeforeunload" event. Here is my code:

            protected void JavaScriptConfirmLogic()
    {
    //add javascript
    string csX = "ConfirmExitClickScript";
    Type csType = this.GetType();
    ClientScriptManager csm = Page.ClientScript;
    if (!csm.IsClientScriptBlockRegistered(csType, csX))
    {
    StringBuilder csText = new StringBuilder();
    csText.Append("<script type='text/javascript'>");
    csText.Append("var needToConfirm = true;");
    csText.Append("window.onbeforeunload = confirmExit;");
    csText.Append("function confirmExit() { ");
    csText.Append("if (needToConfirm) ");
    csText.Append("return 'If you press OK now, any changes you have made for this item will be lost.'; ");
    csText.Append("} </script>");
    csm.RegisterClientScriptBlock(csType, csX, csText.ToString(), false);
    }
    }
    I am also using an OnCommand event and if the page is in edit or new mode, I am calling the above function and adding the 
    client-side script to the page.
            public void OnCommand(object sender, CommandEventArgs e)
    {
    try
    {
    switch (e.CommandName)
    {
    case PageCommandsEnum.Edit:
    {
    fvInvestigationDetails.ChangeMode(FormViewMode.Edit);
    JavaScriptConfirmLogic();
    PopulateControls(PageCommandsEnum.Edit);
    break;
    }
    case PageCommandsEnum.Cancel:
    {
    if (InvestigationNumberr > 0)
    {
    fvInvestigationDetails.ChangeMode(FormViewMode.ReadOnly);
    PopulateControls(PageCommandsEnum.Cancel);
    }
    else
    {
    Response.Redirect("Investigations.aspx");
    }
    break;
    }
    case PageCommandsEnum.New:
    {
    fvInvestigationDetails.ChangeMode(FormViewMode.Insert);
    JavaScriptConfirmLogic();
    PopulateControls(PageCommandsEnum.New);
    break;
    }
    ....
    Of course, the rest of the buttons in the page have a OnClientClick event call as:
    <asp:button id="btnEdit" runat="server" OnCommand="OnCommand" commandname="Edit" text="Edit Investigation" 
    OnClientClick="needToConfirm = false"/>
    Otherwise, the popup will appear afer every click event. "needToConfirm" is by default true, so if a user clicks on the navigation links, it will send a true to the javascript function.
    
    
    So that took care of warning the user when in edit mode and trying to leave... (Also in my first post, when I said navigation menu control, 
    I didn't actually mean the asp.net control, just a user control created for navigation purposes.)
    Thanks for taking the time though. I will have to get myself more familiarized with jQuery and find better solutions to my problems soon.
    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, November 28, 2011 7:23 PM

All replies

  • User3866881 posted

     protected override void OnLoad(EventArgs e)
    {
    base.OnLoad(e);
    Master.MasterInvestigationListClick += 
    new SiteTemplate.MasterInvestigationListClickDelegate(Master_MasterInvestigationListClick);
    }

    Hello:)

    You don't need to handle the event like this, because OnLoad will get fired again and again. So just drag and drop the user control onto the normal page and in the event panel, double click the event and you can write codes there.

    Have a try and hope this helps!

    Sunday, November 20, 2011 9:07 PM
  • User-809368424 posted

    Hi,

    Thanks for your reply. I have to use the Master Page so I can't place the control in the normal page(actually it is already there). But I read somewhere that I can use Page_Unload event and prompt the user when in Edit mode. I will try that solution.

    Cheers.

    Monday, November 21, 2011 1:43 PM
  • User-16411453 posted

    Try Jquery, and register a event for leaving the page, when the form data changes, raise the dirty flag in jquery, and pop the message. Don't worry about the master page, it's a seperate container.

    Your concerns are on the client side, and not the server side. The server only cares about the controls it sent to the client, and certain data in the controls like dropdownlist data. You can't alter data via javascript in a dropdownlist, and post it back to the server, the server will reject it and assume it's tainted.

    After tons of thinking, if a user presses the back button without saving, then that was the intention. If the user presses next without saving, then just save the data without telling them, and then issue the postback without a message, or pop a modal message saying saving data via Jquery, and then send them to the next page.

    In my programs, I just save the data and send them on there way. I think most users just assume the data was saved.

    Saturday, November 26, 2011 2:15 AM
  • User-809368424 posted

    Thanks JKirkerx,

    I decided to go with a less functional but enough logic and wrote a function in code-behind that uses ClientScriptManager type and adds a "window.onbeforeunload" event. Here is my code:

            protected void JavaScriptConfirmLogic()
    {
    //add javascript
    string csX = "ConfirmExitClickScript";
    Type csType = this.GetType();
    ClientScriptManager csm = Page.ClientScript;
    if (!csm.IsClientScriptBlockRegistered(csType, csX))
    {
    StringBuilder csText = new StringBuilder();
    csText.Append("<script type='text/javascript'>");
    csText.Append("var needToConfirm = true;");
    csText.Append("window.onbeforeunload = confirmExit;");
    csText.Append("function confirmExit() { ");
    csText.Append("if (needToConfirm) ");
    csText.Append("return 'If you press OK now, any changes you have made for this item will be lost.'; ");
    csText.Append("} </script>");
    csm.RegisterClientScriptBlock(csType, csX, csText.ToString(), false);
    }
    }
    I am also using an OnCommand event and if the page is in edit or new mode, I am calling the above function and adding the 
    client-side script to the page.
            public void OnCommand(object sender, CommandEventArgs e)
    {
    try
    {
    switch (e.CommandName)
    {
    case PageCommandsEnum.Edit:
    {
    fvInvestigationDetails.ChangeMode(FormViewMode.Edit);
    JavaScriptConfirmLogic();
    PopulateControls(PageCommandsEnum.Edit);
    break;
    }
    case PageCommandsEnum.Cancel:
    {
    if (InvestigationNumberr > 0)
    {
    fvInvestigationDetails.ChangeMode(FormViewMode.ReadOnly);
    PopulateControls(PageCommandsEnum.Cancel);
    }
    else
    {
    Response.Redirect("Investigations.aspx");
    }
    break;
    }
    case PageCommandsEnum.New:
    {
    fvInvestigationDetails.ChangeMode(FormViewMode.Insert);
    JavaScriptConfirmLogic();
    PopulateControls(PageCommandsEnum.New);
    break;
    }
    ....
    Of course, the rest of the buttons in the page have a OnClientClick event call as:
    <asp:button id="btnEdit" runat="server" OnCommand="OnCommand" commandname="Edit" text="Edit Investigation" 
    OnClientClick="needToConfirm = false"/>
    Otherwise, the popup will appear afer every click event. "needToConfirm" is by default true, so if a user clicks on the navigation links, it will send a true to the javascript function.
    
    
    So that took care of warning the user when in edit mode and trying to leave... (Also in my first post, when I said navigation menu control, 
    I didn't actually mean the asp.net control, just a user control created for navigation purposes.)
    Thanks for taking the time though. I will have to get myself more familiarized with jQuery and find better solutions to my problems soon.
    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, November 28, 2011 7:23 PM