ASP:Labels not updating on button Click - asp.net

I know this is probably something so simple that I am just not able to see it. I have an aspx form that has a usercontrol in an updata panel. The user control is a people picker the searches on users from a corporate database.
What I want to see happen is:
The user clicks on a pick user button
The update panel with people picker becomes visible
They search for a user and then select the one they want.
When they make the selection and click Done, I get the user id of the user and look them up in our user table.
The user information should show up in a the form in label fields.
I can step through the code and see that I am getting the user information and that the label text is being set to the values but the page never updates the labels. It is a postback so I would think they would update.
<tr>
<td colspan="4">
<asp:UpdatePanel ID="CollapseDelegate" runat="server">
<ContentTemplate>
<asp:Panel ID="pDelegateHeader" runat="server">
<div style="padding: 10px 0 10px 20px; height:10px; text-align: left; background-color:#ffffff; color:#000000; border: 2px solid #ccc;" >
<asp:Label ID="ShowDelegate" runat="server" /><br />
</div>
</asp:Panel>
<asp:Panel ID="pDelegateBody" runat="server">
<PP:PeoplePicker ID="PP" runat="server" />
<asp:Button ID="btnOk" runat="server" Text="Done" CssClass="Buttons" onclick="btnOk_Click" />
</asp:Panel>
<asp:CollapsiblePanelExtender ID="CollapsiblePanelExtender3" runat="server" TargetControlID="pDelegateBody" CollapseControlID="pDelegateHeader" ExpandControlID="pDelegateHeader" Collapsed="true" TextLabelID="ShowDelegate" CollapsedText="Pick User..." ExpandedText="Close..." CollapsedSize="0"></asp:CollapsiblePanelExtender>
</ContentTemplate>
</asp:UpdatePanel>
</td>
</tr>
<tr>
<td><asp:Label ID="DelegateNameLabel" runat="server" Text="Name:" CssClass="indentedText" /></td>
<td><asp:Label ID="DelegateNameValueLabel" runat="server" CssClass="indentedText" Visible="true"></asp:Label></td>
<td><asp:Label ID="DelegateEmailLabel" runat="server" Text="Email:" CssClass="indentedText" /></td>
<td><asp:Label ID="DelegateEmailValueLabel" runat="server" CssClass="indentedText" Visible="true"></asp:Label></td>
</tr>
<tr>
<td><asp:Label ID="DelegatePhoneLabel" runat="server" Text="Phone:" CssClass="indentedText" /></td>
<td><asp:Label ID="DelegatePhoneValueLabel" runat="server" CssClass="indentedText" Visible="true"></asp:Label></td>
<td><asp:Label ID="DelegateVerifiedLabel" runat="server" Text="Last Verified Date:" CssClass="indentedText" /></td>
<td><asp:Label ID="DelegateVerifiedValueLabel" runat="server" CssClass="indentedText" /></td>
</tr>
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
string PassedDelegateID = string.Empty;
string Mode = string.Empty;
int delegateId = 0;
if (Request.QueryString["Id"] != null)
{
PassedDelegateID = Request.QueryString["Id"].ToString();
}
else
{
PassedDelegateID = "0";
}
if (Request.QueryString["mode"] != null)
{
Mode = Request.QueryString["mode"].ToString();
}
else
{
Mode = "add";
}
if (Mode == "add")
{
pnlUdpateDelegateText.Text = UIConstants.ADDDELEGATETEXT.ToString();
}
else
{
pnlUdpateDelegateText.Text = UIConstants.UPDATEDELEGATETEXT.ToString();
if (int.TryParse(PassedDelegateID, out delegateId))
{
loadDelegateData(delegateId);
}
}
}
}
protected void btnOk_Click(object sender, EventArgs e)
{
TextBox txtSearchValue = (TextBox)PP.FindControl("txtSearchResults");
string LanId = txtSearchValue.Text;
User user = BusinessUtility.GetUser(LanId);
DelegateNameValueLabel.Text = user.Name;
DelegateEmailValueLabel.Text = user.Email;
DelegatePhoneValueLabel.Text = user.Phone;
DelegateVerifiedValueLabel.Text = DateTime.Now.ToShortDateString();
}
Thanks,
Rhonda

Because the labels are outside the update panel, only the content inside the update panel is updated from an ajax post-back, that's the whole point of an update panel.
You will need to either move the labels inside the update panel's content area, or have another update panel for the labels and make it's update mode "always"

Your lables are outside of the UpdatePanel.
Under the hood, ASP.Net performes a full postback, but only the part that pertains to your UpdatePanel is transfered back down to the client. Some JavaScript then takes this bit of HTML and replaces the existing <div> element that is your UpdatePanel.
Since your labels are outside of that <div> they never get updates.

Related

Hide EmptyDataTemplate but leave header visible

I have an EmptyDataTemplate on my ASP.NET webform which allows users to add a record to the database. Depending on the permissions of the user, this EmptyDataTemplate needs to be visible and hidden if no data is found (I have this working!)
For example, my user has Read Access only. When they search a specific criteria, no results are displayed they cannot see the EmptyDataTemplate. However, if they search a criteria, and there is data, data is displayed WITHOUT the headers.
Can someone please help explain why this is happening and if there's a way around it?
The headers are HeaderText on TemplateFields.
I'm hoping it's a general trick.
Thank you in advance for your help!
Please note, it's the HeaderText in the TemplateFields I want to display- not the in the emptyDataTemplate as they'll head up the columns of data that match the search criteria.
edit: code added as requested
For hiding the EmptyDataTemplate:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
Control control = null;
control = GridView1.Controls[0].Controls[0];
if (userManagement.getMIFReadWriteAccess() == "Read")
{
control.Visible = false;
Export_All.Visible = true;
}
else if (userManagement.getMIFReadWriteAccess() == "Write")
{
control.Visible = true;
Export_All.Visible = true;
}
}
in markup for the header text (i've only shown one column but the markup is the same for all of them)
<asp:TemplateField HeaderText="ID">
<ItemTemplate>
<asp:Label ID="lbl_Index" runat="server" Text='<%#Eval("id") %>'></asp:Label>
<asp:Label ID="lbl_ID" runat="server" Text="" Visible="false"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
EmptyDataTemplate:
<EmptyDataTemplate>
<div id="emptyData" runat="server">
<tr>
<th></th>
<th>Serial Number</th>
<th>Comments</th>
<th>Review Date</th>
<th>Approved By</th>
</tr>
<tr>
<td>
<asp:Button runat="server" ID="btInsert" Text="In" OnClick="Add" CommandName="EmptyDataTemplate" Class="Button" OnClientClick="return confirm('You are about to confirm this action. Please confirm this action by clicking OK. If you do not wish to do this, please select Cancel.');" />
<br />
<asp:Button runat="server" ID="btInsertOut" Text="Out" OnClick="AddOut" CommandName="EmptyDataTemplate" Class="Button" OnClientClick="return confirm('You are about to confirm this action. Please confirm this action by clicking OK. If you do not wish to do this, please select Cancel.');" />
</td>
<td>
<asp:TextBox runat="server" ID="tb_Serial_Number" CssClass="text"></asp:TextBox>
</td>
<td>
<asp:TextBox ID="tb_comments" Width="100%" MaxLength="50" runat="server" placeholder="max 50 characters"/>
</td>
<td>
<asp:TextBox ID="tb_reviewDate" runat="server" DataFormatString="{0:dd/mm/yyyy}" Text='<%#Eval("review_by") %>'></asp:TextBox>
</td>
<td><asp:DropDownList ID="tb_approved_by" runat="server">
</asp:DropDownList> </td>
</tr>
</div>
</EmptyDataTemplate>
After trial and error, I found that programatically adding a header row in C# did the trick. Probably not the best way of doing it, but it worked.
Code is as follows:
#region show the emptyDataTemplate depending on user rights
Control control = null;
control = GridView1.Controls[0].Controls[0];
if (userManagement.getMIFReadWriteAccess() == "Read")
{
control.Visible = false;
GridViewRow HeaderRow = new GridViewRow(1, 0, DataControlRowType.Header, DataControlRowState.Insert);
TableCell HeaderCell2 = new TableCell();
HeaderCell2.Text = "Country";
HeaderCell2.ColumnSpan = 1;
HeaderRow.Cells.Add(HeaderCell2);
//Repeat the above for every column of data you have!
GridView1.Controls[0].Controls.AddAt(0, HeaderRow);

Load user control dynamically on Button Click

I have a label and a text box which i have added in the user control.
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="AddMultiLoc.ascx.cs" Inherits="CRM_Streamline_Forms.UserControls.AddMultiLoc" %>
<table>
<tr>
<td style="width:25%">
<asp:Label ID="lblLocName_UC_G0138" runat="server" Text="Location Name:" />
</td>
<td style="width:25%">
<asp:TextBox ID="txtLocName_UC_G0138" runat="server" Width="200px" />
</td>
<td style="width:25%">
<asp:Label ID="lblLocID_UC_G0138" runat="server" Text="Location ID:" />
</td>
<td style="width:25%">
<asp:TextBox ID="txtLocID_UC_G0138" runat="server" Width="200px" />
</td>
</tr>
I have a link button in one of my aspx pages which is when clicked should populate this user control.
<asp:LinkButton ID="lnkAddLoc_AGBI2_G0138" runat="server" Text="+ Add Another Location" onclick="lnkAddLoc_AGBI2_G0138_Click" />
Code behind, I have written this code for the button click:
protected void lnkAddLoc_AGBI2_G0138_Click(object sender, EventArgs e)
{
AddMultiLoc con = (AddMultiLoc)LoadControl("~/UserControls/AddMultiLoc.ascx");
pnlMultiInvoiceInfo1_AGBI2_G0138.Controls.Add(con);
Panel p = new Panel();
Control uc = (Control)Page.LoadControl("~/UserControls/AddMultiLoc.ascx");
p.Controls.Add(uc);
p.Width = 200;
p.Height = 100;
pnlMultiInvoiceInfo1_AGBI2_G0138.Controls.Add(p);
}
First time the user control is populated as am calling it in the aspx page, but second time when i click on the link button, it is not populating the user control for the second time. Am new to coding, please help :(
The problem I think is that you are losing your controls across postback as the controls are loaded in to the ViewState.
Here is a sample where you can load the controls in to the Session which is not really good practice but it will work for your purposes:
AddMultiLocPage.aspx
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:LinkButton ID="lnkAddLoc_AGBI2_G0138" runat="server" Text="+ Add Another Location" OnClick="lnkAddLoc_AGBI2_G0138_Click" />
</div>
<asp:PlaceHolder runat="server" ID="Placeholder1"></asp:PlaceHolder>
</form>
</body>
</html>
AddMultiLocPage.aspx.cs
public partial class AddMultiLocPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
LoadControlsFromSession();
}
private List<AddMultiLoc> ViewStateControls
{
get { return (List<AddMultiLoc>) Session["ViewStateControls"]; }
set { Session["ViewStateControls"] = (List<AddMultiLoc>)value; }
}
private void LoadControlsFromSession()
{
if (ViewStateControls != null)
{
Placeholder1.Controls.Clear();
foreach (var c in ViewStateControls)
{
Placeholder1.Controls.Add(c);
}
}
}
protected void lnkAddLoc_AGBI2_G0138_Click(object sender, EventArgs e)
{
var con = (AddMultiLoc)LoadControl("~/AddMultiLoc.ascx");
con.ID = Guid.NewGuid().ToString();
List<AddMultiLoc> tmpList = ViewStateControls;
if(tmpList == null) tmpList = new List<AddMultiLoc>();
tmpList.Add(con);
ViewStateControls = tmpList;
LoadControlsFromSession();
}
}
UserControl Markup
<table>
<tr>
<td style="width: 25%">
<asp:Label ID="lblLocName_UC_G0138" runat="server" Text="Location Name:" />
</td>
<td style="width: 25%">
<asp:TextBox ID="txtLocName_UC_G0138" runat="server" Width="200px" />
</td>
<td style="width: 25%">
<asp:Label ID="lblLocID_UC_G0138" runat="server" Text="Location ID:" />
</td>
<td style="width: 25%">
<asp:TextBox ID="txtLocID_UC_G0138" runat="server" Width="200px" />
</td>
</tr>
</table>
No need to store control in session, Solution to your problem is :
ASPX Code :
< asp:LinkButton ID="lnkAddLoc_AGBI2_G0138" runat="server" Text="+ Add Another Location" onclick="lnkAddLoc_AGBI2_G0138_Click" />
<asp:Panel ID="Panel1" runat="server">
Code Behind :
protected void lnkAddLoc_AGBI2_G0138_Click(object sender, EventArgs e)
{
Control uc = (Control)Page.LoadControl("~/AddMultiLoc.ascx");
Panel1.Controls.Add(uc);
}
Any time you click on link button lnkAddLoc_AGBI2_G0138 it add new instance of User Control to Panel1.

Confirmation box from server side in asp.net

I want to show the confirmation box in asp.net from server side:
I want to call it from server side because I have to take the customer message from server side. I am using the below code
string str = "Are you sure, you want to Approve this Record?";
ClientScript.RegisterStartupScript(typeof(Page), "Popup", "return confirm('" + str + "');",true);
// More code ....
Now it is showing the popup and irrespective of what I click, whether "ok" or "Cancel", my code is executing.
Please let me know how can I restrict code to be executed when user select "cancel" in the confirmation box.
Check it out:
CODE BEHIND:
string str = "Are you sure, you want to Approve this Record?";
this.ClientScript.RegisterStartupScript(typeof(Page), "Popup", "ConfirmApproval('" + str + "');", true);
ASPX:
function ConfirmApproval(objMsg)
{
if(confirm(objMsg))
{
alert("execute code.");
return true;
}
else
return false;
}
check following example code.
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:Button ID="btnOK" runat="server" Text="OK" onclick="btnOK_Click" />
<cc1:ModalPopupExtender ID="ModalPopupExtender1" runat="server" TargetControlID="lblID" PopupControlID="pnlConfirmation">
</cc1:ModalPopupExtender>
<asp:Panel ID="pnlConfirmation" runat="server" Style="background-color: #D4D0C8;
border: 2px solid black; width: 300px; height: 100px;">
<asp:Label ID="lblID" runat="server"></asp:Label>
<table cellpadding="2" cellspacing="2" width="100%">
<tr>
<td>
Your confirmation message here.
</td>
</tr>
<tr>
<td align="center">
<asp:Button ID="btnOK1" runat="server" Text="OK" onclick="btnOK1_Click" /> <asp:Button ID="btncancel"
runat="server" Text="Cancel" onclick="btncancel_Click" />
</td>
</tr>
</table>
</asp:Panel>
On server side.....
protected void btnOK_Click(object sender, EventArgs e)
{
//some code here.
//then show modal popup
ModalPopupExtender1.Show();
}
protected void btnOK1_Click(object sender, EventArgs e)
{
//If ok some code here to execute
ModalPopupExtender1.Hide();
}
protected void btncancel_Click(object sender, EventArgs e)
{
//hide modal popup
ModalPopupExtender1.Hide();
}
http://forums.asp.net/t/1499789.aspx?confirmation+popup+from+server+side

ASP.NET Accessing web control inside DataList control

Am not sure why I cannot access my Label control which was inside the Panel and the Panel is inside the DataList
<asp:DataList ID="DataList2" runat="server" DataSourceID="SqlDataSource1" Width="100%">
<ItemTemplate>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<!-- post details -->
<td style="width: 60%">
<asp:Panel ID="panelPostDetails" runat="server" CssClass="postpage_details">
<table border="0" cellpadding="5" cellspacing="0" width="100%">
<tr>
<td colspan="2"><div class="postpage_header"><%# Eval("Heading") %></div></td>
</tr>
<tr>
<td>
<img src="picserver/posts/<%# Eval("ImagePath") %>/1.jpg" alt="preview" style="width: 240px;" />
<div id="morepictures">
<asp:Label ID="lblMorePictures" runat="server" />
</div>
</td>
<td>
<div style="padding: 0px 5px 0px 5px;">
<div>
more stuff here
</div>
</div>
</td>
</tr>
</table>
</asp:Panel>
<asp:RoundedCornersExtender ID="RoundedCornersExtender1" runat="server"
Radius="6"
Corners="All"
TargetControlID="panelPostDetails"></asp:RoundedCornersExtender>
</td>
</tr>
</table>
</ItemTemplate>
</asp:DataList>
but when I tried using "lbl" in Page_Load, it seems it cannot find the control? can you please help me?
ItemDataBound and Page_Load event
---------------------------------
Panel p = DataList2.FindControl("panelPostDetails") as Panel;
Label l = p.FindControl("lblMorePictures") as Label;
l.Text = code;
that code returns Object reference not set to an instance of an object.
Thanks in advance
update:
ItemDataBound and Page_Load event
---------------------------------
Panel p = DataList2.FindControl("panelPostDetails") as Panel;
if(p==null)
{
System.Diagnostic.Debug.WriteLine("panel does not exist");
}
else
{
System.Diagnostic.Debug.WriteLine("panel does exist");
}
output:
panel does not exist
what on earth is going on!?!
Typically, you access controls like this at runtime by handling either the DataList's ItemCreated or ItemDataBound event. Here's a sample event handler:
protected void DataList2_ItemDataBound(object sender, DataListItemEventArgs e) {
if (e.Item.ItemType == ListItemType.Item) {
Label lbl = (Label)e.Item.FindControl("panelPostDetails").FindControl("lblMorePictures");
lbl.Text = code;
}
}
Wire up your the event handler like this:
<asp:DataList ID="DataList2" runat="server" OnItemDataBound="DataList2_ItemDataBound" ...
#Peter's code must work.
you can also try this:
protected void DataList2_ItemDataBound(object sender, DataListItemEventArgs e)
{
string st= (e.Item.FindControl("lblMorePictures") as Label).Text;
}
and put breakpoint to wath to st. In my case I get a text of lblMorePictures.
With my Form View I needed to add CType to the FindControl. I understand DataList doesn't necessarily need the Ctype however it is possible the Panel may need this prefix. In this case frmDelView is the name of my Form View. In my case the code line below is in my PreRender of my form. That was the only place at the time of creating the form it would return the data I needed to pass to a label on a next page of a Wizard Step page. Long story.
Note: my code is vb and not C#. It should be nearly or exactly the same.
CType(frmDelView.FindControl("txtcboDAcct"), TextBox).Text

ListView fields not getting posted

I know I've done something like this before, but I have no idea why it isn't working now. I have a ListView with some textboxes. I want to read the text out of those boxes when I click a button (linkbutton, whatever).
<asp:ListView runat="server" ID="lv_bar" EnableViewState="true">
<LayoutTemplate>
<table>
<tr>
<th>Foo</th>
</tr>
<tr runat="server" id="itemPlaceholder"></tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td><asp:LinkButton ID="lb_delete" CausesValidation="false" runat="server" Text="Del" /></td>
<td><asp:TextBox id="txt_foo" runat="server" /></td>
</tr>
</ItemTemplate>
</asp:ListView>
<asp:LinkButton ID="lb_add" CausesValidation="false" runat="server" Text="Add" />
And then here's the relevant code-behind stuff:
protected void Page_Load(object sender, EventArgs e)
{
lb_chapter_add.Click += lb_chapter_add_Click;
if (!IsPostBack)
{
lv_chapters.DataSource = new List<Foo>() { new Foo() { Name = "harbl"} };
lv_chapters.DataBind();
}
}
void lb_add_Click(object sender, EventArgs e)
{
foreach (ListViewDataItem item in lv_bar.Items)
{
var txt_foo = (TextBox)item.FindControl("txt_foo");
Response.Write("foo: " + txt_foo.Text);
}
Response.Write("<br />the end");
Response.End();
}
But what I see when I enter some text into txt_foo and click lb_add is just "the end". What am I doing wrong here?
The problem it that you are using a a non persistent object as DataSource.
Due to clicking the button, you generate a postback and lv_chapters does not contain any items. Set a breakpoint in the line where the foreach is and you will see that lv_chapters.Items in null, or that it's Count property returns 0.

Resources