asp.net dropdownlist - add blank line before db values - asp.net

On my page I have a DropDownList which I populate with database values from an SqlDataSource (see code below).
How can I add my own text or a blank line before the values?
<asp:DropDownList ID="drpClient" runat="server" Width="200px"
AutoPostBack="True" DataSourceID="dsClients" DataTextField="name"
DataValueField="client_id">
</asp:DropDownList>
<asp:SqlDataSource ID="dsClients" runat="server"
ConnectionString="my_connection_string"
ProviderName="System.Data.SqlClient"
SelectCommand="SELECT [client_id], [name] FROM [clients]">
</asp:SqlDataSource>
Thanks.
P.S. Do you recommend using a SqlDataSource or is it better to populate another way?

You can simply add a ListItem inside the DropDownList Markup. All the values from the DataSource will be appended after that.
<asp:DropDownList ID="drpClient" runat="server" Width="200px"
AutoPostBack="True" DataSourceID="dsClients" DataTextField="name"
DataValueField="client_id" AppendDataBoundItems="true">
<asp:ListItem>-- pick one --</asp:ListItem>
</asp:DropDownList>

<asp:DropDownList ID="drpClient" runat="server" Width="200px"
AutoPostBack="True" DataSourceID="dsClients" DataTextField="name"
DataValueField="client_id" AppendDataBoundItems="True">
<asp:ListItem Text="" Value="" />
</asp:DropDownList>
It's easy to miss, so don't forget the AppendDataBoundItems attribute I added.

I haven't really tested this but I'm assuming that you could add an item after you have binded the the drop down list. You could add this event to any dropdown list you'd like to add this empty box to.
protected void DropDownList_DataBound(object sender, EventArgs e)
{
DropDownList ddl = (DropDownList)sender;
ListItem emptyItem = new ListItem("", "");
ddl.Items.Insert(0, emptyItem);
}

I solve changing the select command adding an empty option:
<asp:SqlDataSource ID="dsClients" runat="server"
ConnectionString="my_connection_string"
ProviderName="System.Data.SqlClient"
SelectCommand="SELECT [client_id], [name] FROM [clients] union SELECT NULL, '--- pick one ----' ">
</asp:SqlDataSource>
Greetings!!!

In razor-style implementation at me it looks like this:
#Html.EnumDropDownListFor(
model => model.Privilege.Role,
"-- Select role --",
new
{
#style = "width: 216px !important",
#class = "form-control",
id = "role",
required = "required"
})
And in javascript which is executed on load I have this:
function PutDefaultPrivilegePanelListHints() {
$('#role').val('');
...
}
There is also more flexible solution via unobtrusive validation (not to count on HTML5):
$('.required').each(function () { $(this).rules('add', { required: true, messages: { required: '' } }) });
Of course, there is a server-side check, too.
I don't think it's a good idea to cope with classes.
For instance, everything I show in the page is some class. This class has several enumerable type properties. It would be a nightmare to replicate all those properties, but making them nullable in some additional class as some ones suggested here on stackoverflow.
After all, why should i change my business logic for the sake of some specific markup? Instead, I deal with everything via javascript and some model checks.

Related

ASP.Net 4.5 Model Binding Cascading Drop Downs Null Reference (web Forms)

I'm retrofitting an older web forms site with Model Binding using asp.net 4.5.
In a DetailsView I have a drop down list that allows selection of a particular 'client' and another that allows selection of a particular 'project' that belongs to that client. So the drop down for project has to be filtered on the client number and if the user changes the client selection, I want to filter the project list by client number.
I couldn't figure out how to get the SelectedIndexChanged method on the client ddl to fire the Select method for the Project, so I concluded the only way to do it was to filter the project ddl by client number in all cases. I am getting an error message when the client selection is made:
NullReferenceException was Unhandled by User Code
which point in my aspx directly to the ddl for Projects.
This is an abbreviated version of the details view, you can see both the clients ddl and the projects ddl (I am operating in Edit mode):
<asp:DetailsView ID="AdministratorDetailsView" runat="server" AutoGenerateRows="False"
DataKeyNames="AdministratorNumber" ItemType="BusinessLogic.Administrator"
Width="99%"
SelectMethod="AdministratorDetailsView_GetItem"
UpdateMethod="AdministratorDetailsView_UpdateItem"
DeleteMethod="AdministratorDetailsView_DeleteItem"
FieldHeaderStyle-Width="30%" EditRowStyle-Width="99%"
InsertRowStyle-Width="70%" RowStyle-Width="99%" CssClass="admin"
AutoGenerateDeleteButton="true" AutoGenerateEditButton="true" >
<Fields>
<asp:TemplateField HeaderText="AdministratorCode" SortExpression="AdministratorCode">
<EditItemTemplate>
<asp:Label ID="AdministratorCode" Text="<%# Item.AdministratorCode%>" runat="server" />
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="AdministratorCode" Text="<%# Item.AdministratorCode%>" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="ClientNumber" SortExpression="ClientNumber">
<EditItemTemplate>
<asp:DropDownList ID="ddClients" runat="server"
AutoPostBack="true"
DataTextField="ClientName" DataValueField="ClientNumber"
ItemType="BusinessLogic.Client"
SelectMethod="ddClients_GetList"
SelectedValue="<%# Item.ClientNumber%>"
OnSelectedIndexChanged="AdministratorDetailsView_ddlClients_SelectedIndexChanged"/>
</EditItemTemplate>
<ItemTemplate>
<asp:DropDownList ID="ddClients" runat="server" Enabled="false"
DataTextField="ClientName" DataValueField="ClientNumber"
ItemType="BusinessLogic.Client"
SelectMethod="ddClients_GetList"
SelectedValue="<%# Item.ClientNumber%>"/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Projects" >
<EditItemTemplate>
<asp:DropDownList ID="ddProjects" runat="server" AutoPostBack="true"
DataTextField="ProjectName" DataValueField="ProjectNumber"
ItemType="BusinessLogic.Project"
SelectMethod="ddProjects_GetList"
SelectedValue="<%# Item.ProjectNumber%>" />
</EditItemTemplate>
<ItemTemplate>
<asp:DropDownList ID="ddProjects" runat="server" Enabled="false"
DataTextField="ProjectName" DataValueField="ProjectNumber"
ItemType="BusinessLogic.Project"
SelectMethod="ddProjects_GetList"
SelectedValue="<%# Item.ProjectNumber%>"/>
</ItemTemplate>
</asp:TemplateField>
</Fields>
</asp:DetailsView>
There are two SelectMethods, one for each drop down list, and a selectedindexchaneged method for clients:
Public Function ddClients_GetList() As List(Of BusinessLogic.Client)
Dim special As New List(Of Client)
special = CurrentClient.ClientList() 'add whole list
Dim NullClient As New Client()
NullClient.Load(0)
NullClient.ClientName = "<-Not Selected-->"
special.Add(NullClient) 'Had to have a client with 0 in the list since most admins don't have anything but 0 inthis field
Return special
End Function
Public Function ddProjects_GetList(<Control("ddClients")> ByVal ClientNumber As Integer) As List(Of BusinessLogic.Project)
Dim special As New List(Of Project)
If ClientNumber = 0 Then
special = CurrentProject.ProjectList() 'add whole list, refine it if Clients Drop Down selected
Else
special = CurrentProject.ProjectList(ClientNumber) 'add whole list, refine it if Clients Drop Down selected
End If
Dim NullProject As New Project()
NullProject.Load(0)
NullProject.ProjectName = "<-Not Selected-->"
special.Add(NullProject) 'Had to have a Project with 0 in the list since most admins don't have anything but 0 inthis field
Return special
End Function
Protected Sub AdministratorDetailsView_ddlClients_SelectedIndexChanged(sender As Object, e As EventArgs)
Dim ddlProj As DropDownList
ddlProj = AdministratorDetailsView.FindControl("ddProjects")
ddlProj.ItemType = "BusinessLogic.Project"
ddlProj.DataBind()
End Sub
All is well until the user selects a different client which triggers the SelectIndexChanged event and then we get to the DataBind(), where we get the null exception (ddlProj is found).
Need some ideas on how to refresh the projects list based on the new client selection.
How do I force ddProjects to run its SelectMethod again, to avoid the null reference and reload the control?
Turns out this issue is not unique to ModelBinding, but is a General WebForms Issue.
You cannot have cascading dropdowns within another data control where they depend on each other unless you add a bit of code.
In my case, I was trying to bind both dropdowns to the underlying detailsview, and at the same time setting the selected values. Doesn't work because of timing. It seems right until you try to change the selection on the parent dropdown, and then you get null exception on the second because it is not yet loaded. It's all timing. If you try to work around it with saved values, it gets too messy.
My solution is, Bind another item to the underlying details view (you can make it hidden if you wish). Then add some code to keep it in sync with the actual value. DO NOT Bind SelectedValue on the secondary drop down , this is what causes the problem. Manage Selected Value in code using the added field.
<asp:DetailsView ID="AdministratorDetailsView" runat="server" AutoGenerateRows="False"
DataKeyNames="AdministratorNumber" ItemType="BusinessLogic.Administrator"
Width="99%" SelectMethod="AdministratorDetailsView_GetItem" UpdateMethod="AdministratorDetailsView_UpdateItem" DeleteMethod="AdministratorDetailsView_DeleteItem"
FieldHeaderStyle-Width="30%" EditRowStyle-Width="99%" InsertRowStyle-Width="70%" RowStyle-Width="99%" CssClass="admin" AutoGenerateDeleteButton="true" AutoGenerateEditButton="true"
>
<Fields>
<asp:TemplateField HeaderText="Client Name" SortExpression="ClientName">
<EditItemTemplate><asp:DropDownList ID="ddClients" runat="server" AutoPostBack="true" DataTextField="ClientName" DataValueField="ClientNumber" ItemType="BusinessLogic.Client" SelectMethod="ddClients_GetList" SelectedValue="<%# Item.ClientNumber%>" OnDataBound="ddClients_DataBound" OnSelectedIndexChanged="AdministratorDetailsView_ddlClients_SelectedIndexChanged" /> </EditItemTemplate>
<ItemTemplate><asp:DropDownList ID="ddClients" runat="server" Enabled="false" DataTextField="ClientName" DataValueField="ClientNumber" ItemType="BusinessLogic.Client" SelectMethod="ddClients_GetList" SelectedValue="<%# Item.ClientNumber%>"/></ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText ="Project Number" >
<EditItemTemplate><asp:Label ID="ProjectNumberLabel" runat="server" Text="<%# BindItem.ProjectNumber%>"></asp:Label></EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Project Name" SortExpression="ProjectNumber">
<EditItemTemplate><asp:DropDownList ID="ddProjects" runat="server" AutoPostBack="true" DataTextField="ProjectName" DataValueField="ProjectNumber" ItemType="BusinessLogic.Project" SelectMethod="ddProjects_GetList" OnDataBound="ddProjects_DataBound" OnSelectedIndexChanged="ddProjects_SelectedIndexChanged" />
</EditItemTemplate>
<ItemTemplate><asp:DropDownList ID="ddProjects" runat="server" Enabled="false" DataTextField="ProjectName" DataValueField="ProjectNumber" ItemType="BusinessLogic.Project" SelectMethod="ddProjects_GetList" SelectedValue="<%# Item.ProjectNumber%>" />
</ItemTemplate>
</asp:TemplateField>
</asp:DetailsView>
And in the code behind, not how we set and get the value of the bound projectnumber:
Protected Sub AdministratorDetailsView_ddlClients_SelectedIndexChanged(sender As Object, e As EventArgs)
''If this selection changes we need to change some flags and perhaps theProject ddl
''This causes null exception for Project ddl, can't figure out how to get it to reload. Tried DataBind(), same effect as having a ValueProvider in the parameters to the Select
Dim ProjectNumberLabel As Label = AdministratorDetailsView.FindControl("ProjectNumberLabel")
ProjectNumberLabel.Text = "0" 'Synchronize to no selection
Dim ddProjects As New DropDownList
ddProjects = AdministratorDetailsView.FindControl("ddProjects") 'Have to use Find Control because ddl is buried in DetailsView
ddProjects.SelectedValue = 0 'Cause it to read Select an Item
ddProjects.DataBind() 'Rebinding it causes the SelectMethod to run.
End Sub
Protected Sub ddProjects_DataBound(sender As Object, e As EventArgs)
'Because of the problem with cascading references, we had to remove the SelectValue declaration from ddProjects.
'So we must make sure that once theddProjects is databound, it points to the selected value from the data
Dim ddlProjects As DropDownList
ddlProjects = AdministratorDetailsView.FindControl("ddProjects")
Dim ProjectNumberLabel As Label = AdministratorDetailsView.FindControl("ProjectNumberLabel")
ddlProjects.SelectedValue = CInt(ProjectNumberLabel.Text)
End Sub
Hope someone else sees this as useful. I couldn't find it anywhere.
Great posting, as I faced a similar conundrum and it made me think. I have done this before outside of the model-binding approach, and the solution is essentially the same, as described. I used a ListView, and added the method:
OnItemDataBound="lvWhatever_ItemDataBound"
to fire an event from which to go and get the relevant ID from another bound control in the list view data item:
if (e.Item.ItemType == ListViewItemType.DataItem)
{
// get the ID from from another control in this item record: lblItemID
ListViewDataItem lvdi = (ListViewDataItem)e.Item;
if (lvdi != null)
{
Label iID = (Label)lvdi.FindControl("lblItemID");
if (iID != null)
where lblItemID.Text contains the relevant ID. Then from that I can query to get the relevant list, and manually bind it to the DDL. Brilliant - thanks very much.

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

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

ASP.NET DropDownList bound to data but allows for nulls?

I'm using LINQ to SQL and want to be able to select a parent or no parent. Let's say I have a People table with PersonId, Name and ParentId columns. In ASP I want to enter the name, select a parent and click 'Add' to create a new Person record, but I also want to be able to leave the ParentId null. Don't ask why, this is just a simplified explanation for what I want to do.
<asp:LinqDataSource ID="LinqPeople" runat="server"
ContextTypeName="MyDataContext" EntityTypeName=""
Select="new (PersonId, Name)" TableName="People"/>
<asp:TextBox ID="textName" runat="server" />
<asp:DropDownList runat="server" ID="dropParent"
DataSourceID="LinqPeople" DataTextField="Name" DataValueField="PersonId" />
<asp:Button ID="buttonAddPerson" runat="server" Text="Add" />
Is there any way to display 'None' in the list box with a value of null? I have thought of a few options, which is best or are there any others?
Create a stored procedure for the SQL "SELECT PersonId, Name FROM People UNION SELECT Null, 'NONE'"
Add a CheckBox for "NO PARENT"
Put a ListItem in the markup for the DropDownList
Add the item on the DataBound event handler
I found a better way, adding a ListItem in the markup:
<asp:LinqDataSource ID="LinqPeople" runat="server"
ContextTypeName="MyDataContext" EntityTypeName=""
Select="new (PersonId, Name)" TableName="People"/>
<asp:TextBox ID="textName" runat="server" />
<asp:DropDownList runat="server" ID="dropParent"
DataSourceID="LinqPeople" DataTextField="Name" DataValueField="PersonId">
<asp:ListItem Value="">(none)</asp:ListItem>
</asp:DropDownList>
<asp:Button ID="buttonAddPerson" runat="server" Text="Add" />
I cannot find any way to return the actual value 'NULL' in SelectedValue however, but I can handle that I guess. I think the ListItem way is the best because it is defined in the markup and doesn't require any code...
Don't think you can set the value of NULL since it's a string type.
I don't like the check for NULL, typically, I would use something that doesn't make sense, like -1 or something and check for that. You could also assume that your selected index is 0, however, that could cause problems somewhere else in code if you don't follow throughout the app.

How to set Custom Text into DropdownList in ASP.Net

I have dropdown list control in one of my application and when I add Items in it from database Its displaying the first Item into Dropdown list by default but I want to display someother text into this like "Select Item from the List" Is there any way I can do this .
Also Can you please help me setting the same value from javascript
On the ASP.NET side of things, you can create the DropDownList with AppendDataBoundItems="true" and any items you bind to it will come after the default:
<asp:DropDownList AppendDataBoundItems="true" ID="yourListId" runat="server">
<asp:ListItem Text="Select something" Value="-1" />
</asp:DropDownList>
As for doing the same thing completely in Javascript, you can do it with a function like this:
function addFirstItem(list, text, value)
{
var newOption = document.createElement("option");
newOption.text = text;
newOption.value = value;
list.options.add(newOption);
}
addFirstItem(document.getElementById("yourListId"), "Select something", "-1");
Or with jQuery (there is probably something much cleaner, especially for creating a new option tag, but this works):
$("#yourListId option:first").before("<option value='-1'>Select something</option>");
Patridge answer is correct, however if you are using the asp method and still run into a problem, add the items tag to the listitem.
<asp:DropDownList AppendDataBoundItems="true" ID="yourListId" runat="server">
<items>
<asp:ListItem Text="Select something" Value="-1">--Select Something--</asp:ListItem>
</items>
</asp:DropDownList>

Databound drop down list - initial value

How do I set the initial value of a databound drop down list in ASP.NET?
For instance, I want the values, but the first value to display should be -- Select One ---, with a null value.
I think what you want to do is this:
<asp:DropDownList ID="DropDownList1" runat="server" AppendDataBoundItems="true">
<asp:ListItem Text="--Select One--" Value="" />
</asp:DropDownList>
Make sure the 'AppendDataBoundItems' is set to true or else you will clear the '--Select One--' list item when you bind your data.
If you have the 'AutoPostBack' property of the drop down list set to true you will have to also set the 'CausesValidation' property to true then use a 'RequiredFieldValidator' to make sure the '--Select One--' option doesn't cause a postback.
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="DropDownList1"></asp:RequiredFieldValidator>
I know this is old, but a combination of these ideas leads to a very elegant solution:
Keep all the default property settings for the DropDownList (AppendDataBoundItems=false, Items empty). Then handle the DataBound event like this:
protected void dropdown_DataBound(object sender, EventArgs e)
{
DropDownList list = sender as DropDownList;
if (list != null)
list.Items.Insert(0, "--Select One--");
}
The icing on the cake is that this one handler can be shared by any number of DropDownList objects, or even put into a general-purpose utility library for all your projects.
What I do is set the text property of the drop down list AFTER I databind it. Something like this:
protected void LoadPersonComboBox()
{
var p = new PeopleBLL();
rcmbboxEditPerson.DataSource = p.GetPeople();
rcmbboxEditPerson.DataBind();
rcmbboxEditPerson.Text = "Please select an existing person to edit...";
}
This makes the initial visible value of this dropdown show up, but not actually be a part of the drop down, nor is it a selectable.
I know this already has a chosen answer - but I wanted to toss in my two cents.
I have a databound dropdown list:
<asp:DropDownList
id="country"
runat="server"
CssClass="selectOne"
DataSourceID="country_code"
DataTextField="Name"
DataValueField="CountryCode_PK"
></asp:DropDownList>
<asp:SqlDataSource
id="country_code"
runat="server"
ConnectionString="<%$ ConnectionStrings:DBConnectionString %>"
SelectCommand="SELECT CountryCode_PK, CountryCode_PK + ' - ' + Name AS N'Name' FROM TBL_Country ORDER BY CountryCode_PK"
></asp:SqlDataSource>
In the codebehind, I have this - (which selects United States by default):
if (this.IsPostBack)
{
//handle posted data
}
else
{
country.SelectedValue = "US";
}
The page initially loads based on the 'US' value rather than trying to worry about a selectedIndex (what if another item is added into the data table - I don't want to have to re-code)
To select a value from the dropdown use the index like this:
if we have the
<asp:DropDownList ID="DropDownList1" runat="server" AppendDataBoundItems="true"></asp:DropDownList>
you would use :
DropDownList1.Items[DropDownList1.SelectedIndex].Value
this would return the value for the selected index.
hi friend in this case you can use the
AppendDataBound="true"
and after this use the list item.
for e.g.:
<asp:DropDownList ID="DropDownList1" runat="server" AppendDataBoundItems="true">
<asp:ListItem Text="--Select One--" Value="" />
</asp:DropDownList>
but the problem in this is after second time select data are append with old data.
Add an item and set its "Selected" property to true, you will probably want to set "appenddatabounditems" property to true also so your initial value isn't deleted when databound.
If you are talking about setting an initial value that is in your databound items then hook into your ondatabound event and set which index you want to selected=true you will want to wrap it in "if not page.isPostBack then ...." though
Protected Sub DepartmentDropDownList_DataBound(ByVal sender As Object, ByVal e As System.EventArgs) Handles DepartmentDropDownList.DataBound
If Not Page.IsPostBack Then
DepartmentDropDownList.SelectedValue = "somevalue"
End If
End Sub
dropdownlist.Items.Insert(0, new Listitem("--Select One--", "0");

Resources