Calendar, Dynamic LinkButton CommandEventHandler Help - asp.net

I am attempting to create a calendar which is just a simple UI to display dates and dates to users of our system. I have overridden the Calendar's "DayRender" event to gain access to each cell and then insert a couple of dynamic controls to display specific data. The display of the controls works great. However, I recently wanted to add a LinkButton with command arguments and capture the event to run some other logic and change the UI. I have gotten the LinkButton to display properly and it renders as a simple "" tag with the ID that is assigned. However clicking on the link does nothing and it appears that the normal "href='...javascript action...'" portion of the link is not being generated. I have a feeling this is all due to the fact that I am adding the control at the Day Render stage in the page life cycle. But if that was the case the control probably would not show up at all.
Any ideas as to why the click action is not being added yet the text and everything else are? Code is below.
Thanks for your time
protected void Calendar1_DayRender(object sender, DayRenderEventArgs e)
{
if (Schedule != null)
{
var dayReq = from day in Schedule
where day.RequiredDate == e.Day.Date
where day.RequiredQty != 0
select day;
if (dayReq.FirstOrDefault() != null)
{
//Open the Date
e.Cell.Controls.Add(new LiteralControl("<br /><div class=\"auth-sched-req\">Req Qty: <strong>" + String.Format("{0:#,#.###}", dayReq.FirstOrDefault().RequiredQty) + "</strong><br />Prom Date: "));
//Create a link button for the promise date
LinkButton lb = new LinkButton();
lb.ID = dayReq.FirstOrDefault().ItemId.ToString();
lb.Text = dayReq.FirstOrDefault().RequiredDate.ToShortDateString();
lb.CommandName = "ShowPromise";
lb.CommandArgument = dayReq.FirstOrDefault().ItemId.ToString();
lb.Command +=new CommandEventHandler(lb_Command);
e.Cell.Controls.Add(lb);
//Close the Date
e.Cell.Controls.Add(new LiteralControl("</div>"));
}
}
}
protected void lb_Command(Object sender, CommandEventArgs e)
{
//Do some magic here
Response.Write(e.CommandArgument.ToString());
}

try this
<script type="text/javascript">
function calendarClick(day) {
document.getElementById('<%= hfValue.ClientID %>').value = day;
document.getElementById('<%= ghostButton.ClientID %>').click();
}
</script>
<asp:Button ID="ghostButton" runat="server" Style="display: none" OnClick="ghostButton_Click" />
<asp:HiddenField ID="hfValue" runat="server" />
code behind:
protected void Calendar1_DayRender(object sender, DayRenderEventArgs e)
{
// ...
e.Cell.Attributes["onclick"] = string.Format("calendarClick({0})", dayReq.FirstOrDefault().ItemId.ToString());
// ...
}
protected void ghostButton_Click(object sender, EventArgs e1)
{
string value = hfValue.Value;
// ...
}

Check if AutoEventWireup is set to true i.e.
AutoEventWireup="true"

I ended up going another route with this request. None of the proposed solutions worked and I never could get it to work. One option we looked at was creating a custom table to build the control. We ended up changing where the information was changed and just used the calendar control as the display mechanism.
Sorry for the delay!

Related

What to type in ASP.NET when you want to make sure that a button is clicked

I don't seem to know how to correctly write bn_pwd.Click and to make it work. Please help me.
protected void bn_pwd_Click(object sender, EventArgs e)
{
if (bn_pwd.Click == true)
{
lb_showpwd.Visible = true;
tb_Spwd.Visible = true;
lb_showcfmpwd.Visible = true;
tb_Scfmpwd.Visible = true;
}
else
{
lb_showpwd.Visible = false;
tb_Spwd.Visible = false;
lb_showcfmpwd.Visible = false;
tb_Scfmpwd.Visible = false;
}
}
When the bn_pwd_Click function is fired, it means that the button was clicked. What you want to do with bn_pwd.Click == true ?
Maybe you should use a variable to store the state of the controls you want to apply.
What you have will work (minus some unnecessary code), assuming you have a button with OnClick="bn_pwd_Click":
<asp:Button ID="bn_pwd" OnClick="bn_pwd_Click" Text="Submit" runat="server" />
Alternatively, you can declare the Click event in the code behind (and not have it in the code-front as above). Personally, I like having it on the code-front side.
bn_pwd.Click += bn_pwd_Click;
Now, when the button is clicked, the page will post-back (your Page_Load will execute again), and then bn_pwd_Click will execute. So you only need this:
protected void bn_pwd_Click(object sender, EventArgs e)
{
lb_showpwd.Visible = true;
tb_Spwd.Visible = true;
lb_showcfmpwd.Visible = true;
tb_Scfmpwd.Visible = true;
}
Because that function only ever runs when the button is clicked. I assume the visibilities of all of those controls should be set to false to begin with. Either in code front or in Page_Load.
From your question, it seems like you need to review the ASP.NET Page Life Cycle and could also benefit from some tutorials, like at ASP.net.

SlideShowExtender - How to get the current picture?

I am using asp control SlideShowExtender in a aspx page.
I am using the previous and next buttons.
I want to add a delete button. Is there a way to find out which picture the user is currently on? I'm having a hard time finding how to get the name of the image SlideShowExtender is currently showing.
Thanks for the help =)
$find("<%= slideshowextend1.ClientID %>")._currentValue.ImagePath;
$find("<%= slideshowextend1.ClientID %>")._currentValue.Name;
Crazy workaround
Add MouseDown event to image (OnClick would not work)
asp:Image runat="server" ID="MainImage" Width="1000" ImageUrl="" onmousedown="javascript:return MainClick();"
JavaScript
function MainClick() {
i = document.getElementById('<%=MainImage.ClientID %>');
c = document.getElementById('<%=MainImageClick.ClientID %>');
c.value = i.getAttribute("src");
__doPostBack(null, null);
return true;
}
</script>
C# - there is probably some way of setting the sender but I am working on a over budget project
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
string mainImageClick = MainImageClick.Value;
if (!string.IsNullOrEmpty(mainImageClick))
DoMainImageClick(mainImageClick);
MainImageClick.Value = string.Empty;
}
}

textbox.text always returning empty string instead of user's entered text

I am very surprised to see last night my code was working fine and the next day suddenly my textbox.text always have empty string..
My code is:
Name of Event* :
<br />
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<br />
Code behind:
protected void Page_Load(object sender, EventArgs e) {
}
protected void create_Click(object sender, EventArgs e) {
if (!object.Equals(Session["UserLoginId"], null)) {
int mid = 0;
int cid = 0;
bool valid = true;
if (this.TextBox1.Text == "") {
error.Text = "<p style='color:red'>Marked Fields are compulsory!!</p>";
}
else {
.... // database insert ....
}
I am always ending up with an error.text value.
Why?
Had a similar problem with text boxes getting cleared on adding a new row. It was the issue of the page reloading when the add button was clicked.
Fixed the issue by adding:
Sub Page_Load
If Not IsPostBack Then
BindGrid()
End If
End Sub
Per Microsoft's documentation http://msdn.microsoft.com/en-us/library/aa478966.aspx.
Kinda mentioned but you should make sure your checking your that Post_Back event is not clearing your textbox. It would by default.
Try something like this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (this.TextBox1.Text == "")
{
error.Text = "<p style='color:red'>Marked Fields are compulsory!!</p>";
}
else
{
//.....
}
}
}
I had a similar problem. I had a textarea feeding data to a database on postback. I also designed the page to populate the textarea from the same database field. The reason it failed was because I forgot to put my reload logic inside an if(!IsPostPack) {} block. When a post back occurs the page load event gets fired again and my reload logic blanked the textarea before I could record the initial value.
If the page make a post back, then all the data , the user entered ,will be erased,as the controls are stateless, so u should keep your data entry through EnableViewState = true.
I am having this issue, but i'm using Telerik Ajax request with target in javascript. I have a RadTextBox and a RadButton. I call the same code from both of them but if i call it from the textBox and request a postback, the textbox is empty in the page load. So i call RadAjaxManager.ajaxRequestWithTarget('someUserControlClientID', 'myTextBoxText');
So in the page_load, i can grab the text, in case it's not sent to the server with the arguments sent, Request.Form("__EVENTARGUMENT") will hold my textBox value.
by the way, RadAjaxManager.ajaxRequestWithTarget is like __doPostBack('targetID', 'arguments');. Hope this helps someone. I don't have time to investigate why i lose the text with this request, so this is the workaround i did.

Set focus to textbox in ASP.NET Login control on page load

I am trying to set the focus to the user name TextBox which is inside an ASP.NET Login control.
I have tried to do this a couple of ways but none seem to be working. The page is loading but not going to the control.
Here is the code I've tried.
SetFocus(this.loginForm.FindControl("UserName"));
And
TextBox tbox = (TextBox)this.loginForm.FindControl("UserName");
if (tbox != null)
{
tbox.Focus();
} // if
I'm using Page.Form.DefaultFocus and it works:
// inside page_load, LoginUser is the Login control
Page.Form.DefaultFocus = LoginUser.FindControl("Username").ClientID;
Are you using a ScriptManager on the Page? If so, try the following:
public void SetInputFocus()
{
TextBox tbox = this.loginForm.FindControl("UserName") as TextBox;
if (tbox != null)
{
ScriptManager.GetCurrent(this.Page).SetFocus(tbox);
}
}
Update: Never used a multiview before, but try this:
protected void MultiView1_ActiveViewChanged(object sender, EventArgs e)
{
SetInputFocus();
}
protected void Page_Load(object sender, EventArgs e)
{
SetFocus(LoginCntl.FindControl("UserName"));
}
You may try to do the following:
-Register two scripts (one to create a function to focus on your texbox when page is displayed, second to register id of the textbox)
this.Page.ClientScript.RegisterStartupScript(this.GetType(), "on_load",
"<script>function window_onload() \n { \n if (typeof(idLoginTextBox) == \"undefined\" || idLoginTextBox == null) \n return; \n idLoginTextBox.focus();\n } \n window.onload = window_onload; </script>");
this.Page.ClientScript.RegisterStartupScript(this.GetType(), "Focus", String.Format("<script>var idLoginTextBox=document.getElementById(\"{0}\").focus();</script>", this.loginForm.ClientID));
As the result you should get the following in your code:
<script>
function window_onload()
{
if (typeof(idLoginTextBox) == "undefined" || idLoginTextBox == null)
return;
idLoginTextBox.focus();
}
window.onload = window_onload;
</script>
<script>
var idLoginTextBox=document.getElementById("ctl00_LoginTextBox").focus();
</script>
I've been struggling with this too and I've found a solution that seems to work very well even with deeply nested controls (like AspDotNetStorefront a.k.a. ASPDNSF uses). Note the following code called from the Page_PreRender routine. I knew the name of the TextBox I wanted to give focus to and so I just called FocusNestedControl(Me, "UserName"). I just used Me here because all the routine needs is a parent of the control to get focus; it doesn't matter which parent.
Public Function FocusNestedControl(ByVal ParentControl As Control, ByVal ControlNameToFocus As String) As Control
If ParentControl.HasControls Then
For Each childCtrl As Control In ParentControl.Controls
Dim goodCtrl As Control = FocusNestedControl(childCtrl, ControlNameToFocus)
If goodCtrl IsNot Nothing Then
goodCtrl.Focus()
Return goodCtrl
End If
Next
Else
If ParentControl.ID = ControlNameToFocus Then
ParentControl.Focus()
Return ParentControl
End If
End If
Return Nothing
End Function
You can set focus directly on LoginControl and it will automatically set focus on first field in control. In your case:
this.loginForm.Focus();
More info on MSDN: How to: Set Focus on ASP.NET Web Server Controls
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
Login.FindControl("UserName").Focus();
}
My problem arrized when i moved login control to a custom control and tried to find UsernameTextBox at the OnInit() method.
OnInit of a control is executed before OnInit of Page and this is why no Form control have been created.
I moved the call to UsernameTextBox to the OnLoad function and it worked correctly.
None of the above answers worked for me, so I simply tried:
protected void Page_Load(object sender, EventArgs e) {
// This works for me
TxtMyTextBoxName.Focus();
}
... and it worked!
With an ASP TextBox defined as:
<asp:TextBox ID="TxtMyTextBoxName" type="search" runat="server"></asp:TextBox>
You must put your textbox inside this code on ASP.NET
<form id="WHATEVERYOUWANT" runat="server" method="post">
<div>
<!-- Put your code here-->
</div>
</form>

How to programmatically create and use a list of checkboxes from ASP.NET?

I have a page with a table of stuff and I need to allow the user to select rows to process. I've figured out how to add a column of check boxes to the table but I can't seem to figure out how to test if they are checked when the form is submitted. If they were static elements, I'd be able to just check do this.theCheckBox but they are programaticly generated.
Also I'm not very happy with how I'm attaching my data to them (by stuffing it in there ID property).
I'm not sure if it's relevant but I'm looking at a bit of a catch-22 as I need to known which of the checkboxes that were created last time around were checked before I can re-run the code that created them.
Edit:
I've found an almost solution. By setting the AutoPostBack property and the CheckedChanged event:
checkbox.AutoPostBack = false;
checkbox.CheckedChanged += new EventHandler(checkbox_CheckedChanged);
I can get code to be called on a post back for any check box that has changed. However this has two problems:
The call back is processed after (or during, I'm not sure) Page_Load where I need to use this information
The call back is not called for check boxes that were checked when the page loaded and still are.
Edit 2:
What I ended up doing was tagging all my ID's with a know prefix and stuffing this at the top of Form_Load:
foreach (string v in this.Request.Form.AllKeys)
{
if (v.StartsWith(Prefix))
{
var data = v.Substring(Prefix.Length);
}
}
everything else seems to run to late.
I'm going to assume you're using a DataList but this should work with and Control that can be templated. I'm also going to assume you're using DataBinding.
Code Front:
<asp:DataList ID="List" OnItemDataBound="List_ItemDataBound" runat="server">
<ItemTemplate>
<asp:CheckBox ID="DeleteMe" runat="server"/>
<a href="<%# DataBinder.Eval(Container, "DataItem.Url")%>" target="_blank">
<%# DataBinder.Eval(Container, "DataItem.Title")%></a>
</ItemTemplate>
</asp:DataList>
<asp:Button ID="DeleteListItem" runat="server" OnClick="DeleteListItem_Click" ></asp:Button>
Code Behind:
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadList();
}
protected void DeleteListItem_Click(object sender, EventArgs e)
{
foreach (DataListItem li in List.Items)
{
CheckBox delMe = (CheckBox)li.FindControl("DeleteMe");
if (delMe != null && delMe.Checked)
//Do Something
}
}
LoadList();
}
protected void LoadList()
{
DataTable dt = //Something...
List.DataSource = dt;
List.DataBind();
}
protected void List_ItemDataBound(object sender, DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
{
string id = DataBinder.Eval(e.Item.DataItem, "ID").ToString();
CheckBox delMe = (CheckBox)e.Item.FindControl("DeleteMe");
if (delMe != null)
delMe.Attributes.Add("value", id);
}
}
}
First, make sure that each Checkbox has an ID and that it's got the 'runat="server"' in the tag.
then use the FindControl() function to find it.
For example, if you're looping through all rows in a GridView..
foreach(GridViewRow r in Gridview1.Rows)
{
object cb = r.FindControl("MyCheckBoxId");
if(r != null)
{
CheckBox chk = (CheckBox)cb;
bool IsChecked = chk.Checked;
}
}
Postback data is restored between the InitComplete event and the PreLoad event. If your checkboxes are not created until later then the checkboxes will play "catch up" with their events and the data will be loaded into the control shortly after it is created.
If this is to late for you then you will have to do something like what you are already doing. That is you will have to access the post data before it is given to the control.
If you can save the UniqueId of each CheckBox that you create then can directly access the post data without having to given them a special prefix. You could do this by creating a list of strings which you save the ids in as you generate them and then saving them in the view state. Of course that requires the view state to be enabled and takes up more space in the viewstate.
foreach (string uniqueId in UniqueIds)
{
bool data = Convert.ToBoolean(Request.Form[uniqueId]);
//...
}
Your post is a little vague. It would help to see how you're adding controls to the table. Is it an ASP:Table or a regular HTML table (presumably with a runat="server" attribute since you've successfully added items to it)?
If you intend to let the user make a bunch of selections, then hit a "Submit" button, whereupon you'll process each row based on which row is checked, then you should not be handling the CheckChanged event. Otherwise, as you've noticed, you'll be causing a postback each time and it won't process any of the other checkboxes. So when you create the CheckBox do not set the eventhandler so it doesn't cause a postback.
In your submit button's eventhandler you would loop through each table row, cell, then determine whether the cell's children control contained a checkbox.
I would suggest not using a table. From what you're describing perhaps a GridView or DataList is a better option.
EDIT: here's a simple example to demonstrate. You should be able to get this working in a new project to test out.
Markup
<form id="form1" runat="server">
<div>
<table id="tbl" runat="server"></table>
<asp:Button ID="btnSubmit" runat="server" Text="Submit"
onclick="btnSubmit_Click" />
</div>
</form>
Code-behind
protected void Page_Load(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++)
{
var row = new HtmlTableRow();
var cell = new HtmlTableCell();
cell.InnerText = "Row: " + i.ToString();
row.Cells.Add(cell);
cell = new HtmlTableCell();
CheckBox chk = new CheckBox() { ID = "chk" + i.ToString() };
cell.Controls.Add(chk);
row.Cells.Add(cell);
tbl.Rows.Add(row);
}
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
foreach (HtmlTableRow row in tbl.Rows)
{
foreach (HtmlTableCell cell in row.Cells)
{
foreach (Control c in cell.Controls)
{
if (c is CheckBox)
{
// do your processing here
CheckBox chk = c as CheckBox;
if (chk.Checked)
{
Response.Write(chk.ID + " was checked <br />");
}
}
}
}
}
}
What about using the CheckBoxList control? I have no Visual Studio open now, but as far as I remember it is a DataBound control, providing DataSource and DataBind() where you can provide a list at runtime. When the page does a postback you can traverse the list by calling something like myCheckBoxList.Items and check whether the current item is selected by calling ListItem.Selected method. This should work.
Add them in an override of the CreateChildControls method of the Page. Be sure to give them an ID! This way they get added to the control tree at the correct time.
IMHO The best way would be to use DataBound Templated Control though, i.e. something like a ListView (in .NET 3.5). then in pageload after postback traverse all items in the databound control and use item.FindControl to get at the actual checkbox.
What I ended up doing was tagging all my ID's with a know prefix and stuffing this at the top of Form_Load:
foreach (string v in this.Request.Form.AllKeys)
{
if (v.StartsWith(Prefix))
{
var data = v.Substring(Prefix.Length);
}
}
everything else seems to run to late.

Resources