I want to load data in second <select> tag (in ASP.NET) when I select an item from first <select> tag.
I have :
<table cellpadding="2" border="0">
<tr><td>Categories : <br /><select id="list_cat_for_list" runat="server" onchange="get_list" ></select><br />
<select id="list_got_links" runat="server"></select>
</td><td><asp:RequiredFieldValidator ID="RequiredFieldValidator1" ControlToValidate="list_cat_for_list" ValidationGroup="del_cat" Display="Static" runat="server" ErrorMessage="select category"></asp:RequiredFieldValidator></td></tr>
<asp:Button runat="server" ID="Button1" OnClick="delete_category_function" Text="Delete category" ValidationGroup="del_cat" />
</table>
And the code behind :
protected void get_list( object sender, EventArgs e ) {
BusinessLayerArcht layer = LoadDataFromBL();
foreach ( CategoriesCtrlDto cto in layer.Categories ) {
if ( cto.Name == list_cat_for_list.Value ) {
foreach ( LinksCtrlDto lk in cto.Links ) {
list_got_links.Items.Add( lk.Url );
}
}
}
}
When I change option, IE returns that get_list is undefined.
I don't know what arguments I have to pass to C# function.
I know that onClick has object sender, EventArgs e...
Where is my mistake ?
You can use the ASP Drop down list to perform this aciton on the server side.
<asp:dropdown id = "id" runat="server" selectedIndexChanged="get_list"><asp:dropdownlist>
If you need to access the client side version of the control in javascript you can utilize the browser's "view source" feature to get the ASP generated ID for the control and use that for referencing in any javascript.
If you wish to use AJAX there's an extender in the AJAX Control Toolkit which allows you to perform the cascading drop down feature with multiple dropdowns asynchronously so you won't have the complete postbacks going on while the user is interacting with the page.
You can download the toolkit for free from Here
Why don't you use the asp.net drop down list instead of the html select. Both will be rendered as select element but it will be easier for you to use the drop down list chnage event handler
Related
I'm currently trying to create a web based wizard tool. I have a Wizard page that contains navigation buttons and an asp panel that will contain the individual wizard panels.
<asp:Panel ID="wizardControlPanel" runat="server">
<!-- Wizard panel goes here -->
</asp:Panel>
<asp:Button ID="backButton" runat="server" Text="< Back" OnClick="BackButton_Click" />
<asp:Button ID="nextButton" runat="server" Text="Next >" OnClick="NextButton_Click" />
<asp:Button ID="cancelButton" runat="server" Text="Cancel" PostBackUrl="~/"/>
One control dynamically fills a checkboxlist
<asp:Label ID="Title" runat="server" Text=""></asp:Label>
<asp:Label ID="DescriptionLabel" runat="server" Text ="Description for the wizard"></asp:Label>
<asp:CheckBoxList ID="ProjectSelector" runat="server" DataTextField="ProjectName" DataValueField="Id" ></asp:CheckBoxList>
I dynamically load this control into my wizardControlPanel once the checkbox is populated.
WizardControl = (BaseWizardControl)LoadControl(("~/Views/" + e.ControlType.Name + ".ascx"));
wizardControlPanel.Controls.Add(WizardControl);
The problem is; on postback I then need to be able to find out which checkboxes were checked server side, but the control no longer exists.
I can't find it on the _page variable. Running in to problems (I think) because I am adding the control to a content holder. How can I get this control back?
It is there, you just won't be able to access it using an ID. You'll need to find it by looking through the wizardControlPanel.Controls collection. I think there is a property that represents the filename you used. But it would be best to use the debugger to track down either where it is in the collection or an identifier you can use to find it.
Having done this once or twice, I think I also remember that you'll need to recreate the control prior to the OnLoad event of the life cycle so that the postback will be able to populate it.
As Markus says, there is probably a better way to do what you are trying to do. But if you MUST load this dynamically, this is how you should go about locating it.
If you add controls dynamically in ASP.NET WebForms, you need to re-add them manually very early in the page lifecycle of the PostBack (e.g. by overriding OnInit and creating the control with the same id in this code) in order to be able to retrieve the values. See this link for a How-To.
The following sample shows the basic steps. It consists of an ASPX-page that contains a Panel as a placeholder:
<asp:Panel ID="wizardPanel" runat="server">
</asp:Panel>
<asp:Button ID="btn" runat="server" Text="Do a postback" />
<br />
<asp:Label ID="lbl" runat="server" />
This is the codebehind-file:
public partial class DynamicUserControls : System.Web.UI.Page
{
protected UserControl userCtrl;
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (Page.IsPostBack)
CreateUserControl();
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
CreateUserControl();
else
{
lbl.Text = "The following values were selected: " + string.Join(", ", ((IGetSelectedValues)userCtrl).SelectedValues);
}
}
private void CreateUserControl()
{
if (Request["UserCtrl"] == "A")
{
userCtrl = (UserControl) LoadControl("~/MyUserControlA.ascx");
userCtrl.ID = "myUserCtrl";
wizardPanel.Controls.Add(userCtrl);
}
else if (Request["UserCtrl"] == "B")
{
userCtrl = (UserControl)LoadControl("~/MyUserControlB.ascx");
userCtrl.ID = "myUserCtrl";
wizardPanel.Controls.Add(userCtrl);
}
}
}
The basic steps are the following:
The page determines the user control type to be created upon a Request parameter during Page_Load (or later if necessary). It assigns the ID myUserCtrl to the UserControl.
Upon a PostBack, the page inspects the Request parameters again and re-creates the UserControl with the same ID myUserCtrl. This is important so that ASP.NET can retrieve the new values of the control from the postback data after the page initialization phase. The hardest part is usually to decide which user controls to create, because the data that are available in OnInit is usually not too many.
In Page_Load, the user control can be accessed and the values that were posted back are available. The UserControls in the sample contain a CheckBoxList and implement an interface that allows to retrieve the values that were selected by the user.
In most cases it is easier to find a different approach. Maybe you can use a MultiView control for your wizard that contains the UserControls for the wizard pages as static content. See this link for a description of how to use the MultiView control. If there are not too many (read unlimited) different UserControls to use, this approach is much more stable.
I was looking in the wrong place. Page.Form as opposed to Page.Request.Form. Due to the fact the checkboxlist is already defined in the user control, it's name is traceable in this variable. This way I can keep the current wizard structure.
My html.
<input id="rdb1" type="radio" name="rdbData" checked="checked" />
<input id="rdb2" type="radio" name="rdbData" />
<asp:Button ID="btnTest" runat="server" Text="Test" OnClick="btnTest_Click" />
Button is only asp:button but radio buttons are not.First time when page is load rdb1 is selected.But when i click the button btnTest with check rdb2, page is refreshed and select 1st redio button.To prevent this i try jquery like this.
Inside Document.ready:
var btnTest = "<%=btnTest.ClientID %>";
$('#' + btnTest).bind("click", function() {
if ($('#rdb1').attr("checked")) {
$('#rdb2').attr("checked", false);
$('#rdb1').attr("checked", true);
}
else {
$('#rdb1').attr("checked", false);
$('#rdb2').attr("checked", true);
}
});
But its not work.How can we handle this type of situation.Where i am getting wrong.Any idea or any alternative.Thanks.
If that is the request I would suggest you have a hidden field (server side) which will keep the state of which input radio button is selected (use jquery to update the hidden field when user clicks on the radio buttons). Then on postback as the hidden field is set at runat="server" it will maintain its value (viewstate) and you can simply use jquery to set the right radio button as selected. Does that make sense ?
I repeat that the requirement is ABSURD. How are they going to tell you used server-side controls without looking at the code anyway. This is like requiring that you write the code using chopsticks or something.
However just as an exercise I provide the following solution:
<input id="rdb1" type="radio" name="rbdData" value="rbd1" <%= Rdb1Checked %> />
<input id="rdb2" type="radio" name="rbdData" value="rbd2" <%= Rdb2Checked %> />
<asp:Button ID="btnTest" runat="server" Text="Test" onclick="btnTest_Click" />
And the code behind:
protected string Rdb1Checked
{
get
{
if (IsPostBack)
{
if (Request["rbdData"] == "rbd1")
{
return "checked";
}
else
{
return "";
}
}
return "checked";
}
}
protected string Rdb2Checked
{
get
{
if (IsPostBack)
{
if (Request["rbdData"] == "rbd2")
{
return "checked";
}
else
{
return "";
}
}
return "";
}
}
Ask why they have these requirements. Maybe they don't want to see the client IDs in which case you may set the ClientIDMode to Static and avoid auto generated IDs. You can remove them completely by setting them to null, etc. Maybe they don't like what Web Forms renders for Radio buttons in which case using server side inputs would be OK. The requirement on its own simply does not make sense.
Shree
The fact is that client click (added by jQuery) executes before the call to server. If you want to persist the selectin, try using server sided controls:
<input id="rdb1" type="radio" name="rdbData" checked="true" runat="server" />
<input id="rdb2" type="radio" name="rdbData" runat="server" />
<asp:Button ID="btnTest" runat="server" Text="Test" OnClick="btnTest_Click" />
Try this if it does work for you.
Hope it helps.
When the "Test" button is clicked, the page posts back to the server, which re-renders all client-side controls just as if the page has been loaded for the first time. Since the entire page is reloaded, jQuery will also "forget" about the state of the controls, so that approach won't work either. The simplest way to prevent this is to ensure the radio buttons run on the server side. For instance:
<asp:RadioButton id="rdb1" Checked="True" GroupName="RadioGroup1" runat="server" />
<asp:RadioButton id="rdb2" GroupName="RadioGroup1" runat="server" />
Hope that helps!
What do you mean? That you have a requirement that does not let you use "servr side controls" or that your IDE does not allow that?
By definition, in ASP.NET all HTML controls inherit from a server control. Simply adding runat="server", you can access that control from codebehind, although it will still render in page as a normal HTML control.
Working with C# .NET 4.0 and Umbraco
I have a user control on which there is a button allowing user to dynamically add additional text boxes to the form. I've tried a myriad of methods but have been unable to persist any data entered into the dynamic text boxes between page loads.
Here's the UI:
<div id="new-item">
<h3>Add new menu item</h3>
<div><label for="ItemTitle">Title</label><asp:TextBox ID="ItemTitle" runat="server" CssClass="title"></asp:TextBox></div>
<div><label for="ItemDescription">Text</label><textarea id="ItemDescription" runat="server" rows="5" cols="20"></textarea></div>
<div><label for="ItemPrice">Price</label><asp:TextBox ID="ItemPrice" runat="server" CssClass="price"></asp:TextBox></div>
<div class="new-item-options">
<p><strong>Menu item options (optional) </strong><asp:Button ID="AddMenuItemOption" runat="server" Text="Add Option" OnClick="AddOption" /></p>
<asp:Panel ID="MenuItemOptionsPanel" runat="server"></asp:Panel>
<asp:HiddenField ID="ItemOptionCount" runat="server" />
</div>
<div><asp:Button ID="AddItemButton" runat="server" Text="Save" /></div>
<asp:HiddenField ID="ItemID" runat="server" />
<asp:HiddenField ID="ItemOrder" runat="server" />
And in the AddOption button click event:
protected void AddOption(object sender, EventArgs e)
{
var dynamicControlCount = Convert.ToInt32(ItemOptionCount.Value) + 1;
for (var option = 0; option < dynamicControlCount; option++)
{
MenuItemOptionsPanel.Controls.Add(new Literal { ID = "OptionTextLiteral" + option, Text = "<label>Option Text</label>" });
MenuItemOptionsPanel.Controls.Add(new TextBox { ID = "OptionTextBox" + option });
MenuItemOptionsPanel.Controls.Add(new Literal { ID = "OptionPriceLiteral" + option, Text = "<label>Option Price</label>" });
MenuItemOptionsPanel.Controls.Add(new TextBox { ID = "OptionPriceBox" + option });
}
ItemOptionCount.Value = dynamicControlCount.ToString();
}
I know I need to create these dynamic controls in the Page_Load or OnInit methods but the problem is when the page loads for the first time, I don't want any dynamic controls create, only once the user clicks the button each time I'm like additional control added and those that already exist to have any data in them persisted.
Any ideas? I don't think I'm too far off hopefully :)
Can you test the confition (perhaps IsPostback) in page_load, then if you need to generate the controls, do it?
Perhaps you have to look at this (series of) article. It explains in details how to work with dynamically created controls, especially about how to persist ViewState.
Otherwise, I would suggest you to go the AJAX way (create controls using JavaScript, post the data back to server using AJAX for the server to process). In this case, you do not have to worry about PostBack and ViewState, and it makes the user experience better too!
ASP.Net web forms, .NET 2.0
I have a dilemma. I have an aspx page that has a custom control:
<def:CustomControl ID="customID" runat="server" />
The custom control can be added multiple times to the ASPX page if certain criteria is met:
<asp:Repeater runat="server" ID="options" OnItemDataBound="options_OnItemDataBound">
<HeaderTemplate>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
</HeaderTemplate>
<ItemTemplate>
<td>
<span>
<asp:Label runat="server" ID="optionName">
</asp:Label>
<asp:DropDownList runat="server" ID="optionValues" CssClass="PartOption" >
</asp:DropDownList>
</span>
</td>
</ItemTemplate>
<FooterTemplate>
</tr>
</table>
</FooterTemplate>
</asp:Repeater>
In the code behind of the aspx page, I wanted to append a event (OnSelectedItemChange) to the dropdown control that isn't actually on the ASPX page (yet). However, when I try to do something like the following in the code behind:
foreach(Control eachControl in customID.Controls) {
if (eachControl.HasControls) {
Control DdControl = eachControl.FindControl("optionValues"); //always null
if (DdControl != null && DdControl is typeOf(DropDownList)) {
DdControl = DdControl as DropDownlist; //I might have the syntax wrong
//here, but you get the point.
//add event to control.
}
}
}
But All that eachControl has is a repeater, and it shows its childcontrol count as 0. So when it get to the FindControl method, it always returns null.
QUESTION
So what I am trying to do is add an event (OnSelectedItemChange) to the dropdownlist control inside the repeater (which is a custom control that gets added to the page if criteria is met). When a selection is made in the drop down, I want it to trigger the Event method.
How can I either:
A) Find a way to add the event if the dropdownlist control exists on the page?
OR
B) A way to be able to call a method in the code behind and pass the selections from all the drop down lists (since the custom control could be added more than once creating multiple drop downs?
NOTE I don't have the code in front of me, so if I have something syntactically incorrect, please overlook. I also know that ID's are unique, so this is also assumed to be a problem with my logic. When it renders these, the ID's might be mangled by the asp name convention which I would assume I have to find a way around.
If you create that event on the custom control, you won't need to check if it exists on the page or not. If it does, it will definately trigger the event. Or am I missing something here?
EDIT:
What you'll have to do is declare a public event on your control, then when the SelectedIndexChanged Event fired, you'd fire that event, and receive it on the page.
So on your control you'd have:
public delegate void MyIndexChangedDelegate(string value);
public event MyIndexChangedDelegate MyEvent;
protected void myDropDown_SelectedIndexChanged(object sender, EventArgs e)
{
MyEvent(myDropDown.SelectedValue); // Or whatever you want to work with.
}
Then on your page, on your control declaration you'd have:
<usc:control1 runat="server" OnMyEvent="EventReceiver" />
And on the code behind:
protected void EventReceiver(string value)
{
// Do what you have to do with the selected value, which is our local variable 'value'
ClientScript.RegisterStartupScript(typeof(Page), "Alert", string.Format("<script language='JavaScript'>alert('User selected value {0} on my DropDown!');</script>"), value);
}
That should work.
Assuming that you can't put this logic in the control itself, what you need to do I think is access that repeater and attach an ItemDataBound event to it. Something like this:
Repeater options = customID.FindControl("options") as Repeater;
if (options != null)
{
options.ItemDataBound += new RepeaterItemEventHandler(OptionsItemDataBound);
}
Then in the ItemDataBound event you would do something like this:
void OptionsItemDataBound(object sender, RepeaterItemEventArgs e)
{
DropDownList optionValues = e.Item.FindControl("optionValues") as DropDownList;
if (optionValues != null)
{
//perform logic you need here
}
}
I don't have time to try that out right this minute, but I suspect that should work.
I need to display a control consistently across a set of pages. So I'm using a MasterPage to do that in ASP.NET/C#. However I also need to programmatically access this control, mostly provide options to view/hide depending on whether the controls checkbox is clicked.
Here is the Source for the MasterPage
<div id="verifyInitial" runat="server">
<asp:CheckBox ID="chkInitialVerify" runat="server"
oncheckedchanged="chkInitialVerify_CheckedChanged" />
I agree that my initial data is correct.
</div>
<div id="verifyContinuous" runat="server">
<asp:CheckBox ID="chkContinuousVerify" runat="server"
oncheckedchanged="chkContinuousVerify_CheckedChanged" />
I agree that my continuous data is correct
</div>
Now in the code behind I want to perform the following operations. Basically if a person clicks on the checkbox for the initial div box, then the initial box disappears and the continous box shows up. However it seems that the code behind for the MasterPage does not activate whenver I click on the checkbox. Is that just the way MasterPages are designed? I always thought you could do add some sort of control functionality beyond utilizing the Page Load on the Master Page.
protected void chkInitialVerify_CheckedChanged(object sender, EventArgs e)
{
verifyContinuous.Visible = true;
verifyInitial.Visible = false;
}
protected void chkContinuousVerify_CheckedChanged(object sender, EventArgs e)
{
verifyContinuous.Visible = false;
}
If you're expecting the two controls to trigger a change for that page immediately then you'll need to set the AutoPostBack property to true for both of them:
<div id="verifyInitial" runat="server">
<asp:CheckBox ID="chkInitialVerify" runat="server" oncheckedchanged="chkInitialVerify_CheckedChanged" AutoPostBack="true" />
I agree that my initial data is correct.
</div>
<div id="verifyContinuous" runat="server">
<asp:CheckBox ID="chkContinuousVerify" runat="server" oncheckedchanged="chkContinuousVerify_CheckedChanged" AutoPostBack="true" />
I agree that my continuous data is correct
</div>
Otherwise, you need an <asp:button /> or some other control on the page to trigger a postback and cause your event handlers to run. The button, or other control, can either be on your masterpage or on your content page, the choice is entirely yours.