I have form with 2 DDL named
State and City
State:
<asp:UpdatePanel ID="States" runat="server" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="States"EventName="SelectedIndexChanged" />
</Triggers>
<ContentTemplate>
<asp:DropDownList ID="States" runat="server"
AutoPostBack="True" DataSourceID="StatesObjectDataSource"
AppendDataBoundItems="true"
onselectedindexchanged="States_SelectedIndexChanged">
<asp:ListItem Value="-1" Text="- None -"/>
</asp:DropDownList>
<asp:ObjectDataSource ID="StatesObjectDataSource" runat="server"
onselecting="StatesObjectDataSource_Selecting"
SelectMethod="GetStates"
TypeName="Something">
</asp:ObjectDataSource>
</ContentTemplate>
</asp:UpdatePanel>
City:
<asp:DropDownList ID="Cities" runat="server">
</asp:DropDownList>
When they choose a state I want to populate the Cities DDL with all the cities for that state.
In code behind I am able to get to
States_SelectedIndexChanged(object sender, EventArgs e)
and i try to populate the Cities DDL by this
Cities.Items.Add(new ListItem(city,city));
However, I do not see my Cities DDL populated
I recommend creating a private property in the ViewState that holds the collection of physical objects. Then add the object to that list then databind the list of objects to the drop down.
Page Behind
<asp:DropDownList runat="server" ID="ddlCity" DataValueField="Key" DataTextField="Value">
</asp:DropDownList>
Code Behind
private List<KeyValuePair<string, string>> ListData
{
get { return (List<KeyValuePair<string, string>>) (ViewState["ListData"] ??
(ViewState["ListData"] = new List<KeyValuePair<string, string>>())); }
set { ViewState["ListData"] = value; }
}
protected void States_SelectedIndexChanged_SelectedIndexChanged(object sender, EventArgs e)
{
ListData.Add(new KeyValuePair<string, string>(ddlCitys.SelectedValue, ddlCitys.SelectedValue));
ddlCitys.DataSource = ListData;
ddlCitys.DataBind();
}
The get statement also employs lazy loading on the ListData property so you will never encounter a null reference exception when accessing the list.
If at all possible, I would suggest using the CascadingDropDown Extender instead of the UpdatePanel. There's no use reinventing that wheel, and the Toolkit control uses web services instead of partial postbacks (much faster).
Place your city DropDownList inside the update panel.
Related
I have cascading dropdowns one is for topics and the other for sections. I was hoping to be able to use tooltips to show the description of each topic and section. However I first have to choose a particular topic and or a section to get the tooltip to show up and also the only description that shows up is for the one at the bottom of the dropdown regardless if its selected or not. Any ideas what I'm doing wrong?
Below is how I'm loading the topic dropdown. Load_Topic1() is being called on the Page_Load method.
protected void Load_Topic1()
{
var topics = ReadTopics();
foreach (var topic in topics)
{
var topicListItem = new ListItem(topic.Name, topic.Id.ToString());
topic1.Items.Add(topicListItem);
topic1.Attributes.Add("Title",topic.Description);
}
topic1.Items.Insert(0, new ListItem("--- Select Topic ---", "0"));
}
Here are my cascading dropdowns:
<asp:UpdatePanel ID="updatePanel1" runat="server">
<ContentTemplate>
<asp:DropDownList ID="topic1" DataTextField="NAME" DataValueField="ID" OnSelectedIndexChanged="Load_Section1" AutoPostBack="True" AppendDataBoundItems="true" runat="server"/>
<asp:DropDownList ID="section1" DataTextField="NAME" DataValueFile="ID" runat="server">
<asp:ListItem Text="--- Select Section ---" Value="0"></asp:ListItem>
</asp:DropDownList><br/>
<asp:RequiredFieldValidator runat="server" ID="topic1ReqVal" InitialValue="0" ControlToValidate="topic1" errormessage="Please select a topic"/>
<asp:RequiredFieldValidator runat="server" ID="section1ReqVal" InitialValue="0" ControlToValidate="section1" errormessage="Please select a section"/><br/>
</ContentTemplate>
</asp:UpdatePanel>
The 2nd dropdown or section1 dropdown is being given its information from this method:
protected void Load_Section1(object sender, EventArgs e)
{
section1.Items.Clear();
var sections = ReadForTopic(Guid.Parse(topic1.SelectedValue));
foreach (var section in sections)
{
var sectionListItem = new ListItem(section.Name, section.Id.ToString());
section1.Items.Add(sectionListItem);
section1.Attributes.Add("Title", section.Description);
}
section1.Items.Insert(0, new ListItem("--- Select Section ---", "0"));
}
You adding the attribute just for the dropdown, not for each element in the dropdown.
What you need to do is:
foreach (var topic in topics)
{
var topicListItem = new ListItem(topic.Name, topic.Id.ToString());
topicListItem.Attributes.Add("Title",topic.Description);
topic1.Items.Add(topicListItem);
}
And of course the same for section. This should give each select element in your option and title.
Cheers,
I can't get the dropdown onselectedindexchanged event to fire, and when I make a selection it resets the value of the dropdown onpostback, even though I have the if (!ispostback) in the page load event.
this is a content page in a master page in asp in case that matters.
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:DropDownList ID="EventSVCProgList" runat="server"
EnableViewState="true"
OnSelectedIndexChanged="EventSVCProgList_SelectedIndexChanged"
AutoPostBack="true"></asp:DropDownList>
</ContentTemplate>
</asp:UpdatePanel>
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
SqlConnection constr = new SqlConnection(ConfigurationManager.ConnectionStrings["CBTestDBConnectionString"].ConnectionString);
SqlCommand eventsvcprogCMD = new SqlCommand("select*from SvcProg where eventatteligable=1", constr); // table name
SqlDataAdapter eventsvcadapt = new SqlDataAdapter(eventsvcprogCMD);
DataSet eventsvcset = new DataSet();
constr.Open();
eventsvcadapt.Fill(eventsvcset); // fill dataset
EventSVCProgList.DataTextField = eventsvcset.Tables[0].Columns["SvcProgID"].ToString(); // text field name of table dispalyed in dropdown
EventSVCProgList.DataValueField = eventsvcset.Tables[0].Columns["eventatteligable"].ToString();
EventSVCProgList.DataSource = eventsvcset.Tables[0]; //assigning datasource to the dropdownlist
EventSVCProgList.DataBind(); //binding dropdownlist
constr.Close();
}
}
protected void EventSVCProgList_SelectedIndexChanged(object sender, EventArgs e)
{
MessageBox.Show("Eat Poop");
var somevalue = EventSVCProgList.SelectedValue;
}
There are couple of things.
1) You need to add a Script Manager to the page at the top if not added already(it will give you a runtime error if you have not added a script Manager to the page)
2) You need to change the Update Panel content as shown below
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:DropDownList ID="EventSVCProgList" runat="server" AutoPostBack="True" OnSelectedIndexChanged="EventSVCProgList_SelectedIndexChanged">
</asp:DropDownList>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="EventSVCProgList" EventName="SelectedIndexChanged" />
</Triggers>
</asp:UpdatePanel>
There seems that any parent control or page leven ViewState is disabled. please check in debug mode that what value you getting for EventSVCProgList.EnableViewState and other parent controls' as well.
thanks for the help. its still not working so i'm just going to try to use javascript instead. its got to be some fundamental flaw with the way the master page or content page is setup.
Im facing a pretty weird problem today.
I created a DropDownList which adds the selected Item to a List. The List will be binded to the ListView.
This is the Dropdown:
<asp:DropDownList ID="ddlChooseNewApplication" runat="server" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged" AutoPostBack="True">
<asp:ListItem Selected="True">Bitte wählen</asp:ListItem>
<asp:ListItem Value="windows">Windows</asp:ListItem>
<asp:ListItem Value="mail">E-Mail</asp:ListItem>
<asp:ListItem Value="app1">App1</asp:ListItem>
<asp:ListItem Value="app2">App2</asp:ListItem>
<asp:ListItem Value="app3">App3</asp:ListItem>
</asp:DropDownList>
Next, when a Item has been clicked it runs the following code:
//This is a global variable
List<NewApplicationModels> applicationName = new List<NewApplicationModels>();
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
string value = ddlChooseNewApplication.SelectedValue.ToString();
applicationName.Add(new NewApplicationModels(){ ApplicationName = value});
ListViewNewApplications.DataSource = applicationName;
ListViewNewApplications.DataBind();
}
It will be added to a List<> which should add the selected application to the ListView which looks like this:
<asp:ListView ID="ListViewNewApplications" runat="server">
<ItemTemplate>
<br /><br />
<%# Eval("ApplicationName") %><br />
<asp:Label ID="Label3" runat="server" Text="Titel"></asp:Label><br />
<asp:TextBox ID="tbNewTitle" runat="server"></asp:TextBox><br /><br />
<asp:Label ID="Label4" runat="server" Text="Beschreibung"></asp:Label><br />
<asp:TextBox ID="tbNewDescription" runat="server" TextMode="MultiLine"></asp:TextBox><br /><br />
</div>
</ItemTemplate>
</asp:ListView>
Adding a single Item to the ListView works. The problem is, if I select a new Item in the DropDown, the current object in the ListView will be overwritten. I want it to create a new Item under the current Item.
Where is the mistake?
Many thanks in advance
Editted: Just read here that static property is per application domain, not per user, So the solution should change to use Session State
//Add using on top of .cs
using System.Linq;
//In cs class
public partial class name_of_class : Page
{
private List<NewApplicationModels> applicationName = new List<NewApplicationModels>();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//Do page_load stuff....
Session.Remove("name_here"); //reset the Session when first page load
}
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
//Get List from Session
applicationName = (List<NewApplicationModels>)Session["name_here"];
if (applicationName == null)
applicationName = new List<NewApplicationModels>();
string value = ddlChooseNewApplication.SelectedValue.ToString();
if (!applicationName.Any(item => item.ApplicationName == value))
{
applicationName.Add(new NewApplicationModels(){ ApplicationName = value});
Session["name_here"] = applicationName;
ListViewNewApplications.DataSource = applicationName;
ListViewNewApplications.DataBind();
}
}
}
For static property is per application domain, 2 stranger people from 2 different place browse the same page in same server (app domain) will all see it.
That means when userA change dropdownlist 2 times and the listview have 2 items, then userB browse and change dropdownlist, he may get 3 items in listview, 2 of userA and 1 of his recently choose (he may get nothing too).
Hi I am developing one asp.net web application, In that I am creating one registration form. On Registration form page, I have three Dropdownlists named as country, state, city.
So When User selects any country, states in that country will be shown in dropdownlist of state and when user selects state from State dropdownlist He can see lists of cities in in dropdownlist.
I have implemented the functionality, but When User selects value in dropdownlist, post-back occurs.
In my case I don't want to reload the page when User selects country or state, So I have tried to implement the same functionality by using ajax toolkit. But I am not able to achieve the same functionality using ajax.
So in brief my problem is: selecting country, state and city from dropdownlist in asp.net without reloading the page.
Here I am giving you the aspx part.
Please help me.
CountryDropDown
<asp:DropDownList ID="DropDownListCountry" runat="server" Enabled="false"
OnSelectedIndexChanged="DropDownListCountry_OnSelectedIndexChanged"
AutoPostBack ="false">
<asp:ListItem>India</asp:ListItem>
<asp:ListItem>Other</asp:ListItem>
</asp:DropDownList>
StateDropDown
<asp:UpdatePanel ID="UpdatePanel1" runat="server" >
<Triggers>
<asp:AsyncPostBackTrigger ControlID="DropDownListCountry" EventName="OnSelectedIndexChanged" />
</Triggers>
<ContentTemplate>
<asp:DropDownList runat="server" ID="DropDownListState" Enabled="false"
OnSelectedIndexChanged="DropDownListState_OnSelectedIndexChanged">
</asp:DropDownList>
</ContentTemplate>
</asp:UpdatePanel>
wow you manage to make a big mess of explaining whats wrong....
but ill do my best to try to help. first of, first DDL should be defined like so:
<asp:DropDownList ID="Contries" runat="server" AutoPostBack="true" OnSelectedIndexChanged="Contries_SelectedIndexChanged">
<asp:ListItem Text="country1" />
<asp:ListItem Text="country2" />
</asp:DropDownList>
2nd DDL :
<asp:UpdatePanel runat="server" >
<ContentTemplate>
<asp:DropDownList ID="States" runat="server" AutoPostBack="true">
<asp:ListItem Text="state1" />
<asp:ListItem Text="state2" />
</asp:DropDownList>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Contries" EventName="OnSelectedIndexChanged" />
</Triggers>
</asp:UpdatePanel>
and so on, auto post back must be true in DDL that should do async post back,
try to remove DDLs one by one and start only with 2 then move forward.
First create a web service to retrieve data for your dropdownlists
Create webservice: CascadingDropdown.asmx
in your CascadingDropdown.asmx.cs write code retrieve data for Country, State and City from the database, see this is how i did, you can do something like this, i have used entity framework to fetch the data from the database.
[WebMethod]
public CascadingDropDownNameValue[] FetchCountries()
{
GetLookupResponse countryLookupResponse = commonService.GetLookup("Country");
List<CascadingDropDownNameValue> countries = new List<CascadingDropDownNameValue>();
foreach (var dbCountry in countryLookupResponse.LookupItems)
{
string countryID = dbCountry.ID.ToString();
string countryName = dbCountry.Description.ToString();
countries.Add(new CascadingDropDownNameValue(countryName, countryID));
}
return countries.ToArray();
}
[WebMethod]
public CascadingDropDownNameValue[] FetchStates(string knownCategoryValues)
{
int countryID;
StringDictionary strCountries = AjaxControlToolkit.CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);
countryID = Convert.ToInt32(strCountries["Country"]);
GetLookupResponse stateLookupResponse = commonService.GetLookup("State");
List<CascadingDropDownNameValue> states = new List<CascadingDropDownNameValue>();
foreach (var dbState in stateLookupResponse.LookupItems.Where(id => id.DependencyID == countryID))
{
string stateID = dbState.ID.ToString();
string stateName = dbState.Description.ToString();
states.Add(new CascadingDropDownNameValue(stateName, stateID));
}
return states.ToArray();
}
[WebMethod]
public CascadingDropDownNameValue[] FetchCities(string knownCategoryValues)
{
int stateID;
StringDictionary strStates = AjaxControlToolkit.CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);
stateID = Convert.ToInt32(strStates["State"]);
GetLookupResponse cityLookupResponse = commonService.GetLookup("City");
List<CascadingDropDownNameValue> cities = new List<CascadingDropDownNameValue>();
foreach (var dbCity in cityLookupResponse.LookupItems.Where(id => id.DependencyID == stateID))
{
string cityID = dbCity.ID.ToString();
string cityName = dbCity.Description.ToString();
cities.Add(new CascadingDropDownNameValue(cityName, cityID));
}
return cities.ToArray();
}
then in your aspx file, you need to register AjaxControlToolkit on top of the page below
, if you haven't installed AjaxControlToolkit, then install it from Nuget packages.
then your dropdownlist code:
<label class="col-sm-3 col-form-label required">Country</label>
<div class="col-sm-9">
<asp:DropDownList ID="ddlCountry" runat="server" CssClass="form-control"></asp:DropDownList>
<ajax:CascadingDropDown ID="csdCountry" runat="server"
Category="Country"
TargetControlID="ddlCountry"
LoadingText="Loading Countries..."
ServiceMethod="FetchCountries"
ServicePath="~/CascadingDropdown.asmx"></ajax:CascadingDropDown>
</div>
<label class="col-sm-3 col-form-label required">State</label>
<div class="col-sm-9">
<asp:DropDownList ID="ddlState" runat="server" CssClass="form-control"></asp:DropDownList>
<ajax:CascadingDropDown ID="csdState" runat="server"
ParentControlID="ddlCountry"
Category="State"
TargetControlID="ddlState"
LoadingText="Loading States..."
ServiceMethod="FetchStates"
ServicePath="~/CascadingDropdown.asmx"></ajax:CascadingDropDown>
</div>
<label class="col-sm-3 col-form-label required">City</label>
<div class="col-sm-9">
<asp:DropDownList ID="ddlCity" runat="server" CssClass="form-control"></asp:DropDownList>
<ajax:CascadingDropDown ID="csdCity" runat="server"
ParentControlID="ddlState"
Category="City"
TargetControlID="ddlCity"
LoadingText="Loading Cities..."
ServiceMethod="FetchCities"
ServicePath="~/CascadingDropdown.asmx"></ajax:CascadingDropDown>
</div>
What i am doing in this is when we select country frop country dropdownlist, I am passing country id to FetchStates webmethod that is in our CascadingDropdown.asmx.cs web service to fetch the states based on country id, and same goes for city, pass state id to FetchCities webmethod to fetch cities.
Hope it helps.
I have an entity class with a MailingState property. I want to do some manipulation of that value in another property, so I added:
public string MailingStateAbbreviation
{
get { return getStateAbbreviation(MailingState); }
set { MailingState = value; }
}
However, in a DetailsView EditItemTemplate, the following fails when I try to submit the edit form:
<asp:DropDownList ID="ddlMailingState" runat="server" DataSourceID="ddlAllStates"
AppendDataBoundItems="True" DataTextField="StateAbbreviation"
DataValueField="StateAbbreviation"
SelectedValue='<%# Bind("MailingStateAbbreviation") %>'>
<asp:ListItem Value="" Text="" />
</asp:DropDownList>
I get this error:
A property named 'MailingStateAbbreviation' was not found on the entity during an insert, update, or delete operation. Check to ensure that properties specified as binding expressions are available to the data source.
If I change Bind to Eval on the SelectedValue, the form submits fine but the MailingState property is not updated. How can I bind form controls to custom properties on my entity?
Though I would prefer a more declarative approach that doesn't involve handling events, this worked. I added an OnItemUpdating handler to the DetailsView, implemented as follows:
protected void dvOrg_ItemUpdating(object sender, DetailsViewUpdateEventArgs e)
{
var view = (DetailsView)sender;
var mailStateDdl = (DropDownList)view.FindControl("ddlMailingState");
e.NewValues["MailingState"] = mailStateDdl.SelectedValue;
}
In my .aspx, I had this:
<asp:DropDownList ID="ddlMailingState" runat="server" DataSourceID="ddlAllStates"
AppendDataBoundItems="True" DataTextField="StateAbbreviation"
DataValueField="StateAbbreviation"
SelectedValue='<%# Eval("MailingStateAbbreviation") %>'>
<asp:ListItem Value="" Text="" />
</asp:DropDownList>