Where to catch user control properties being wrapped to be loaded inside a modal? - asp.net

I have a user control which has a public property (e.g. AlarmID) and this control is wrapped inside a div and when user presses a button on the page, in code-behind the public property of that user control becomes set. then a ScriptManager.RegisterStartupScript is called to show a modal popup which is a div wrapping that control.
My problem is that although in code-behind I first set the public property of that user control, but when the modal popup shows that user control, I cannot access that property
I used Control_PreRender, and Control_Load events but none of them were able to show the correct value of that property in a label inside that control.
For more clarification, here is my code in the code-behind of the control:
protected void Control_Load(object sender, EventArgs e)
{
lblAlarmCode.Text = alarmID.ToString();
}
public int AlarmID
{
get
{
return this.alarmID;
}
set
{
this.alarmID = value;
}
}
What is the exact life-cycle event in which I can catch the property to be shown correctly by that label?
Thanks

Make sure that the modal is attached to the <form> element on the page otherwise it will not be a part of the page lifecycle at all.
Just as a sample, not saying this is your code, but I had to use something similar in order to have <asp:Textbox> and <asp:Button> controls to be brought back and forth across the Request
ASPX code:
<asp:Panel runat="server" ID="pnlWorkItem">
<fieldset>
<legend></legend>
<label>Job Code</label>
<asp:DropDownList runat="server" ID="ddlJobCode" Width="50%" />
<label>Hours</label>
<asp:TextBox runat="server" ID="txtHours" />
</fieldset>
<fieldset>
<legend></legend>
<p><asp:Button runat="server" ID="btnAddWorkItem" OnClick="btnAddWorkItem_Click" text="Add Work Item" /></p>
</fieldset>
</asp:Panel>
Javascript:
$(function () {
var workItemPanel = $("#<%= pnlWorkItem.ClientID %>");
workItemPanel.hide();
$("#add-work").on("click", function () {
$(workItemPanel).dialog({
width: 450,
height: 300
}).parent().appendTo($("form:first"));
});
});
It will append your element to the form element generated by ASP.net and should have your properties set and carried across.

One solution is to set the label in setter. However there might be other solutions but this ways is just working.

Related

Retain Style Properties on postback

I have a div and 4 drop-down controls.
Default div is hidden using Style="display:none".
First drop-down don't have autopostback event.
Div's display property is changed on few values of 1st drop-down. Once its is visible. User can change values in drop-down field 2/3/4 which is having auto postback true.
As user changes value in any of the 2-5 drop-down controls, postback triggers and set the display property of that Div to Style="display:none".
How can I retain display property of div.
This is on .aspx page
The styles are not part of the data that are contained in the PostBack. In order to include them, you can create a hidden field on the page that you also set whenever your client code changes the visibility of the div.
<asp:HiddenField ID="hidden" runat="server" />
When the PostBack arrives at the server, you evaluate the Value property of the hidden field and set the style on the div so that it matches the state that was stored in the hidden field. In order to be able to change the style on the div in .NET code, you need to make sure that runat="server" is specified:
<div ID="myDiv" runat="server">
<!-- ... -->
</div>
Sample
The following sample shows how you can use a hidden field to transfer the visibility to the server and restore it on the client. In ASPX, there is the div, the hidden field to store the visiblity and a script that sets the visiblity of the div and also the value of the hidden field:
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<div id="myDiv" runat="server" style="display:none;">
Div is visible
</div>
<asp:HiddenField ID="myHidden" runat="server" />
<input type="button" value="Toggle visiblity" onclick="javascript:toggleDiv()" />
<asp:Button ID="btn" runat="server" Text="Postback" />
<script type="text/javascript">
function toggleDiv()
{
$(myDivId).toggle();
$(myHiddenId).val($(myDivId).css('display'));
}
</script>
</asp:Content>
Important to note is that the div and the hidden fields get special ASP.NET client ids that do not necessarily match the ids of the tags in the ASPX-file. Therefore, I register a startup script that defines variables with the ids (myDivId and myHiddenId):
protected void Page_Load(object sender, EventArgs e)
{
ClientScript.RegisterStartupScript(GetType(), "DivId",
"var myDivId = '#" + myDiv.ClientID + "';" + Environment.NewLine +
"var myHiddenId = '#" + myHidden.ClientID + "';",
true);
}
When a postback occurs, the value of the hidden field is transferred to the server and can be used. I've defined a PreRender event handler, that restores the visibility of the div:
protected void Page_PreRender(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(myHidden.Value))
myDiv.Style[HtmlTextWriterStyle.Display] = "none";
else
myDiv.Style[HtmlTextWriterStyle.Display] = myHidden.Value;
}

Checkboxlist in hidden DIV

I have a CheckboxList within a DIV. The DIV appears as a modal popup when a button is clicked. Then the user checks off any number of items in the checkboxlist and clicks OK. This hides the div.
once the user clicks the save button on the main form, I need to pass parameters to a stored procedure based on which items in the checkboxlist were clicked, but they are always set to unchecked when I run the save code. I'd love some thoughts on how to do this properly.
Thanks
JQuery:
$(document).ready(function () {
$('#<%=txtLANG.ClientID %>').click(function () {
$("#overlay-back").dialog({
resizable: false,
modal: true,
width: 500,
height: 400,
buttons: {
OK: function () {
GetLanguages();
$(this).dialog("close");
},
Cancel: function () {
$(this).dialog("close");
}
}
});
});
});
Save Method in CodeBehind
private void Save()
{
List<string> lstItemsChecked = new List<string>();
for (int i = 0; i < chkTopLanguages.Items.Count; i++)
{
if(chkTopLanguages.Items[i].Selected)
lstItemsChecked.Add(chkTopLanguages.Items[i].Value);
}
//stored proc call
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
Save();
}
ASPX Code for DIV popup and CheckBoxList
<div id="overlay-back" style="display:none;">
<td rowspan="3" valign="top">
<asp:CheckBoxList ID="chkTopLanguages" TextAlign="Right" runat="server" />
<br />
<asp:TextBox runat="server" ID="txtOtherLanguages" Text="Other Languages..."></asp:TextBox>
</td>
</div>
maybe this happens because the when you close the popup, the controls on the popup are not accessible. I don't know the exact cause but you can create an array variable in javascript. Whenever you check or uncheck a checkbox; with the help of javascript, you modify that variable to what all variables are set or not.
I used modal popup way long back and there was an issue like that only.
This approach might not be optimal but will work for sure.
Try setting the AutoPostBack to false:
<asp:CheckBoxList ID="chkTopLanguages" TextAlign="Right" runat="server" AutoPostBack="false" />
For the CheckBoxList control.

How to correct ASP.NET webform jquery reference being lost on partial postback

Within an asp.net webform I have some jquery that controls the positioning of elements on the page. Since this is a webform and some of these controls talk to the server to get jquery to work I have the controls nested in an AJAX UpdatePanel to prevent postbacks from resetting my controls.
aspx:
<asp:UpdatePanel ID="searchupdatePanel" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<div id="searchholder" >
<div id="searchoptions">
Close Advanced Search
<br />
Filters
</div>
<div id="search" class="searchcontainer">
<asp:TextBox ID="tbsearchterm" CssClass="watermark" runat="server" OnTextChanged="tbsearchterm_TextChanged" />
<div class="buttons">
<asp:LinkButton runat="server" Text="Search" class="button search-big" ID="btnSearch" OnClick="btnSearch_Click" />
<asp:LinkButton runat="server" Text="Fx" class="button left big" ID="btnOperators" />
<asp:LinkButton runat="server" Text="Save" class="button right big" ID="btnSave" />
</div>
</div>
<div id="divAdvSearch">
</div>
</div>
</ContentTemplate>
</asp:UpdatePanel>
<div id="divBody">
<asp:UpdatePanel runat="server" UpdateMode="Always">
<ContentTemplate>
<div id="divSearchResults" visible="true" runat="server">
<uc:SearchResultsControl ID="SearchResultsControl" runat="server"></uc:SearchResultsControl>
</div>
</ContentTemplate>
</asp:UpdatePanel>
When the search button is clicked I modify the css class for the search control to reposition my search div layer which is the update panel "searchudpatepanel"
searchcontrol.js
$(function () {
$("#searchupdatePanel").addClass("searchmenubar");
$("#btnClose").hide();
});
$(function () {
$("#btnSearch").click(function () {
$(".searchmenubar").animate({ "margin-top": "5px" }, "fast");
$("#btnAdvanceSearch").show();
$("#btnFilters").show();
$("#btnClose").hide();
$("#divAdvSearch").hide();
alert("search");
});
});
The button click also calls serverside code to retrieve and populate the results within a user control called SearchResultsControl ( second update panel)
Where I am confused is when the searchResult Control is loaded with the results all references to the jquery classes are lost. As a result every div element that is hidden or button click that is called ceases to work. Working through this in debug I can see when the user control is called the Page_Load for the default.aspx file is invoked as second time. I assume this partial load is dropping reference to the js files I just don't know how to correct this.
I tried a test within the page load using IsStartupScriptRegistered to see if the js was getting called
string csname = "PopupScript";
Type cstype = this.GetType();
ClientScriptManager cs = Page.ClientScript;
if (!cs.IsStartupScriptRegistered(cstype, csname))
{
StringBuilder cstext1 = new StringBuilder();
cstext1.Append("<script type=text/javascript> alert('Hello World!') </");
cstext1.Append("script>");
cs.RegisterStartupScript(cstype, csname, cstext1.ToString());
}
Here on the initialization of the page I would see the pop up occur however when the UserControl was loaded I would pass through this a second time in the page load but the alert never displayed( I assume this is due to a partial load so the browser thinks the script is already registered).
The only other thing I can think of is I am overriding the rendering of the UserControl being loaded as it loads a custom result set.
protected override void Render(HtmlTextWriter htw)
{
if (IsPostBack)
{
QueryResponse qr = iu.GetSearchResults(SearchTerm);
int num = qr.TotalMatchesReturned;
SearchData sd = new SearchData();
htw.Write("<table style='width: 100%; height:100%'><tr ><td style='width: 50%'>");
htw.Write("<div id='divResultDetail' runat=server >");
htw.Write("<script type='text/javascript' src='../js/paging.js'></script><div id='pageNavPosition'></div><table id='results'>");
for (int i = 0; i < num; i++)
{
...edited for brevity.
Any suggestions or guidance as to why I am losing reference to the jquery functions? I am not using master pages so I haven't used the ASP ScriptManager.
This all worked fine prior to using UpdatePanels. I define "fine" as: the postback was reloading/registering the js files each time, so they were being reset (which was okay). However, now with some other changes needed I need to look at leveraging UpdatePanels.
Thanks for any suggestions or ideas.
You can use the live or delegate jQuery methods to get your handlers to be bound to any elements added to the page.
Alternatively, if you need some setup to always happen after every partial postback in addition to original page load, you can put it in a pageLoad method instead of document.ready. ASP.NET calls this on page load, and after every partial postback.
function pageLoad()
{
// Setup code here
}
Check this article for more:
http://encosia.com/document-ready-and-pageload-are-not-the-same/
You need to use delegate for the button click. It will assure that all elements present and future will be bound to the event handler.
http://api.jquery.com/delegate/
$("body").delegate("#btnSearch", "click", function () {
$(".searchmenubar").animate({ "margin-top": "5px" }, "fast");
$("#btnAdvanceSearch").show();
$("#btnFilters").show();
$("#btnClose").hide();
$("#divAdvSearch").hide();
alert("search");
});
You need to rebind the elements when the update panel finish updating. Like this,
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(function () {
$('#add').click(function () {
});
$('#addPrevious').click(function () {
});
});
Hope this helps.

ASP.NET linkbutton visible property issue

I'm using a public variable called IsAdmin in the code behind of an aspx page.
public partial class _news : System.Web.UI.Page
{
public bool IsAdmin = false;
protected void Page_Load(object sender, EventArgs e)
{
if (User.Identity.Name.Contains("admin"))
{
IsAdmin = true;
}
else
{
IsAdmin = false;
}
}
And i use the property Visible='<%#IsAdmin%>' to assign to panels which i want to show if the user is an admin in the aspx design of the page. Strangely it works for the linkbuttons i've put on the repeater.
<asp:Panel ID="Panel1" runat="server" Visible='<%#IsAdmin%>'>
<asp:LinkButton ID="LinkButton2" runat="server" PostBackUrl='<%# "news_edit.aspx? Action=edit&id=" + Convert.ToString( Eval("news_id")) %>Edit</asp:LinkButton>
<asp:LinkButton ID="LinkButton3" runat="server" PostBackUrl='<%# "news.aspx?Action=delete&id=" + Convert.ToString( Eval("news_id")) %>'>Delete</asp:LinkButton>
</asp:Panel>
and it works fine, however outside the repeater i've put another linkbutton without a panel
<asp:LinkButton ID="LinkButton4" runat="server" PostBackUrl="~/news_edit.aspx?action=new" Visible='<%#IsAdmin%>'>Add New Item</asp:LinkButton>
but the visible property doesn't work on it! I tried putting it inside a panel too and setting it's visible property but that too didn't work.
So i have following doubts
1)what is the issue?
2)what is the technical name when we use references like '<%#IsAdmin%>' in the design page
3)Does page load happen before page is rendered of after page is rendered?
Thanks
<%# %> is the syntax used for accessing databound fields. Since you are likely databinding the Repeater control at some point, these expressions will be evaluated.
Since you are likely not calling databind on the Panel and the Linkbuttons outside of the Repeater, these expressions will not be processed. You can probably change them to something like
<%= IsAdmin.ToString() %>
and get the result you want.
Check this great blog entry for more information on the differences.
Also, Page Load happens before the page is rendered. Rendering the page is the last thing that happens in the ASP.Net page lifecycle.

OnClick vs OnClientClick for an asp:CheckBox?

Does anyone know why a client-side javascript handler for asp:CheckBox needs to be an OnClick="" attribute rather than an OnClientClick="" attribute, as for asp:Button?
For example, this works:
<asp:CheckBox runat="server" OnClick="alert(this.checked);" />
and this doesn't (no error):
<asp:CheckBox runat="server" OnClientClick="alert(this.checked);" />
but this works:
<asp:Button runat="server" OnClientClick="alert('Hi');" />
and this doesn't (compile time error):
<asp:Button runat="server" OnClick="alert('hi');" />
(I know what Button.OnClick is for; I'm wondering why CheckBox doesn't work the same way...)
That is very weird. I checked the CheckBox documentation page which reads
<asp:CheckBox id="CheckBox1"
AutoPostBack="True|False"
Text="Label"
TextAlign="Right|Left"
Checked="True|False"
OnCheckedChanged="OnCheckedChangedMethod"
runat="server"/>
As you can see, there is no OnClick or OnClientClick attributes defined.
Keeping this in mind, I think this is what is happening.
When you do this,
<asp:CheckBox runat="server" OnClick="alert(this.checked);" />
ASP.NET doesn't modify the OnClick attribute and renders it as is on the browser. It would be rendered as:
<input type="checkbox" OnClick="alert(this.checked);" />
Obviously, a browser can understand 'OnClick' and puts an alert.
And in this scenario
<asp:CheckBox runat="server" OnClientClick="alert(this.checked);" />
Again, ASP.NET won't change the OnClientClick attribute and will render it as
<input type="checkbox" OnClientClick="alert(this.checked);" />
As browser won't understand OnClientClick nothing will happen. It also won't raise any error as it is just another attribute.
You can confirm above by looking at the rendered HTML.
And yes, this is not intuitive at all.
Because they are two different kinds of controls...
You see, your web browser doesn't know about server side programming. it only knows about it's own DOM and the event models that it uses... And for click events of objects rendered to it. You should examine the final markup that is actually sent to the browser from ASP.Net to see the differences your self.
<asp:CheckBox runat="server" OnClick="alert(this.checked);" />
renders to
<input type="check" OnClick="alert(this.checked);" />
and
<asp:CheckBox runat="server" OnClientClick="alert(this.checked);" />
renders to
<input type="check" OnClientClick="alert(this.checked);" />
Now, as near as i can recall, there are no browsers anywhere that support the "OnClientClick" event in their DOM...
When in doubt, always view the source of the output as it is sent to the browser... there's a whole world of debug information that you can see.
You are right this is inconsistent. What is happening is that CheckBox doesn't HAVE an server-side OnClick event, so your markup gets rendered to the browser. http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.checkbox_events.aspx
Whereas Button does have a OnClick - so ASP.NET expects a reference to an event in your OnClick markup.
For those of you who got here looking for the server-side OnClick handler it is OnCheckedChanged
I was cleaning up warnings and messages and see that VS does warn about it:
Validation (ASP.Net): Attribute 'OnClick' is not a valid attribute of element 'CheckBox'. Use the html input control to specify a client side handler and then you won't get the extra span tag and the two elements.
Asp.net CheckBox is not support method OnClientClick.
If you want to add some javascript event to asp:CheckBox you have to add related attributes on "Pre_Render" or on "Page_Load" events in server code:
C#:
private void Page_Load(object sender, EventArgs e)
{
SomeCheckBoxId.Attributes["onclick"] = "MyJavaScriptMethod(this);";
}
Note: Ensure you don't set AutoEventWireup="false" in page header.
VB:
Private Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
SomeCheckBoxId.Attributes("onclick") = "MyJavaScriptMethod(this);"
End Sub
You can do the tag like this:
<asp:CheckBox runat="server" ID="ckRouteNow" Text="Send Now" OnClick="checkchanged(this)" />
The .checked property in the called JavaScript will be correct...the current state of the checkbox:
function checkchanged(obj) {
alert(obj.checked)
}
You can assign function to all checkboxes then ask for confirmation inside of it. If they choose yes, checkbox is allowed to be changed if no it remains unchanged.
In my case I am also using ASP .Net checkbox inside a repeater (or grid) with Autopostback="True" attribute, so on server side I need to compare the value submitted vs what's currently in db in order to know what confirmation value they chose and update db only if it was "yes".
$(document).ready(function () {
$('input[type=checkbox]').click(function(){
var areYouSure = confirm('Are you sure you want make this change?');
if (areYouSure) {
$(this).prop('checked', this.checked);
} else {
$(this).prop('checked', !this.checked);
}
});
});
<asp:CheckBox ID="chk" AutoPostBack="true" onCheckedChanged="chk_SelectedIndexChanged" runat="server" Checked='<%#Eval("FinancialAid") %>' />
protected void chk_SelectedIndexChanged(Object sender, EventArgs e)
{
using (myDataContext db = new myDataDataContext())
{
CheckBox chk = (CheckBox)sender;
RepeaterItem row = (RepeaterItem) chk.NamingContainer;
var studentID = ((Label) row.FindControl("lblID")).Text;
var z = (from b in db.StudentApplicants
where b.StudentID == studentID
select b).FirstOrDefault();
if(chk != null && chk.Checked != z.FinancialAid){
z.FinancialAid = chk.Checked;
z.ModifiedDate = DateTime.Now;
db.SubmitChanges();
BindGrid();
}
gvData.DataBind();
}
}
One solution is with JQuery:
$(document).ready(
function () {
$('#mycheckboxId').click(function () {
// here the action or function to call
});
}
);

Resources