FormView CheckBox should fill Shipping info with Billing info - asp.net

Staying away from javascript I endeavor to use Check_Clicked event handler to populate my Shipping info if same as Billing info in my FormView. This should be real simple but I have not been able to get the plumbing right.
I am following the example in http://msdn.microsoft.com/en-us/library/4s78d0k1%28v=vs.71%29.aspx#Y617 but would like to use my FormView instead of Form1.
The value that appears on checking the box is System.Web.UI.WebControls.TextBox
<asp:CheckBox id="SameCheckBox" AutoPostBack="True"
Text="Same as billing." TextAlign="Right"
OnCheckedChanged="Check_Clicked" runat="server"/>
protected void Check_Clicked(Object sender, EventArgs e)
{
CheckBox SameCheckBox = (CheckBox)FormView1.FindControl("SameCheckBox");
TextBox BillingFirst = (TextBox)FormView1.FindControl("BillingFirstNameTextBox");
TextBox ShippingFirst = (TextBox)FormView1.FindControl("ShippingFirstNameTextBox");
if (SameCheckBox.Checked)
{
ShippingFirst.Text = BillingFirst.ToString();
}
else
ShippingFirst = null;
}
In addition to the solutions given to me below I will add for others edification; the other problem I had was DropdownList data. Here is what worked for me:
DropDownList BillingState = FormView1.Row.FindControl("BillingStateTextBox") as DropDownList;
DropDownList ShippingState = FormView1.Row.FindControl("ShippingStateTextBox")as DropDownList;
ShippingState.SelectedValue = BillingState.Text;

This line:
ShippingFirst.Text = BillingFirst.ToString();
Should be:
ShippingFirst.Text = BillingFirst.Text;
The ToString() output of a WebControl will be the type name.

Use :
ShippingFirst.Text = BillingFirst.Text;

Related

ASP.NET user control and grid view

IN dot net, User control has a drop down when it is changed. The grid needs to be changed, but the grid is not inside user control?
How can we achieve it?
You bind an event using the OnSelectedIndexChange to your drop down list on your aspx page:
<asp:DropDownList ID="ddlGridType" runat="server" OnSelectedIndexChanged="ddlGridType_SelectedIndexChanged" AutoPostBack="true" >
Then on your C# code behind:
protected void ddlRunType_SelectedIndexChanged(object sender, EventArgs e)
{
DataTable dtblDataSource = New DataTable();
string gridType = ddlGridType.SelectedValue;
//remove the old data from the grid view
TheGridView.DataSource = null;
TheGridView.DataBind();
//get the new data using whatever method you use to get the data
dtblDataSource = theGridView_GetDataSource(gridType);
//bind the new data to the list
TheGridView.DataSource = dtblDataSource;
TheGridView.DataBind();
}

One DropDownList does not fire SelectedIndexChanged But Other Does

I am having a issue that I just can figure why it is happening
the situation is that I have two dropdownlists, both set up the same way
<asp:DropDownList ID="DocumentLink" runat="server" AutoPostBack="true" OnSelectedIndexChanged="DocumentLink_Changed">
</asp:DropDownList>
<asp:DropDownList ID="PageLink" runat="server" AutoPostBack="true" OnSelectedIndexChanged="PageLink_Changed">
</asp:DropDownList>
Their events look like this
protected void DocumentLink_Changed(object sender, EventArgs e)
{
DropDownList DocumentLink = sender as DropDownList;
LinkParam = DocumentLink.SelectedValue.ToString();
DescriptionParam = DocumentLink.SelectedItem.Text;
}
protected void PageLink_Changed(object sender, EventArgs e)
{
DropDownList PageLink = sender as DropDownList;
LinkParam = PageLink.SelectedValue.ToString();
DescriptionParam = PageLink.SelectedItem.Text;
}
In the case of the DropDown called "PageLink" the event handler fires. However for the "DocumentLink" the event handler does not. In debug I see that page load is fired but the event drops off after the page load and never enters DocumentLink_Changed
As an point of interest if I use a telerik radComboBox in place of the DropDownList using the same set-up it does work.
<telerik:RadComboBox ID="DocumentLink" runat="server" AutoPostBack="true" OnSelectedIndexChanged="DocumentLink_Changed">
</telerik:RadComboBox>
with the event handler like this
protected void DocumentLink_Changed(object sender, RadComboBoxSelectedIndexChangedEventArgs e)
unfortunately I need to use Dropdownlists for my project.
What could be causing this?
UPDATE
I have taken the working dropdownlist and used the LINQ binding for the dropdownlist that did not work. The result was that the PageLink dropdownlist began to behave just like the 'DocumentLink' dropdownlist. This makes me believe that the issue might be in the binding method but they the two are very similar and I do see results in the dropdownlist
this is my binding
if (selectedValue == 3)
{
DropDownList select = lvLinks.InsertItem.FindControl("PageLink") as DropDownList;
List<IPW_Links_get_document_listResult> getList = (from i in lqContext.IPW_Links_get_document_list(0, "my stuff") select i).ToList();
select.DataSource = getList;
select.DataTextField = "DocumentName";
select.DataValueField = "FolderPath";
select.DataBind();
}
if (selectedValue == 2)
{
DropDownList select = lvLinks.InsertItem.FindControl("PageLink") as DropDownList;
List<IPW_Links_get_available_pagesResult> getList = (from i in lqContext.IPW_Links_get_available_pages(PortalId) select i).ToList();
select.DataSource = getList;
select.DataTextField = "TabName";
select.DataValueField = "TabPath";
select.DataBind();
}
do check if you have any statements in the PageLoad event that alters the dropdownlists. If you have a databinding statement or a selection reset statement in the page load event , then make sure it is under the if not ispostback conditional snippet.

How to use the FindControl function to find a dynamically generated control?

I have a PlaceHolder control inside of a ListView that I am using to render controls from my code behind. The code below adds the controls:
TextBox tb = new TextBox();
tb.Text = quest.Value;
tb.ID = quest.ShortName.Replace(" ", "");
((PlaceHolder)e.Item.FindControl("ph_QuestionInput")).Controls.Add(tb);
I am using the following code to retrieve the values that have been entered into the TextBox:
foreach (ListViewDataItem di in lv_Questions.Items)
{
int QuestionId = Convert.ToInt32(((HiddenField)di.FindControl("hf_QuestionId")).Value);
Question quest = dc.Questions.Single(q => q.QuestionId == QuestionId);
TextBox tb = ((TextBox)di.FindControl(quest.ShortName.Replace(" ","")));
//tb is always null!
}
But it never finds the control. I've looked at the source code for the page and the control i want has the id:
ctl00_cphContentMiddle_lv_Questions_ctrl0_Numberofacres
For some reason when I look at the controls in the ListViewDataItem it has the ClientID:
ctl00_cphContentMiddle_lv_Questions_ctrl0_ctl00
Why would it be changing Numberofacres to ctl00? Is there any way to work around this?
UPDATE:
Just to clarify, I am databinding my ListView in the Page_Init event. I then create the controls in the ItemBound event for my ListView. But based on what #Womp and MSDN are saying the controls won't actually be created until after the Load event (which is after the Page_Init event) and therefore are not in ViewState? Does this sound correct?
If so am I just SOL when it comes to retrieving the values in my dynamic controls from my OnClick event?
UPDATE 2:
So i changed the code i had in my Page_Init event from:
protected void Page_Init(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
//databind lv_Questions
}
}
to:
protected void Page_Init(object sender, EventArgs e)
{
//databind lv_Questions
}
And it fixed my problem. Still a little confused as to why I want to databind regardless of whether it's a postback or not but the issue is resolved.
It looks like you're adding your textbox to a Placeholder control... but then you're searching a ListViewDataItem container for it later.
Seems to me that you need to search for the Placeholder first, and then search it for the textbox.

Adding RadComboBox to RadGrid Edit

I have added a RadControl, RadGrid and I need to add a radComboBox in the edit mode.
When user clicks on the radComboBox, I need to get both "text" and "value" of the radComboBox to save to table when user updates values.
<telerik:RadComboBox ID="RadComboBox1" Runat="server"
DataSourceID="SqlDataSource1" DataTextField="docCategoryName"
DataValueField="docCategoryID" Height="200px" Skin="Vista">
When user selects from the radComboBox, I need to get the value of DataTextField & DataValueField into a HiddenField.
The approach described by Program.X is very good. This, of course, works if you're using a RadCombobox inside of a GridTemplateColumn in RadGrid.
RadGrid also provides a built-in GridDropDownColumn that can automatically render a RadCombobox during edits. If you choose to use the built-in column type, you need to programmatically set the client-side event handlers for the rendered RadGrid, like this:
protected void RadGrid1_ItemCreated(object sender, Telerik.Web.UI.GridItemEventArgs e)
{
//Find GridEditableItems when in Edit mode
if (e.Item is GridEditableItem && e.Item.IsInEditMode)
{
//Get reference to item (i.e. Row)
var item = e.Item as GridEditableItem;
//Get reference to auto-generated RadCombobox in
//specific column (in this case, a column called Title)
var rcb = item["Title"].Controls[0] as RadComboBox;
if (rcb == null)
return;
//Customize the RadCombobox properities
rcb.OnClientSelectedIndexChanged = "onselectedindexchanged";
}
}
Where "onselectedindexchanged" is the name of a client-side JavaScript function on your page designed to handle the RadCombobox event.
Either of these approaches should enable you to achieve your goal.
Telerik are the best people to help you with this, but from their site (and from memory):
http://www.telerik.com/help/aspnet-ajax/combo_clientsideonclientselectedindexchanged.html
If you have your radCombo:
<telerik:RadComboBox
ID="RadComboBox1"
runat="server"
OnClientSelectedIndexChanged="OnClientSelectedIndexChanged">
</telerik:RadComboBox>
With your JS event:
<script language="javascript" type="text/javascript">
function OnClientSelectedIndexChanged(sender, eventArgs)
{
var item = eventArgs.get_item();
// get the text and value elements
var text=item.get_text();
var val=item.get_value();
$('#hiddenField').val(val);
}
</script>
Where hiddenField is the ID of the hidden field.

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