Home > Mobile >  Retrieve Value from Textbox in ASP UpdatePanel on AsyncPostBackTrigger
Retrieve Value from Textbox in ASP UpdatePanel on AsyncPostBackTrigger

Time:06-01

I have an issue where I am embedding a user control inside a JQuery dialog. In this user control is a simple contact form which utilizes UpdatePanel to asyncronously hit the server, and submit the data without causing a full page postback. The issue I am facing is that when the server is reached, I cannot obtain the values from the textboxes in the update panel. Please see code snippets below, and let me know if you have any questions. Thank you.

ASCX Update Panel

<asp:UpdatePanel ID="contactPanelID" runat="server"> 
<ContentTemplate>
    <div>
        <h2>CONTACT US</h2>
        <p type="Name:"><asp:TextBox id="nameText" runat="server" css placeholder="Write your name here.."/></p>             
        <p type="Email:"><asp:TextBox id="emailText" runat="server" css placeholder="Let us know how to contact you back.."/></p>
        <p type="Message:"><asp:TextBox id="messageText" runat="server" css placeholder="What would you like to tell us.."/></p>
        <asp:LinkButton id="ContactSubmit" css runat="server" Text="Send Message" />
        <asp:label runat="server" id="responseLabel" css></asp:label>
    </div>
</ContentTemplate>
<Triggers>
    <asp:AsyncPostBackTrigger ControlID="ContactSubmit" />
</Triggers>   
</asp:UpdatePanel>  

VB User Control

Protected Sub lnk_ContactSubmit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ContactSubmit.Click
    responseLabel.Text = nameText.Text ' WHY IS THIS VALUE BLANK?
End Sub

Web.Master Embedded User Control

    <div id="dialog" title="Basic dialog" style="display: none" >
        <web:ContactUs runat="server" ></web:ContactUs>   
    </div>

Web.Master Javascript to open dialog

$("#dialog").dialog({
            dialogClass: 'contactDialog'
        });    

Edit for Albert As you can see from the images below, it appears that when I appendTo the form, it's almost disabling the modal option of the dialog which I have now added. Sorry if I am just missing something simple, but I am confused as to why the dialog is not opening.

var myDialog = $("#EditRecord");
        myDialog.dialog({
            title: "Edit Hotel Information",
            appendTo: "form1",
            modal: true,
            width: 860 
        });

Here is the form before selecting the button which opens the dialog

Here is the form after selecting the button which opens the dialog

EDIT 2 For Albert

Here is a sample of what my Web.Master looks like (simpflified)

<head id="Head1" runat="server">
  <script type="text/javascript" language="javascript">
    function OpenDialog(){
        $("#dialog").dialog({
            width: 500,
            height: 550,
            modal: true,
            dialogClass: "myTitleClass"
        });
  }
  </script>
  <body style=" margin-top:1px; text-align:center;" id="body_master" runat="server">
    <form id="form1" runat="server">
       <!-- All kinds of unrelated content -->
      <div id="dialog" style="display: none;" title="Contact Us">
        <web:ContactUs runat="server" ></webrg:ContactUs>  <!-- This is my user control --> 
      </div>
    </form>
  </body>
</head>

Updated user control ascx code

<asp:UpdatePanel ID="contactPanelID" runat="server"> 
<ContentTemplate>
    <div>
        <p type="Name:"><asp:TextBox id="nameText" runat="server" css placeholder="Write your name here.."/></p>             
        <p type="Email:"><asp:TextBox id="emailText" runat="server" css placeholder="Let us know how to contact you back.."/></p>
        <p type="Message:"><asp:TextBox id="messageText" runat="server" css placeholder="What would you like to tell us.."/></p>
        <asp:LinkButton id="ContactSubmit" css runat="server" Text="Send Message" />
        <asp:label runat="server" id="responseLabel" css></asp:label>
    </div>
</ContentTemplate>
<Triggers>
    <asp:AsyncPostBackTrigger ControlID="ContactSubmit" />
</Triggers>   

</asp:UpdatePanel>

CodePudding user response:

In the VAST majority of cases, a post-back from a update panel Will cause the dialog to collapse. However, I have found if you put a div OUT side of the update panel, and have jquery.ui pop that div, and INSIDE the div is THEN your update panel, then the jquery.ui dialog can survive and have post-backs. Do keep in mind that while a update panel only posts back the part in the update panel? It is actually what we call a "partial" post-back, and even the web page Load even does fire, and does trigger each time you post-back from inside that update panel. Move div you pop to surround the up.

And if the button inside of the UP has a event, then you don't need a trigger setting. You also don't show the #Dialog div, but as noted, you want to have this div surround the up, not nest the UP inside of the pop div.

Next up:

YES you often find that when you have that post-back in the UP, the values are not seen, or correctly put back into the page DOM.

So, add this to your jquery.UI dialog:

    <script>
        function PopEdit() {
            var myDialog = $("#EditRecord");
            myDialog.dialog({
                title: "Edit Hotel Information",
                modal: true,
                width: 860,
                appendTo: "form"
            });
        }
    </script>

Note VERY careful in above. The appendTo: "form". You in general don't need this for most dialogs you pop, but if that dialog is to edit data, and you are to see the changes in code behind, then you need that appendTo.

So, keep in mind, that while the UP does a partial post-back, you do get, and see and have a standard page life cycle post-back occurring here.

And viewstate is also posted back in the UP when you click a button. So, it not like you not going to get ZERO post-back. You get a post-back, and page load, and a full page cycle when using a UP panel.

Often, since a post-back DOES collapse the UP, then that can be part of your design. If I pop a up, and have a save button (that is a post-back), then that's great, since the post-back will collapse (close) the panel for me (and that's what I want).

So, often I use the fact of a post-back in the UP to close the panel, since any post back as a general rule will collapse the UP. However, if you move the "div" outside and surround the UP, then the panel can survive post-backs, and not collapse.

So, take this simple grid - with a pop jquery.UI dailog to edit a row.

We have this simple grid:

    <div style="width:40%">
        <asp:GridView ID="GHotels" runat="server" AutoGenerateColumns="False" 
            DataKeyNames="ID" CssClass="table">
            <Columns>
                <asp:BoundField DataField="FirstName" HeaderText="FirstName"  />
                <asp:BoundField DataField="LastName" HeaderText="LastName"    />
                <asp:BoundField DataField="HotelName" HeaderText="HotelName"  />
                <asp:BoundField DataField="Description" HeaderText="Description"  />
                <asp:TemplateField HeaderText="Edit">
                    <ItemTemplate>
                        <asp:Button ID="cmdEdit" runat="server" Text="Edit" CssClass="btn" OnClick="cmdEdit_Click" />
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>
    </div>

And code to load the grid:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    If Not IsPostBack Then
        LoadGrid
    End If

End Sub

Sub LoadGrid()

    Dim cmdSQL As New SqlCommand("SELECT * FROM tblHotelsA ORDER BY HotelName")
    GHotels.DataSource = MyrstP(cmdSQL)
    GHotels.DataBind()

End Sub

And now we have this:

enter image description here

Also, WHY are you using a link button???? (I guess ok, but GOOD reason should exist for making that choice over a regular button).

So, in above, we have view. that just a plane jane button.

And the code when we click is this:

Protected Sub cmdEdit_Click(sender As Object, e As EventArgs)

    Dim btn As Button = sender
    Dim gRow As GridViewRow = btn.NamingContainer
    Dim pkID = GHotels.DataKeys(gRow.RowIndex).Item("ID")

    Dim cmdSQL As New SqlCommand("SELECT * from tblHotelsA where ID = @ID")
    cmdSQL.Parameters.Add("@ID", SqlDbType.Int).Value = pkID
    Dim rstData As DataTable = MyrstP(cmdSQL)

    Call fLoader(Me.EditRecord, rstData.Rows(0)) ' load up hidden div with data
    ViewState("rstData") = rstData
    ' lets call the js routine to pop our hidden edit div
    ClientScript.RegisterStartupScript(Page.GetType(), "PopEditKey", "PopEdit()", True)

End Sub

That simple button click event for the gv gets the PK, loads up the hidden div (that jquery.ui will pop).

Client side, I have that simple jquery.ui dialog to pop our edit div.

that code is this:

    <script>
        function PopEdit() {
            var myDialog = $("#EditRecord");
            myDialog.dialog({
                title: "Edit Hotel Information",
                modal: true,
                width: 860,
                appendTo: "form"
            });
        }
    </script>

So, now, when I click a row, I get this:

enter image description here

Now, in a above, I have a cancel button. (i used html button, since I wanted icons for the button. But, with id and runat=server, it REALLY works the same as a standard asp.net button.

For the 3 buttons in above, I have this:

        <button id="cmdSave" runat="server"  onserverclick="cmdSave_ServerClick" >
            <span aria-hidden="true" > Save</span> 
        </button>

        <button id="cmdCancel" runat="server"  style="margin-left:15px">
            <span aria-hidden="true" > Back/Cancel</span>
        </button>

        <button id="cmdDelete" runat="server"  style="margin-left:15px">
            <span aria-hidden="true" > Delete</span>
        </button>

Note how the cancel button has ZERO code. I just let it post-back, no code behind event, but as I pointed out, any post-back will collopse the dialog, and I am happy and fine with that.

The save button? Sure, it has a code behind stub, and has this:

Protected Sub cmdSave_ServerClick(sender As Object, e As EventArgs)

    Dim rstData As DataTable = ViewState("rstData")
    Call fWriterW(EditRecord, rstData.Rows(0))
    Call SaveTable(rstData, "tblHotelsA")
    LoadGrid()   ' re-display grid with changes

End Sub

Once again, no code to close the dialog required.

And delete button - that could in theory pop up another jquery.ui dialog to ask yes, or no to the user.

However, since I do allow editing of that pop div, then again, note the appendTo: setting - this pushes back the dialog into the "dom" so your code behind will see the changes.

And, I suppose for good measure, I can post the pop div markup (but, not all that imporant). But, it was this:

    <div id="EditRecord" runat="server" style="float:left;display: none">
        <style>
            .iForm label {display:inline-block;width:90px}
            .iForm input {border-radius:8px;border-width:1px;margin-bottom:10px}                
            .iForm textarea {border-radius:8px;border-width:1px;margin-bottom:10px}     
            .iForm input[type=checkbox] {margin-right:8px}
        </style>

        <div style="float:left" >
                <label>HotelName</label><asp:TextBox ID="txtHotel" runat="server" f="HOtelName" width="280"></asp:TextBox> <br />
                <label>First Name</label><asp:TextBox ID="tFN" runat="server" f="FirstName" Width="140"></asp:TextBox> <br />
                <label>Last Name</label><asp:TextBox ID="tLN" runat="server" f="LastName" Width="140"></asp:TextBox> <br />
                <label>City</label><asp:TextBox ID="tCity" runat="server" f="City" Width="140"></asp:TextBox> <br />
                <label>Province</label><asp:TextBox ID="tProvince" runat="server" f="Province" Width="75"></asp:TextBox> <br />
        </div>
        <div style="float:left;margin-left:20px" >
            <label>Description</label> <br />
            <asp:TextBox ID="txtNotes" runat="server" Width="400" TextMode="MultiLine" 
                Height="150px" f="Description" ></asp:TextBox> <br />
            <asp:CheckBox ID="chkActive" f="Active" Text=" Active" runat="server" TextAlign="Right" />
            <asp:CheckBox ID="chkBalcony" f="Balcony" Text=" Has Balcony" runat="server" TextAlign="Right" />
        </div>
        <div style="clear:both"></div>
        <button id="cmdSave" runat="server"  onserverclick="cmdSave_ServerClick" >
            <span aria-hidden="true" > Save</span> 
        </button>

        <button id="cmdCancel" runat="server"  style="margin-left:15px">
            <span aria-hidden="true" > Back/Cancel</span>
        </button>

        <button id="cmdDelete" runat="server"  style="margin-left:15px">
            <span aria-hidden="true" > Delete</span>
        </button>
   </div>

So, that's the div we pop. Now, I COULD put the content in a UP, and thus no post-backs in the panel would not cause it to close. (but then that would mean the cancel button, save button, and even the delete button code would THEN be responsible for close of the dialog.

Edit: div with runat=server

It not clear if you using code behind for the div. You can remove the "id" and runat=server for the div. However, I oftne need (and want) code behind to have use of that div.

So, to get jquery to work, then add this to the div:

 <div id="EditRecord" runat="server" 
    style="float:left;display: none" clientidmode="Static"  >

But, then again, if your code behind does not need that div as a control in code behind, then no need to have the runat=server.

But, if the div you picking up in jquery.UI does have a runat=server tag, the you can use clientIDmode="static", or you can change the jQuery to this:

var MyDialog = $('#<%= EditRecord.ClientID %>').dialog

So, I am not recommending or suggesting to add a runat=server for the div, but only if you need it (in my example, I did need it).

Edit2: Master page example:

So, say I have this:

            <asp:ScriptReference Name="Focus.js" Assembly="System.Web" Path="~/Scripts/WebForms/Focus.js" />
            <asp:ScriptReference Name="WebFormsBundle" />
            <%--Site Scripts--%>
        </Scripts>
    </asp:ScriptManager>

            <script src="Scripts/jquery-ui.js"></script>
            <link href="Scripts/jquery-ui-1.12.1.css" rel="stylesheet" />

(I cust most out - so I added jquery.ui and the .css for jQuery.ui

then furhter down, the menu (again most cut out).

We have this:

                    <li><a runat="server" href="~/About">About</a></li>
                    <li><a runat="server" href="~/Contact">Contact</a></li>
                    <li><a onclick="HotelEdit();">Edit Hotel</a>
                    </li>
                </ul>
            </div>
        </div>
    </div>

    <div id="HotelDialog" style="display:none">
        <uc1:HotelEd1 runat="server" id="HotelEd1" />
    </div>

    <script>
        function HotelEdit() {
                $("#HotelDialog").dialog({
                    width: 740,
                    height: 340,
                    modal: true,
                    title: "Edit Hotel",
                    appendTo: "form"
                });
            } 
    </script>
    

Note how I did add back the append to.

so, when we run, we get this:

enter image description here

so, my user control does pop. And note how I re-introduced the appendTo: "form". Since the site master is in fact the "form" page then appendTo may well be required for buttons inside of the popup to work.

  • Related