JQuery UI modal dialog is not closing after asyncpostback in update panel - asp.net

I am using modal dialog of jQuery UI with my ASP.Net application.
The page contains UpdatePanel component for asynchronous postbacks.
aspx code
<script>
function ShowDialog() {
$('#modal').dialog({
autoOpen: false,
modal: true,
dialogClass: 'dialog',
resizable: false,
width: 500,
height: 400
});
$('#modal).dialog('open');
}
function CloseDialog(){
$('#modal).dialog('close');
}
</script>
<asp:UpdatePanel ID="updatepanel" runat="server" RenderMode="Inline">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnSave" EventName="Click" />
</Triggers>
<ContentTemplate>
<asp:Repeater ID="repEducationHistory" runat="server">
<HeaderTemplate>
<table>
<tr>
<th>Field 1</th>
<th>Field 2</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><asp:Literal ID="litField1" runat="server">
</asp:Literal>
</td>
<td><asp:Literal ID="litField1" runat="server">
</asp:Literal>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
<asp:LinkButton ID="btnAdd" runat="server" Text="Add new"
OnClick="BtnAdd_Click" />
<div id="modal" title="Add item" style="display:none;">
<div>
<label>Educational institution:</label>
<asp:TextBox ID="tbField1" runat="server"/>
<br />
<label>Country:</label>
<asp:DropDownList ID="tbField2" runat="server"
DataValueField="Id" DataTextField="Name" />
<br />
<asp:LinkButton ID="btnSave" runat="server"
Text="Save" OnClick="BtnSave_Click"></asp:LinkButton>
</div>
</div>
<asp:LinkButton ID="btnSave" runat="server" CausesValidation="true"
ValidationGroup="vgMpt" Text="Save" OnClick="BtnSaveUsrEdu_Click">
</asp:LinkButton>
cs code
protected void BtnAdd_Click(object sender, EventArgs e)
{
tbField1.Text=string.Empty;
ddlField2.SelectedIndex=0;
ScriptManager.RegisterStartupScript(updatepanel, updatepanel.GetType(),
Guid.NewGuid().ToString(), "ShowDialog();", true);
}
protected void BtnSaveUsrEdu_Click(object sender, EventArgs e)
{
ScriptManager.RegisterStartupScript(updatepanel, updatepanel.GetType(),
Guid.NewGuid().ToString(), "CloseDialog();", true);
}
When button Add is clicked the codebehind prepares controls on dialog (putting there values or removing them, it depends on the fact if dialog is used to add item or to edit it) and then sends script to create and show dialog. When Save button is clicked the code behind (after omitted here routine of checking the data entry, storing it and rebinding the repeater) sends script to close the dialog. The problem is that the dialog is not closing. The JavaScript function CloseDialog is called but $('#modal).dialog('close'); does not do what is required to.
Any ideas how to solve this problem ?

The code below works well for me:
<asp:UpdatePanel ID="updatepanel" runat="server" UpdateMode="Conditional" RenderMode="Inline">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnSave" />
</Triggers>
<ContentTemplate>
<asp:LinkButton ID="btnAdd" runat="server" Text="Add new" OnClick="BtnAdd_Click" />
</ContentTemplate>
</asp:UpdatePanel>
<div id="modal" title="Add item" style="display: none;">
<asp:UpdatePanel runat="server" ID="DialogUpdatePanel">
<ContentTemplate>
<div>
<label>
Educational institution:
<asp:TextBox ID="tbField1" runat="server" />
</label>
<br />
<label>
Country:
<asp:DropDownList ID="tbField2" runat="server" DataValueField="Id" DataTextField="Name" />
</label>
<br />
<asp:LinkButton ID="btnSave" runat="server" Text="Save" OnClick="btnSave_Click"></asp:LinkButton>
</div>
</ContentTemplate>
</asp:UpdatePanel>
</div>
Code-behind:
protected void BtnAdd_Click(object sender, EventArgs e)
{
tbField1.Text = string.Empty;
ScriptManager.RegisterStartupScript(updatepanel, updatepanel.GetType(),
Guid.NewGuid().ToString(), "ShowDialog();", true);
}
protected void btnSave_Click(object sender, EventArgs e)
{
ScriptManager.RegisterStartupScript(DialogUpdatePanel, DialogUpdatePanel.GetType(),
Guid.NewGuid().ToString(), "CloseDialog();", true);
}

Solved it myself.
The script to show/close dialog was like that:
function ShowDialog() {
$('#modal').dialog({
autoOpen: false,
modal: true,
dialogClass: 'dialog',
resizable: false,
width: 500,
height: 400
});
$('#modal).dialog('open');
}
function CloseDialog(){
$('#modal).dialog('close');
}
What I did is: add to close function the definition of dialog:
function CloseDialog(){
$('#modal').dialog({
autoOpen: false,
modal: true,
dialogClass: 'dialog',
resizable: false,
width: 500,
height: 400
});
$('#modal).dialog('close');
}
And now dialog is closing without problem.
BUT!!!
The contribution of Yuriy Rozhovetskiy was extremely valuable: adding UpdatePanel to the content of dialog's DIV solved a lot of other issues of updating the dialog from codebehind. I believe, the best solution for using jQuery UI dialog inside UpdatePanel is to add one more UpdatePanel inside dialog. Thanks, Yuriy !!!

Related

How to get text in popup control extender?

i am using a popup control extender.but i am getting only index of selected value from radiobutton list.I want to get the text
Below is my source code
<div class="FloatRight">
<asp:TextBox ID="txtTeam" runat="server" Width="150px" autocomplete="off"></asp:TextBox>
<br />
<asp:Panel ID="panel" runat="server">
<div style="border: 1px outset white; width: 100px">
<asp:UpdatePanel runat="server" ID="up1">
<ContentTemplate>
<asp:RadioButtonList ID="rbteam" runat="server" AutoPostBack="true" OnSelectedIndexChanged="rbteam_SelectedIndexChanged">
</asp:RadioButtonList>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</asp:Panel>
<cc1:PopupControlExtender ID="txtTeam_PopupControlExtender" runat="server" Enabled="True"
and this is server side
protected void rbteam_SelectedIndexChanged(object sender, EventArgs e) {
if (!string.IsNullOrEmpty(rbteam.SelectedValue))
{
txtTeam_PopupControlExtender.Commit(rbteam.SelectedValue);
}
else
{
txtTeam_PopupControlExtender.Cancel();
}
rbteam.ClearSelection();
}
txtTeam_PopupControlExtender.Commit(rbteam.SelectedItem.Text);

Specify when UpdateProgress Control are displayed

Does anyone have a resource or provide a code sample on when not to display an UpdatePrgress Control when a certain button is clicked.
in your Markup:
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<fieldset>
<legend>UpdatePanel</legend>
<asp:Label ID="Label1" runat="server" Text="Initial page rendered."></asp:Label><br />
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
</fieldset>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdateProgress ID="UpdateProgress1" runat="server">
<ProgressTemplate>
Processing...
</ProgressTemplate>
</asp:UpdateProgress>
in your code behind:
protected void Button1_Click(object sender, EventArgs e)
{
// Introducing delay for demonstration.
System.Threading.Thread.Sleep(3000);
Label1.Text = "Page refreshed at " +
DateTime.Now.ToString();
}
this should work, try it...
source: Introduction to the UpdateProgress Control

UpdatePanel reset textbox background color

I have an UpdatePanel within it a textbox with a background color of yellow and a trigger for text-changed for the textbox and everything works fine except that the background color reverts to white when I write some text in the text box and then focus somewhere else.
What is causing this? Thanks.
Using asp.net 4.0
Here is the asp.net markup:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<span>
<asp:TextBox ID="sticky" runat="server" AutoPostBack="true"
Text='<%# Bind("sticky") %>' TextMode="MultiLine"
OnTextChanged="cSticky" />
</span>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="sticky" EventName="TextChanged" />
</Triggers>
</asp:UpdatePanel>
Here is the css:
#StickyDiv textarea
{
height:170px;
width:185px;
resize:none;
margin-top:1px;
border:none;
font-family:Comic Sans MS;
font-size:1.2em;
padding:3px;
line-height:1.1em;
}
And here is the jQuery:
$(function () {
$("#StickyDiv textarea:even").css("background-color","#ffff95");
$("#StickyDiv textarea:odd").css("background-color", "#fe8ab9");
});
Your problem is that when you do a update in the ajax panel your jquery is not called. If the text is changed you update the box to yellow and not call the javascript because it is rendered outside of your panel. To fix this you can register the script in you codebehide like:
ScriptManager.RegisterClientScriptBlock(Page,typeof(string),"JavaScriptCall",script.ToString(), false);
I did in the folowing example
in ASPX file
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:TextBox ID="TextBox1" runat="server" BackColor="Yellow" AutoPostBack="true" OnTextChanged="textChanged"></asp:TextBox>
<br />
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
In Codebehind File
protected void textChanged(object sender, EventArgs e)
{
TextBox1.BackColor = System.Drawing.Color.Yellow;
Label1.Text = TextBox1.Text;
}

update panel not working

i am having two list box which perform add remove item functionality which are controlled by four buttons and o each button click there happen to be post back but i don't want it to be flicker for which i am using update panel like this but it still made post back wats wrong with this explain me this
<asp:UpdatePanel ID="button" runat="server" UpdateMode="Always">
<ContentTemplate>
<asp:Button ID="ButtonAdd" runat="server" Text=">" OnClick="ButtonAdd_Click" Width="50px"/><br />
<asp:Button ID="ButtonRemove" runat="server" Text="<" OnClick="ButtonRemove_Click" Width="50px"/><br />
<asp:Button ID="ButtonAddAll" runat="server" Text =">>>" OnClick="ButtonAddAll_Click" Width="50px"/><br />
<asp:Button ID="ButtonRemoveAll" runat="server" Text ="<<<" OnClick="ButtonRemoveAll_Click" Width="50px"/>
</ContentTemplate>
</asp:UpdatePanel>
I wrote a quick example that does work. You do not need your buttons in the UpdatePanel. You only need the ListBox since they are the only controls being refresh. Setup the Trigger for the UpdatePanel will cause the refreshes to occur without the 'flicker'.
aspx code:
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<div>
<asp:Button ID="ButtonAdd" runat="server" Text=">" OnClick="ButtonAdd_Click" Width="50px"/><br />
<asp:Button ID="ButtonRemove" runat="server" Text="<" OnClick="ButtonRemove_Click" Width="50px"/><br />
<asp:Button ID="ButtonAddAll" runat="server" Text =">>>" OnClick="ButtonAddAll_Click" Width="50px"/><br />
<asp:Button ID="ButtonRemoveAll" runat="server" Text ="<<<" OnClick="ButtonRemoveAll_Click" Width="50px"/>
<asp:UpdatePanel ID="button" runat="server" UpdateMode="Always">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ButtonAdd" EventName="Click" />
<asp:AsyncPostBackTrigger ControlID="ButtonRemove" EventName="Click" />
<asp:AsyncPostBackTrigger ControlID="ButtonAddAll" EventName="Click" />
<asp:AsyncPostBackTrigger ControlID="ButtonRemoveAll" EventName="Click" />
</Triggers>
<ContentTemplate>
<asp:ListBox ID="ListBox1" runat="server"></asp:ListBox>
<asp:ListBox ID="ListBox2" runat="server"></asp:ListBox>
</ContentTemplate>
</asp:UpdatePanel>
</div>
cs (codebehind) code:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ListBox1.Items.Add(new ListItem("Test1", "1"));
ListBox1.Items.Add(new ListItem("Test2", "2"));
ListBox1.Items.Add(new ListItem("Test3", "3"));
ListBox1.Items.Add(new ListItem("Test4", "4"));
ListBox1.Items.Add(new ListItem("Test5", "5"));
}
}
protected void ButtonRemove_Click(object sender, EventArgs e)
{
if (ListBox2.SelectedItem != null)
{
ListBox1.Items.Add(ListBox2.SelectedItem);
ListBox2.Items.RemoveAt(ListBox2.SelectedIndex);
ListBox2.ClearSelection();
ListBox1.ClearSelection();
}
}
protected void ButtonAdd_Click(object sender, EventArgs e)
{
if (ListBox1.SelectedItem != null)
{
ListBox2.Items.Add(ListBox1.SelectedItem);
ListBox1.Items.RemoveAt(ListBox1.SelectedIndex);
ListBox1.ClearSelection();
ListBox2.ClearSelection();
}
}
I have tested this and it does work. I only implemented 2 of the Buttons to present a complete example.
Add the asp:ListBox to the ContentTemplate of your asp:UpdatePanel, or add a new asp:UpdatePanel and add it to its ContentTemplate. The control won't be updated using an asynchronous postback if it's not placed within an asp:UpdatePanel.
With the following code snippets the newly added listBox will be updated with new content using an asynchronous postback:
Page.aspx:
<asp:UpdatePanel ID="button" runat="server" UpdateMode="Always">
<ContentTemplate>
<asp:Button ID="ButtonAdd" runat="server" Text=">" OnClick="ButtonAdd_Click" Width="50px" /><br />
<asp:Button ID="ButtonRemove" runat="server" Text="<" OnClick="ButtonRemove_Click"
Width="50px" />
<br />
<asp:Button ID="ButtonAddAll" runat="server" Text=">>>" OnClick="ButtonAddAll_Click"
Width="50px" />
<br />
<asp:Button ID="ButtonRemoveAll" runat="server" Text="<<<" OnClick="ButtonRemoveAll_Click"
Width="50px" />
<asp:ListBox runat="server" ID="listBox"></asp:ListBox>
</ContentTemplate>
</asp:UpdatePanel>
Sample event handler in the code-behind file, Page.aspx.cs:
protected void ButtonAddAll_Click(object sender, EventArgs e)
{
listBox.DataSource = new List<string>() { "Test" };
listBox.DataBind();
}
<asp:UpdatePanel ID="button" runat="server" UpdateMode="Always">
<ContentTemplate>
<asp:Button ID="ButtonAdd" runat="server" Text=">" OnClick="ButtonAdd_Click" Width="50px" /><br />
<asp:Button ID="ButtonRemove" runat="server" Text="<" OnClick="ButtonRemove_Click"
Width="50px" />
<br />
<asp:Button ID="ButtonAddAll" runat="server" Text=">>>" OnClick="ButtonAddAll_Click"
Width="50px" />
<br />
<asp:Button ID="ButtonRemoveAll" runat="server" Text="<<<" OnClick="ButtonRemoveAll_Click"
Width="50px" />
<asp:ListBox runat="server" ID="listBox"></asp:ListBox>
</ContentTemplate>
</asp:UpdatePanel>

Losing Button.Click events after first partial postback in UpdatePanel

I have a Page that has a single instance of a UserControl that itself has a single UpdatePanel. Inside the UpdatePanel are several Button controls. The Click event for these controls are wired up in the code-behind, in the Init event of the UserControl.
I get the Click event for the first button I push, every time, no problem. After that, I only get Click events for one button (SearchButton) - the rest are ignored. I have included the code for the control below - for sake of brevity, I have excluded the click event handler methods, but they are all of the standard "void Button_Click(object sender, EventArgs e)" variety. Any ideas?
<asp:UpdatePanel ID="PickerUpdatePanel" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Panel ID="Container" runat="server">
<div>
<asp:TextBox ID="PickerResults" runat="server" style="margin-right: 3px;" SkinID="Plain" />
<asp:Image
ID="LaunchPopup" runat="server" ImageUrl="~/images/icons/user_manage.png"
ImageAlign="Top" BorderColor="#294254" BorderStyle="Dotted" BorderWidth="1px"
Height="20px" Width="20px" style="cursor: pointer;" />
</div>
<asp:Panel ID="PickerPanel" runat="server" DefaultButton="OKButton" CssClass="popupDialog" style="height: 227px; width: 400px; padding: 5px; display: none;">
<asp:Panel runat="server" id="ContactPickerSearchParams" style="margin-bottom: 3px;" DefaultButton="SearchButton">
Search: <asp:TextBox ID="SearchTerms" runat="server" style="margin-right: 3px;" Width="266px" SkinID="Plain" />
<asp:Button ID="SearchButton" runat="server" Text="Go" Width="60px" SkinID="Plain" />
</asp:Panel>
<asp:ListBox ID="SearchResults" runat="server" Height="150px" Width="100%" SelectionMode="Multiple" style="margin-bottom: 3px;" />
<asp:Button ID="AddButton" runat="server" Text="Add >>" style="margin-right: 3px;" Width="60px" SkinID="Plain" />
<asp:TextBox ID="ChosenPeople" runat="server" Width="325px" SkinID="Plain" />
<div style="float: left;">
<asp:Button ID="AddNewContact" runat="server" SkinID="Plain" Width="150px" Text="New Contact" />
</div>
<div style="text-align: right;">
<asp:Button ID="OKButton" runat="server" Text="Ok" SkinID="Plain" Width="100px" />
</div>
<input id="SelectedContacts" runat="server" visible="false" />
</asp:Panel>
<ajax:PopupControlExtender ID="PickerPopEx" runat="server" PopupControlID="PickerPanel" TargetControlID="LaunchPopup" Position="Bottom" />
</asp:Panel>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="AddButton" EventName="Click" />
<asp:AsyncPostBackTrigger ControlID="SearchButton" EventName="Click" />
<asp:AsyncPostBackTrigger ControlID="AddNewContact" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
public partial class ContactPicker : System.Web.UI.UserControl
{
protected void Page_Init(object sender, EventArgs e)
{
SearchButton.Click += new EventHandler(SearchButton_Click);
AddButton.Click += new EventHandler(AddButton_Click);
OKButton.Click += new EventHandler(OKButton_Click);
}
// Other code left out
}
It seems that adding UseSubmitBehavior="false" to the button definitions has solved my problem. Still don't know why that first button click worked at all.
The most likely reason for this would be the client IDs that .Net generates for its controls changing. These are dynamically assigned and could change between postbacks / partial postbacks.
If controls are being added to the panel dynamically, the ID of your button could be different between postbacks causing .Net to be unable to tie the click event to the correct event handler in your code.
In my case, i had a LinkButton within a dgPatients_ItemDataBound event handler that used the PostBackUrl property.
The moment i changed the LinkButton to a HyperLink, the problem went away.

Resources