How to populate a dropdown list in asp.net from a DB table? - asp.net

I want to populate a dropdown list with values from a table I created. I only want to populate the list with one of the fields- the languages in my table. I think I have connected to the data source correctly, but I don't know what I have to do to get the values into the list. I can enter my own values but I'd rather have this automated.
This is what I have so far, but I'm guessing there's more to it than just linking the list to the data source.
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:HBshareIndexConnectionString %>"
SelectCommand="SELECT * FROM [Web_Metrics] WHERE ([LCID] = #LCID)">
<SelectParameters>
<asp:QueryStringParameter Name="LCID" QueryStringField="LCID" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
<asp:Label ID="Label1" runat="server" Text="Select LCID: " ></asp:Label>
<asp:DropDownList ID="DropDownList1" Width="150px" runat="server" DataSourceID="SqlDataSource1" DataTextField="LCID" DataValueField="LCID">
<asp:ListItem>Select LCID...</asp:ListItem>
</asp:DropDownList>
Thanks for the help. I got the dropdown list populated now, but I was wondering how do I actually get the repeater I'm using to display the details of the LCID the person selects? I've seen people talking about page.isPostback but I don't know what that is or if it works with my current setup. I need to somehow get the LCID they selected and then refresh the page to show the details of that LCID. Does anyone have any ideas?

Your problem is that you're trying to define list items and a data source.
If you want to insert a "Select an item.." option, I would suggest prepending it to your resultset (getting it to always be first with a UNION and ORDER BY could be difficult depending on your fields) or inserting it after databinding in your code behind:
Modification to DropDownList1s attributes:
<asp:DropDownList ID="DropDownList1" Width="150px" runat="server" DataSourceID="SqlDataSource1" DataTextField="CountryName" DataValueField="LCID" OnDataBound="InsertChooseItem" />
C#:
protected void InsertChooseItem(object sender, EventArgs e)
{
ListItem selectOnePlease = new ListItem("Select LCID..", 0);
DropDownList1.Items.Insert(0, selectOnePlease);
}
VB:
Protected Sub InsertChooseItem(sender As Object, e As EventArgs)
Dim selectOnePlease As New ListItem("Select LCID..", 0)
DropDownList1.Items.Insert(0, selectOnePlease)
End Sub

You've specified the select parameter to be a query string, so the data in your DropDownList will only be populated when the URL resembles something like:
http://{Your server name}/Default.aspx?LCID=1
That doesn't make any sense though because the LCID column in your table should be unique, so although this will work there will only be one value in the drop down list.
I think what you want is to display all the languages from the database in the drop down, here's an example:
<asp:SqlDataSource ID="sqlDS" runat="server"
ConnectionString="<%$ ConnectionStrings:HBshareIndexConnectionString %>"
SelectCommand="SELECT LCID,Language FROM [Web_Metrics]">
</asp:SqlDataSource>
<asp:DropDownList ID="ddlLanguages" AppendDataBoundItems="true" Width="150px" runat="server" DataSourceID="sqlDS" DataTextField="Language" DataValueField="LCID">
<asp:ListItem>Select Language</asp:ListItem>
</asp:DropDownList>
Just a note, you should never display the ID to the client, it's totally meaningless to them, the ids are mostly used by developers in the background that's why in the drop down I set the:
DataTextField="Language" (This is the language name visible to the user)
DataValueField="LCID" (Not visible to the user, but useful for any additional processing in code behind)
AppendDataBoundItems="true" - this line of code will keep all the items you've manually added to the drop down, e.g "Select Language" and will append any data bound items e.g from a SQL table

Related

Cannot change SelectCommand contents dynamically

I am having an issue trying to change SelectCommand contents dynamically.
There is this Telerik searchbox control that uses SQLDataSource to constantly bang the DB with a select query and show up a list of words filtered by your typing. Then if you pick an entry from the list it will become a "token" and then you can start typing again.
In my case, the query should return a list of car makes and the initial query is:
SELECT DISTINCT mfrname
FROM Manufacturers
WHERE mfrname IS NOT NULL
ORDER BY mfrname
So if I type "Che" it will show up "Checker" and "Chevrolet". So if I click "Chevrolet" it will become a token and my typing is reset so I can start typing again.
For tests purposes after the token is generated I slighted changed my query to:
SELECT DISTINCT mfrname
FROM manufacturers
WHERE mfrname IS NOT NULL and mfrname like 'm%'
ORDER BY mfrname
Notice that now it should only select the car makes started with an "M" like "Mercedes", "Maseratti", etc, so if I type anything else that doesn't starts with an "M" it shouldn't show anything.
However if I type "Che" there it is "Checker" and "Chevrolet" again, making it clear that it's still using the initial query and not the new one.
OKay, I know that the event IS being triggered and the SelectCommand value IS being changed (I know this because I added a label that changes and shows up the new value). What I don't know is why the control insists on keep using the old query and not the new one! Any idea?
My code front:
<form id="form1" runat="server">
<telerik:RadScriptManager runat="server" ID="RadScriptManager1" />
<telerik:RadAutoCompleteBox RenderMode="Lightweight" runat="server" ID="RadAutoCompleteBox1" autopostback="true" EmptyMessage="Type in car make..."
DataSourceID="SqlDataSource1" DataTextField="mfrname" InputType="Token" Width="450" DropDownWidth="150px" OnEntryAdded="RadAutoCompleteBox1_EntryAdded" >
</telerik:RadAutoCompleteBox>
<asp:SqlDataSource runat="server" ID="SqlDataSource1" CancelSelectOnNullParameter="false" ConnectionString="<%$ ConnectionStrings:MyConn %>" SelectCommand="SELECT DISTINCT mfrname FROM Manufacturers WHERE mfrname IS NOT NULL ORDER BY mfrname">
</asp:SqlDataSource>
<div>
<br />
<asp:label id="label1" runat="server">Waiting for update...</asp:label>
</div>
</form>
My code behind:
Protected Sub RadAutoCompleteBox1_EntryAdded(sender As Object, e As Telerik.Web.UI.AutoCompleteEntryEventArgs)
SqlDataSource1.SelectCommand = "SELECT DISTINCT mfrname FROM manufacturers WHERE mfrname IS NOT NULL and mfrname like 'm%' ORDER BY mfrname"
RadAutoCompleteBox1.DataBind()
label1.Text = e.Entry.Text + " was added. (" + SqlDataSource1.SelectCommand + ")"
End Sub
I found the solution. Well, more like a work around but it works.
In my case I didn't need to change entirely the query, but actually only the WHERE clause. So I added a dynamic parameter to the query text and tied it to another control (an invisible label) forcing the AutoCompleteBox to always look into the contents of the label before to run the query.
This way, changing the contents of the label will change the parameter used in my WHERE clause and so I can control the query. It may be expanded by simply adding more parameters to the SQLDataSource and adding additional invisible controls to the page.
So here it goes the implemented solution since it may be of help for someone else...
Code front:
<form id="form1" runat="server">
<telerik:RadScriptManager runat="server" ID="RadScriptManager1" />
<telerik:RadAutoCompleteBox RenderMode="Lightweight" runat="server" ID="RadAutoCompleteBox1" autopostback="true" EmptyMessage="Type in car make..." DataSourceID="SqlDataSource1" DataTextField="mfrname" InputType="Token" Width="450" DropDownWidth="150px" OnEntryAdded="RadAutoCompleteBox1_EntryAdded" >
</telerik:RadAutoCompleteBox>
<asp:SqlDataSource runat="server" ID="SqlDataSource1" CancelSelectOnNullParameter="false" ConnectionString="<%$ ConnectionStrings:MyConn %>" SelectCommand="SELECT DISTINCT mfrname FROM Manufacturers WHERE mfrname like #mypar and mfrname IS NOT NULL ORDER BY mfrname">
<SelectParameters>
<asp:ControlParameter ControlID="lblSQLpar" Name="mypar" PropertyName="Text" />
</SelectParameters>
</asp:SqlDataSource>
<div>
<!-- initial value -->
<asp:label id="lblSQLpar" runat="server" Visible="false">%</asp:label>
</div>
</form>
code behind:
Protected Sub RadAutoCompleteBox1_EntryAdded(sender As Object, e As Telerik.Web.UI.AutoCompleteEntryEventArgs)
'Use CASE structure to change the parameter accordingly to your needs
lblSQLpar.Text = "m%"
End Sub

Databound Child Master Dropdownlist

Ok, I give up, I need your help. I thought this'd be simple!
In this scenario, Departments belong to Institutions. In my SQL database, it's a one-to-many relationship. People belong to both Departments and Institutions. I'm writing a page which allows the editing of a Person's details, where the Departments to which they can belong are restricted according to the Institution to which they belong. For example, if the HR Department is part of Institution A and the Finance Department is part of Institution B, if the Person is in Institution A they cannot belong to the Finance Department unless you first move them to Institution B.
I've got two dropdownlists in a FormView for editing the person's details - ddlEditInstitution and ddlEditDepartment. Quite simply, when the FormView first enters Edit mode, I want these two dropdownlists to show the Institution and Department to which that Person currently belongs. If you click on the Department dropdownlist you will only be able to choose from Departments belonging to that Institution. If you change the Institution in ddlInstitution, the available options in ddlDepartment should refresh to only show Departments belonging to the newly-selected Institution.
Right, some code. Here's my mark-up for the dropdownlists:
<tr>
<td class="fieldlabel">Institution</td>
<td><asp:DropDownList ID="ddlEditInstitution" runat="server" DataTextField="Name" DataValueField="ID" DataSourceID="SQLInstitution" SelectedValue='<%# Bind("InstitutionID")%>' CssClass="contactdetailseditfield"
AutoPostBack="True" OnSelectedIndexChanged="ddlEditInstitution_SelectedIndexChanged" /></td>
<asp:SqlDataSource ID="SQLInstitution" runat="server" ConnectionString="<%$ ConnectionStrings:ContactsConnectionString %>"
SelectCommand="SELECT * FROM [Institution] WHERE ([Deleted] = 0)" />
</tr>
<tr>
<td class="fieldlabel">Department</td>
<td><asp:UpdatePanel ID="upDepartment" runat="server" UpdateMode="conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ddlEditInstitution" EventName="SelectedIndexChanged" />
</Triggers>
<ContentTemplate>
<asp:DropDownList ID="ddlEditDepartment" runat="server" DataTextField="Name" DataValueField="ID" DataSourceID="SQLDepartment" CssClass="contactdetailseditfield" />
<asp:SqlDataSource ID="SQLDepartment" runat="server" ConnectionString="<%$ ConnectionStrings:ContactsConnectionString %>"
SelectCommand="SELECT * FROM [Department] WHERE ([Deleted] = 0) AND (Institution = #InstitutionID)">
<SelectParameters>
<asp:ControlParameter ControlID="ddlEditInstitution" PropertyName="SelectedValue" Name="InstitutionID" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
</ContentTemplate>
</asp:UpdatePanel></td>
</tr>
And here's the code behind:
Protected Sub ddlEditInstitution_SelectedIndexChanged(sender As Object, e As EventArgs)
ddlEditDepartment.SelectedValue = Nothing
ddlEditDepartment.Items.Clear()
ddlEditDepartment.DataBind()
ddlEditDepartment.Items.Insert(0, New ListItem("--Select a department--", "-1"))
ddlEditDepartment.SelectedIndex = 0
End Sub
This almost works perfectly. The problem is that when the FormView first enters Edit mode, ddlEditDepartment does not display the Person's current Department, it displays the first Department in the dropdownlist's items. This makes sense - I haven't set the SelectedValue of ddlEditDepartment. However, if I do so (as I did originally, when I thought this would be easy) by adding the property to ddlEditDepartment in the page mark-up, like so...
SelectedValue = '<%# Bind("DepartmentID")%>'
... then what happens is that if you select a different option from ddlInstitution, the databound items for ddlDepartment don't update. They continue to be the options linked to the old Institution. Presumably this is because the SelectedValue property of ddlEditDepartment is overriding everything else - the dropdownlist is bound to that column no matter what, it seems.
I've tried getting around this every which way I can think of, by manually changing the SelectedValue of ddlEditDepartment in code behind when changing ddlEditInstitution, by trying to set the SelectedValue of ddlEditDepartment in code behind to the Person's current Department when the FormView first enters Edit mode rather than explicitly... But nothing works.
I hate dropdownlists in ASP.NET. Can anybody tell me how to achieve what seems like a relatively simple effect?
Finally figured out a way to do this. In the DataBound event of the FormView, if it's in Edit Mode, I manually get the Person's current Department and set ddlEditDepartment to that value.
Protected Sub fvContactDetails_DataBound(sender As Object, e As EventArgs) Handles fvContactDetails.DataBound
Dim dept As Integer = DataBinder.Eval(fvContactDetails.DataItem, "DepartmentID")
If fvContactDetails.CurrentMode = FormViewMode.Edit Then
ddlEditDepartment.SelectedValue = dept
End If
End Sub

How to set initial value as Select in the dropdown of asp.net page that is databound with sql statement

I am binding a dropdown for location with a select statment
Select location_id, location_name,businessid from inventory.tbl_location order by location_name
I want to put the first element as 'Select location'. Right now I am getting all locations. How to set initial value as Select in the dropdown of asp.net page that is databound with sql statement?
In the aspx page :
<asp:DropDownList ID="ddlAllLocations" runat="server" DataSourceID="SqlDataSourceBusinessLocations"
DataTextField="Location_Name" DataValueField="Location_ID" AutoPostBack="True">
</asp:DropDownList>
And
<asp:SqlDataSource ID="SqlDataSourceBusinessLocations" runat="server" ConnectionString="<xxxxxx>"
ProviderName="<%$ zzzzz %>" SelectCommand="Select location_id, location_name,businessid from inventory.tbl_location order by location_name" FilterExpression="businessid in ({0})">
<FilterParameters>
<asp:SessionParameter DefaultValue="0" Name="BUID" SessionField="BusinessUnitIDs" />
</FilterParameters>
</asp:SqlDataSource>
I added the code as suggested in the page_load event, here is another problem, everytime it is adding select location to the list items
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If IsPostBack() Then
lblError.Text = ""
ddlAllLocations.Items.Insert(0, New ListItem("Select location"))
End If
End Sub
Try this:
<asp:DropDownList ID="ddlAllLocations" runat="server"
DataSourceID="SqlDataSourceBusinessLocations"
DataTextField="Location_Name"
DataValueField="Location_ID"
AutoPostBack="True"
AppendDataBoundItems="True">
<asp:ListItem value="" selected="True">
Select
</asp:ListItem>
</asp:DropDownList>
Don't forget the AppendDataBoundItems attribute. Be careful using this in an update panel: each update will re-append all the items and you'll end up with duplicates. In that case, you might be able to fix it by disabling ViewState for the control.
Not sure how you do the databinding but I hope you're doing it in code-behind...
In that case it's pretty straighforward:
mydroplist.DataSource = someSource;
mydroplist.DataBind();
mydroplist.Items.Insert(0, new ListItem("Select location"));
edit based on your edit:
it's not a good idea to have SQL in your UI.. That's a very bad design. Do some research on proper programming architectures, how to separate layers etc. Then you will do the databinding in code-behind and my sample will help you.
If you insist on using your way of doing things, you can simply wire up the event when the dropdownlist is databound and add this piece of code (except the binding part of course)

Duplicate items in dropdownlist!

Ok I really hope you guys can help me with this, I've spent the past 2 days trying to figure it out and I think I'm about to throw my computer out the window, so I thought I might as well ask here first:
I'm designing a web page with two dropdownlists, one for the Make of a car, the other for the Model, both bound to a database with separate SQLDataSources, and using a distinct statement. I add "All" at the top of both by setting appendDataBoundItems = true and adding items named all. Then when I fill the Make with a querystring all the model items get added twice (but only the databound items).
Here's my code:
<asp:DropDownList ID="DropDownMake" runat="server"
DataSourceID="SqlMakes" DataTextField="Make" DataValueField="Make"
AppendDataBoundItems="True" EnableViewState="False" AutoPostBack="True">
<asp:ListItem Selected="True" Value="All">All</asp:ListItem>
</asp:DropDownList>
<asp:DropDownList ID="DropDownModel" runat="server"
AppendDataBoundItems="True" AutoPostBack="True" DataSourceID="SqlModels"
DataTextField="Model" DataValueField="Model" EnableViewState="False">
<asp:ListItem>All</asp:ListItem>
</asp:DropDownList>
<asp:SqlDataSource ID="SqlMakes" runat="server"
ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
SelectCommand="SELECT DISTINCT [Make] FROM [Parts]">
</asp:SqlDataSource>
<asp:SqlDataSource ID="SqlModels" runat="server"
ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
SelectCommand="SELECT DISTINCT [Model] FROM [Parts] WHERE ([Make] = #Make)">
<SelectParameters>
<asp:ControlParameter ControlID="DropDownMake" Name="Make"
PropertyName="SelectedValue" />
</SelectParameters>
</asp:SqlDataSource>
'And in the VB file:
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
DropDownMake.SelectedValue = Request.QueryString("Make")
DropDownModel.SelectedValue = Request.QueryString("Model")
End Sub
If I remove the line "DropDownMake.SelectedValue = Request.QueryString("Make")" it doesnt produce duplicates anymore. What is going on?? I swear I've spent more time developing entire iphone apps, if anyone helps figure this out I think I'm going to have to make an award for you.
Thank you!!
I think your databind method might be fired twice. Have you tried to set appendDataBoundItems=false and then attach an event handler for the OnDataBound event and insert your top item in the event handler instead?
protected void yourDdlControl_DataBound(object sender, EventArgs e)
{
if (yourDdlControl.Items.Count > 0)
{
yourDdlControl.Items.Insert(0, "All");
yourDdlControl.Items[0].Value = "";
yourDdlControl.SelectedIndex = 0;
}
}
}
Ok, so that is c# code, but you should be able to translate it :). Also, you can set the selected value in the DataBound instead based on the existence of your query parameters.
Put your code inside not postback i.e.
If Not Page.IsPostBack Then
DropDownMake.SelectedValue = Request.QueryString("Make")
DropDownModel.SelectedValue = Request.QueryString("Model")
End If

How do I data bind a drop down list in a gridview from a database table using VB?

So in this gridview, there is a column for status and I want to have a drop down list with Pass, Pending, Fail appear when the edit button is clicked. These values are already in a table, so I need to somehow bind from this table to each ddl for every row.
Here is the column from the gridview. As you can see, I would like to just have a label showing when not in edit mode, and a ddl when the edit button is pressed
<asp:TemplateField HeaderText="During Production Status" SortExpression="DuringProductionStatus">
<EditItemTemplate>
<asp:DropDownList ID="ddlStatus" runat="server" datavaluefield="Name"
datatextfield="Name" DataSource="*What goes here?*"> />
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblStatus" runat="server"
Text='I don't understand how to get this from the ddl' />
</ItemTemplate>
</asp:TemplateField>
For clarity's sake, my table is named Status, and the database is named DirectImport
There's a few steps to go through here - none of them are particularly difficult, but they can be a bit fiddly (IMHO). The good news is once you've got this working once, it gets easier to do it again!
I'm assuming you've got a <asp:*DataSource> control on your page - my preference is for an ObjectDataSource but I don't think it matters, I think a SqlDataSource works equally well. I've never tried doing this with GridView.DataSource = MyDataSet in code-behind, so I don't know whether that would work or not, but my assumption is that it wouldn't as you wouldn't get the proper two-way binding that you want. This data source feeds your grid with your main data. The key point here is that your database query must return both the Status text field and the Status id.
So your gridview will now look something like:
<asp:objectdatasource runat="server" id="MainDataSource" ... />
<asp:gridview runat="server" id="MyGridView" DataSourceID="MainDataSource">
<Columns>
<asp:TemplateField HeaderText="During Production Status" SortExpression="DuringProductionStatus">
<ItemTemplate>
<asp:Label ID="lblStatus" runat="server"
Text="<%# Bind('Status') %>" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:gridview>
The Text="<%# Bind('Status') %>" is the bit you're missing to get the status text into the grid.
Now add a second data source into your markup that reads in the set of values from the Status table.
<asp:objectdatasource runat="server" id="StatusObjectDataSource" ... />
And add the EditItemTemplate into the GridView, which is bound to the Status DataSource.
<EditItemTemplate>
<asp:DropDownList ID="ddlStatus" runat="server" datavaluefield="StatusID"
datatextfield="Status" DataSourceID="StatusObjectDataSource"
SelectedValue="<%# Bind('StatusId') %>" />
</EditItemTemplate>
The SelectedValue="<%# Bind('StatusId') %>" is what connects up the two datasets so that when you flip a row into Edit mode, the dropdownlist has the correct item already selected, and when you then save it you've got the Status ID to put into your database.
And you're done.
I have used the RowDataBound event. Here is a small code snippet. HTH
you would have an ItemTemplate in your aspx/ascx
<asp:TemplateField HeaderText="Column Headings">
<ItemTemplate>
<asp:DropDownList ID="ddlName" runat="server" Width="150"></asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
and in your code behind, you will have
protected void grdDataMap_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddl = (DropDownList)e.Row.FindControl("ddlName");
ddl.DataSource = someList;//the source of your dropdown
ddl.DataBind();
}
}
so when you bind your grid with grdDataMap.Databind (assuming your grid id is grdDataMap), row databound event will be called for each row (including header/footer, and thats the reason you check RowType)
so you can probably decide what controls/columns to hide/show/bind inside this row databound event
In the winforms world I pull my objects from the DB into a List(Of Whatever) and use the list as the datasource.
This also lets me add extra "convenience" fields in the object so that I can populate it with stuff from other tables.
I don't know asp.net at all so if you can do something similar, it might help.
A really quick solution is to create a custom web control for the status dropdown. The control will always contain the same data. When it renders you populate the datasource. When it gets added to the gridview, the data will be in the drop down. Hope that helps!

Resources