简体   繁体   中英

Prevent bootstrap modal closing on postback in ASP.NET

I have a bootstrap modal I want to show in order to perform a search and select funcionality in a ASP.NET Web form. The problem is when the user clicks on "Search" button, the modal closes. I want the modal keeps open to show search results on GridView below and closes when the user selects any GridView item.

I've tried other solutions mentioned in other threads but nothing seems to work. I'm using a WebForm with a Master page, I don't know if it can be causin me the issue.

This is my modal code:

<div class="modal fade" id="modSearchByAccount" role="dialog">
<div class="modal-dialog">
    <div class="modal-content">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal">&times;</button>
            <h4 class="modal-title">Search by Account</h4>
        </div>
        <div class="modal-body">
            <div class="row">
                <div class="col-md-8">
                    <asp:TextBox ID="txtSearchText" runat="server" CssClass="form-control" placeholder="Account name"></asp:TextBox>
                </div>
                <div class="col-md-4">
                     <asp:Button ID="btnSearchAccount" runat="server" OnClick="btnSearchAccount_Click" Text="Buscar" CssClass="btn btn-default" />
                </div>    
            </div>
            <div class="row">
                <div class="col-md-12">
                     <asp:Panel ID="pnlSearchResults" runat="server" ScrollBars="Vertical" Height="200px" Width="100%">
                        <asp:GridView ID="gvSearchResults" runat="server" AutoGenerateColumns="False" DataKeyNames="ACCOUNT_ID" OnSelectedIndexChanged="gvSearchResults_SelectedIndexChanged" CssClass="table table-striped table-hover">
                            <Columns>
                                <asp:BoundField DataField="ACCOUNT_ID" HeaderText="ID" />
                                <asp:BoundField DataField="ACCOUNT_NAME" HeaderText="Name" />
                                <asp:CommandField ShowSelectButton ="true" />
                            </Columns>
                        </asp:GridView>
                    </asp:Panel>
                </div>
            </div>
        </div>
        <div class="modal-footer">
            <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        </div>
    </div> 
 </div>

Any ideas? Can I use an UpdatePanel somewhere here?

Thanks in advance!

Probably too late now, but yes it can be done. The key is to have an outer UpdatePanel and an inner UpdatePanel. The outer panel should be set to an UpdateMode of conditional and ChildrenAsTriggers = true.

In my case I moved the inner body into a User Control, but your code example should work as follows:

<asp:UpdatePanel runat="server" ID="updatePanelTop" UpdateMode="Conditional" ChildrenAsTriggers="True">
<ContentTemplate>
    <div class="modal fade" id="modSearchByAccount" role="dialog">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h4 class="modal-title">Search by Account</h4>
            </div>
            <div class="modal-body">
                <asp:UpdatePanel runat="server">
                <ContentTemplate>
                    <div class="row">
                        <div class="col-md-8">
                            <asp:TextBox ID="txtSearchText" runat="server" CssClass="form-control" placeholder="Account name"></asp:TextBox>
                        </div>
                        <div class="col-md-4">
                             <asp:Button ID="btnSearchAccount" runat="server" OnClick="btnSearchAccount_Click" Text="Buscar" CssClass="btn btn-default" />
                        </div>    
                    </div>
                    <div class="row">
                        <div class="col-md-12">
                             <asp:Panel ID="pnlSearchResults" runat="server" ScrollBars="Vertical" Height="200px" Width="100%">
                                <asp:GridView ID="gvSearchResults" runat="server" AutoGenerateColumns="False" DataKeyNames="ACCOUNT_ID" OnSelectedIndexChanged="gvSearchResults_SelectedIndexChanged" CssClass="table table-striped table-hover">
                                    <Columns>
                                        <asp:BoundField DataField="ACCOUNT_ID" HeaderText="ID" />
                                        <asp:BoundField DataField="ACCOUNT_NAME" HeaderText="Name" />
                                        <asp:CommandField ShowSelectButton ="true" />
                                    </Columns>
                                </asp:GridView>
                            </asp:Panel>
                        </div>
                    </div>
                </ContentTemplate>
                </asp:UpdatePanel>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
            </div>
        </div> 
     </div>
</ContentTemplate>
</asp:UpdatePanel>     

If you are using the UpdatePanel with Select2List or Some other bootstrap like FileUpload Controls, they will not properly render on Auto Post Back

To avoid this don't use the Update Panel just add the following code in code behind. This code will keep your Bootstrap Popup open after AutoPostBack Event.

 protected void OnSelectedIndexChanged(object sender, EventArgs e) { ClientScript.RegisterStartupScript(this.GetType(), "Popup", "$('#MyPopup').modal('show')", true); }

I know this is old, but I came upon this thread with the same problem. The other solutions did not work for me, but I came up with my own that seems to work, although it might be considered a "hack". Basically, in the code-behind I set up the various attributes of HTML elements the same way that Bootstrap does it. I figured out what to set them to by comparing the Page Source when the dialog was "closed" vs. when "open".

Here's the top of the markup for my modal:

                        <div id="modalSizeChange" runat="server" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="true">
                        <div class="modal-header">
                            <asp:Button ID="btnCloseMatItem" class="close" runat="server" Text='&times;' OnClick="btnCloseMatItem_Click" OnClientClick="$('#modalSizeChange').modal('hide')" />
                            <h2 id="ResizeDlgHdr" runat="server">Change Size of Return Piece</h2>
                        </div>

And here are two subroutines (this is vb.net) for keeping the modal open or closing it:

    Private Sub HideResizeDlg()
    modalSizeChange.Style.Remove("display")
    modalSizeChange.Attributes("class") = "modal hide fade"
    modalSizeChange.Attributes("aria-hidden") = "true"
    litDlgBackdrop.Text = ""
    litDlgBackdrop.Visible = False

    'Following is to remove any Div with "modal-backdrop fade in" class created by JQuery (instead of the one created by code-behind)
    Dim script As String = "$('.modal-backdrop').remove();"
    ScriptManager.RegisterStartupScript(Me, Me.GetType(), "#modalBackdropRemove", script, True)
End Sub

Private Sub ShowResizeDlg()
    'Set the attributes of the dialog so it stays visible on the post back - this matches the state after the JQuery .modal('show') is called
    modalSizeChange.Style.Add("display", "block")
    modalSizeChange.Attributes("class") = "modal hide fade in"
    modalSizeChange.Attributes("aria-hidden") = "false"
    litDlgBackdrop.Text = "<div class=""modal-backdrop fade in""></div>"
    litDlgBackdrop.Visible = True

End Sub

So whenever during postback I want to keep the dialog displayed, I call ShowResizeDlg(). The one problem with this approach is that after reloading the page, the close/cancel buttons no longer work using basic client-side .modal('hide') call, for the same reasons that the dialog didn't stay open. So to get around that I made those post-back buttons as well, and they call the HideResizeDlg() subroutine which does the equivalent of 'hide'.

A note about litDlgBackdrop, which is a literal at the bottom just before the </body> tag. I found out that the version of bootstrap used in my app achieves the darkened background effect by adding a <div> at this location with the class="modal-backdrop fade in". So to achieve the same affect I populate this literal with the same thing.

In the HideResizeDlg(), I register a startup script that looks for and deletes any elements with class "modal-backdrop" - to get rid of the one created by bootstrap.

One other caution, the app I'm working on is using an old Bootstrap version from 2013, so the attributes I'm setting may not work with newer versions, but you could take a similar approach by studying the Page Source like I did to find out what to change.

There's probably a much better way, I just found this works for my purposes.

Put your Modal outside the updatepanel, if the modal inside the updatepanel the modal will close automatically when postback or asp button clicked.

<div class="modal fade" id="mdlGuncelle" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-keyboard="false" data-backdrop="static">
<asp:UpdatePanel ID="upModalGuncelle" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="true">
    <ContentTemplate>
       
            <div class="modal-dialog">

Modal popup özelliğini Update Panel dışına alın. PostBack olacak kısımları Update panel içerisine koyması işinizi görecektir.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM