cascading dropdownlist without reloading the page in asp.net - c#

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.

Related

Get value of a TextBox inside a DataList

I have a DataList in ASP.NET that brings me the products from the "Products" table, so with the "Eval" statement I assign the product ID:
<asp:TextBox ID="idProductoText" runat="server" type="hidden" value='<%# Eval("PRO_ID") %>'></asp:TextBox>
So in my C# code I need to get the value of that TextBox by its ID, for example an idProductText.Text.Trim(); , but for some reason it doesn't work, any solution? I leave the complete DataList below.
Code to fill the DataList:
public void loadStockProducts()
{
OracleConnection connection = new OracleConnection(with);
OracleCommand command = new OracleCommand("SHOW_PRODUCTS_BUY", connection);
command.CommandType = System.Data.CommandType.StoredProcedure;
command.Parameters.Add("registers", OracleDbType.RefCursor).Direction = ParameterDirection.Output;
OracleDataAdapter d = new OracleDataAdapter();
d.SelectCommand = command;
DataTable dt = new DataTable();
d.Fill(dt);
DataList1.DataSource = dt;
DataList1.DataBind();
connection.Close();
}
Full DataList in ASP.NET
<asp:DataList ID="DataList1" runat="server">
<ItemTemplate>
<div class="card mb-6" style="max-width: 1400px">
<div class="row g-0">
<div class="col-md-4">
<img
src="../../img/armchair.jpg"
class="img-fluid rounded-start"
alt="product" />
</div>
<div class="col-lg-5 m-4 form-floating">
<div class="card-body">
<!-- THE PRODUCT ID IS HIDDEN, IT WILL ONLY BE USED TO ADD TO CART -->
<asp:TextBox ID="idProductoText" runat="server" type="hidden" value='<%# Eval("PRO_ID") %>'></asp:TextBox>
<asp:Label ID="PRO_NAMELabel" class="card-title" runat="server" Text='<%# Eval("PRO_NAME") %>' Font-Bold="true" Font-Size="Large" Visible="True" />
<br />
<br />
Q<asp:Label ID="PRO_PRICELabel" class="card-text" runat="server" Text='<%# Eval("PRO_PRICE") %>' Font-Size="Large" />
<br />
<br />
<div class="input-group">
<asp:Button ID="moreInformation" runat="server" Text="More Information" class="btn btn-dark m-2" />
<asp:TextBox ID="quantidadBuy" runat="server" type="number" class="form-control m-2" placeholder="Quantity to Buy"></asp:TextBox>
<asp:Button ID="addCart" runat="server" Text="Add to Cart" class="btn btn-success m-2"/ OnClick="addCart_Click"/>
</div>
</div>
</div>
</div>
</div>
<br />
</ItemTemplate>
</asp:DataList>
Ok, while there are some events of the data list, you can just grab and get all the information you need/want from that button click you have.
However, before we write that code, I see you need a database row PK id, so, I suggest you remove this:
<!-- THE PRODUCT ID IS HIDDEN, IT WILL ONLY BE USED TO ADD TO CART -->
<asp:TextBox ID="idProductoText" runat="server"
type="hidden" value='<%# Eval("PRO_ID") %>'></asp:TextBox>
Assuming PRO_ID is the PK database id, then we really don't want to have that information in the markup - (even hidden).
So, use the so called "data keys" feature. You COULD leave the above, but remove it - we really don't need it.
So, in datalist, add this setting:
<asp:DataList ID="DataList1" runat="server" DataKeyField = "PRO_ID" >
Ok, so now the click event for the button.
Say we have this button:
<asp:Button ID="cmdView" runat="server" Text="View" CssClass="btn"
OnClick="cmdView_Click" />
Code behind:
protected void cmdView_Click(object sender, EventArgs e)
{
Button cmdView = sender as Button;
DataListItem gRow = cmdView.NamingContainer as DataListItem;
// get row index
Debug.Print("row click = " + gRow.ItemIndex.ToString());
// get database primary key (data keys)
int? PkID = DataList1.DataKeys[gRow.ItemIndex] as int?;
Debug.Print("Database PK id = " + PkID);
// get value of single control - say hotel label called
Label lHotelName = gRow.FindControl("HotelNameLabel") as Label;
Debug.Print("Hotel name = " + lHotelName.Text);
}
Output:
So note several things:
We grab/get current row - naming container. This works for Gridview, repeater, listview - quite much all of the data bound types of controls.
From that row, then we can get:
Row index -
From Row index, we reference into data keys. Note that datalist ONLY supports ONE data key, so in MOST cases, we have to do this .DataKeys[ some index]["SOME KEY"]
But datalist is a exception - only one key, so .DataKeys[some index] is all you require.
And to pull controls out, use .FindControl as I show above.
FYI: debug.print - this requires using System.Diagnostics;
(and I have my outputs re-directed to Immediate window).

Looping through RadioButtonList

I am creating a site that contains 3 surveys stored in one SQL table, so based on the selected SurveyID the page will then be populated by the Questions and an answer line, now I have achieved this but now I need to be able to retrieve the information.
Using a DataList, each question generates a line, and within the itemtemplate of my DataList (QuestionList) I have put the following:
<asp:DataList ID="QuestionList" runat="server" DataKeyField="QuestionID" DataSourceID="QuestionData">
<ItemTemplate>
<div class="col-md-12" id="hr">
<h3>
<asp:Label ID="Higher_ReadingLabel" runat="server" Text='<%# Eval("Higher_Reading") %>' /></h3>
</div>
<div class="col-md-12" id="lr">
<h3>
<asp:Label ID="Lower_ReadingLabel" runat="server" Text='<%# Eval("Lower_Reading") %>' /></h3>
</div>
<div class="col-md-12">
<asp:RadioButtonList ID="AnswerList" runat="server" RepeatDirection="Horizontal" RepeatLayout="Table">
<asp:ListItem Text="Excellent" Value="Excellent"></asp:ListItem>
<asp:ListItem Text="Very Good" Value="Very Good"></asp:ListItem>
<asp:ListItem Text="Good" Value="Good"></asp:ListItem>
<asp:ListItem Text="Fair" Value="Fair"></asp:ListItem>
<asp:ListItem Text="Bad" Value="Bad"></asp:ListItem>
</asp:RadioButtonList>
</div>
</ItemTemplate>
</asp:DataList>
When the submit button is clicked, I want to retrieve the following:
DataKeyField of the QuestionList
Value of Checked Radio Button within AnswerList
I admit I am pretty stumped atm, everything I have tried hasnt worked at all, as the SQL isnt wrote yet I just wanted to see if the output could just output using Response.Write(value,datakeyfield).
Hope you guys can help,
Neil
This may be helpfull for you:
foreach (DataListItem datalistItem in QuestionList.Items)
{
if (datalistItem.ItemType == ListItemType.Item || datalistItem.ItemType == ListItemType.AlternatingItem)
{
var radioButtonList = datalistItem.FindControl("AnswerList") as RadioButtonList;
if (radioButtonList != null)
{
var selectedRadioButtonValue = radioButtonList.SelectedValue;
var itemDataKeyValue = QuestionList.DataKeys[datalistItem.ItemIndex];
Response.Write(string.Format("QuestionID :{0}, selected option: {1} <br/>", itemDataKeyValue, selectedRadioButtonValue));
}
}
}

Text Boxes Not Populating from Database

Framework: ASP.NET 4.5 | Database: MSMMS
My demo application is supposed to populate textboxes with dynamic data when a selection is made from a dropdown list. I've added a button, that when pressed fires, an OnClick event that is supposed to assign values from the DB to the appropriate textboxes. Right now my code looks like:
protected void btnChoose_Click(object sender, EventArgs e)
{
API_DatabaseEntities1 db = new API_DatabaseEntities1();
var customer = (from c in db.Customers
where c.CustomerID == 4
select c).FirstOrDefault();
if (customer == null)
{
return;
}
if (ddlCustomer.SelectedValue == "Marisol") {
tbDescription.Text = customer.ToString();
tbFName.Text = customer.Fname;
tbSocial.Text = customer.SSN;
tbDOB.Text = customer.DOB.ToString();
tbFName1.Text = customer.Fname;
tbMName.Text = customer.Mname;
tbLName.Text = customer.Lname;
tbPrimaryPhone.Text = customer.PrimaryPhone;
tbSecondaryPhone.Text = customer.SecondaryPhone;
tbAdd1.Text = customer.Address;
tbCity.Text = customer.City;
tbZip.Text = customer.Zip;
tbEmail.Text = customer.Email;
tbMonLease.Text = customer.MortLeaseAmt;
tbEmployer.Text = customer.Employer;
tbPosition.Text = customer.Position;
tbHireDate.Text = customer.HireDate.ToString();
tbWorkPhone.Text = customer.WorkPhone;
tbGross.Text = customer.GrossIncome;
}
Debug.WriteLine(tbPosition.Text);
}
When the button is clicked, the page sends a request to the DB, but the textboxes remain blank. I am returning a value from the database, but it's not populating. Here is some code from my front page:
<form id="form1" runat="server">
<asp:DropDownList ID="ddlCustomer" runat="server" DataSourceID="SqlDataSource1" DataTextField="Fname" DataValueField="CustomerID"></asp:DropDownList>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:APIConnectionString %>" SelectCommand="SELECT [CustomerID], [Fname], [Lname] FROM [Customer] ORDER BY [Fname]"></asp:SqlDataSource><br /><br />
<asp:Button ID="btnChoose" runat="server" Text="Choose Test Case" OnClick="btnChoose_Click" /><br /><br />
Description of Goods and/or Services:<asp:TextBox ID="tbDescription" runat="server"></asp:TextBox><br /><br />
<div>
Membership #:<asp:TextBox ID="tbMembership" runat="server"></asp:TextBox> Ext.: <asp:TextBox ID="tbExt1" runat="server"></asp:TextBox>
First Name:<asp:TextBox ID="tbFName" runat="server"></asp:TextBox><br /> <br /><br />
Soc Sec No.: <asp:TextBox ID="tbSocial" runat="server"></asp:TextBox> Date of Birth:<asp:TextBox ID="tbDOB" runat="server" ></asp:TextBox>
</div><br /> <br />
I'm not sure if the problem is from the code behind or from the front page design. Any help would be appreciate. Thank you.
It looks like your code is checking for a selection in the drop-down list of the name "Marisol" - however, the "Value" field of the drop-down list is configured to use the CustomerID column. So this code populating the fields will never execute.
Maybe you should instead be using ddlCustomer.SelectedValue in the WHERE clause of your query.

Insert Query adding to database but not appearing in ListView after insert until page is refreshed

As part of a registration page, users can add their address, if they have not got an address the EmptyItemTemplate within my ListView control commands users to click a button outside of the ListView control to add an address which is shown below;
<asp:Button ID="add_new_address" CssClass="blue" runat="server" Text="Add New Address" OnClick="add_new_address_Click" />
<div id="add_address_div" runat="server">
<asp:DropDownList ID="address_dropdown_insert" runat="server">
<asp:ListItem Value="Home">Home Address</asp:ListItem>
<asp:ListItem Value="Term">Term Time Address</asp:ListItem>
<asp:ListItem Value="Mail">Mail Address</asp:ListItem>
<asp:ListItem Value="Business">Business Address</asp:ListItem>
</asp:DropDownList><br />
Address 1:
<asp:TextBox Text="" runat="server" ID="address_1TextBox" /><br />
Address 2:
<asp:TextBox Text="" runat="server" ID="address_2TextBox" /><br />
Town/City:
<asp:TextBox Text="" runat="server" ID="town_cityTextBox" /><br />
County:
<asp:TextBox Text="" runat="server" ID="countyTextBox" /><br />
PostCode:
<asp:TextBox Text="" runat="server" ID="postcodeTextBox" /><br />
Country:
<asp:TextBox Text="" runat="server" ID="countryTextBox" />
<asp:Button runat="server" CommandName="Insert" Text="Insert" ID="InsertButton" OnClick="insert_address_button_Click" />
<asp:Button runat="server" CommandName="Cancel" Text="Clear" ID="Button4" OnClick="cancel_address_button_Click" /><br />
</div>
I then have the following code behind in C# which inserts the data from the insert form above into a database table;
protected void add_new_address_Click(object sender, EventArgs e)
{
add_address_div.Visible = true;
add_new_address.Visible = false;
}
protected void insert_address_button_Click(object sender, EventArgs e)
{
string userid = Session["user_id"].ToString();
string addtype = address_dropdown_insert.SelectedValue;
string add1 = address_1TextBox.Text;
string add2 = address_2TextBox.Text;
string town = town_cityTextBox.Text;
string county = countyTextBox.Text;
string pcode = postcodeTextBox.Text;
string country = countryTextBox.Text;
string ConnectionString = WebConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
SqlConnection myConnection = new SqlConnection(ConnectionString);
myConnection.Open();
String query = "INSERT INTO address (user_id, address_type, address_1, address_2, town_city, county, postcode, country) VALUES (#user_id, #address_type, #address_1, #address_2, #town_city, #county, #postcode, #country)";
SqlCommand myCommand = new SqlCommand(query, myConnection);
myCommand.Parameters.AddWithValue("#user_id", userid);
myCommand.Parameters.AddWithValue("#address_type", addtype);
myCommand.Parameters.AddWithValue("#address_1", add1);
myCommand.Parameters.AddWithValue("#address_2", add2);
myCommand.Parameters.AddWithValue("#town_city", town);
myCommand.Parameters.AddWithValue("#county", county);
myCommand.Parameters.AddWithValue("#postcode", pcode);
myCommand.Parameters.AddWithValue("#country", country);
myCommand.ExecuteNonQuery();
myConnection.Close();
}
protected void cancel_address_button_Click(object sender, EventArgs e)
{
add_address_div.Visible = false;
}
This works, in that data is inserted into the database table as it should but after I click the insert_address_button, the data does not display in the ListView control, it only displays the EmptyItemTemplate. However, if I were to refresh the page the data then appear.
I am also working within View Controls so a normal refresh will bring the user back to the beginning of the registration process and would prefer they would be redirected back to the View control for the Address'.
Is there a step in the process I am missing after the insert so that the data displays in the list view? Any help would be greatly appreciated.
Yes, you need to rebind the ListView's datasource. It's still got the "old" version.
You need the list to update asynchronously from the page when an address is added. You can either have it re-load via Ajax or you can have a javascript function add the address that is being sent to the server side code to the list.

Populate asp:dropdownlist - VS 2008

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.

Categories