ASP.NET DropDownList - GetSelectedIndices missing one selected item - asp.net

Maybe I'm losing my mind - I thought this was straight forward.
ListCode.DataTextField = "code_desc";
ListCode.DataValueField = "code_id";
ListCode.DataSource = Foo.GetCodes();
ListCode.DataBind();
The selection mode is set to multipls and all is good, about 50 items with appropriate values displays. Then I select 5 items and submit the form. I do a
int[] indices = ListCode.GetSelectedIndices();
and the array only has the first four items that I selected. It seems that if I select multiple items in the list and submit the form, I'm only able to retrieve all but the last selected item - it doesn't matter if I use GetSelectedIndices or if I iterate through each item in the list.
Any help would be greatly appreciated.

You must be using a ListBox I assume. I made the following test app:
<asp:ListBox ID="lstTest" runat="server" SelectionMode="Multiple">
<asp:ListItem Text="Test1" Value="1" />
<asp:ListItem Text="Test2" Value="2" />
<asp:ListItem Text="Test3" Value="3" />
<asp:ListItem Text="Test4" Value="4" />
</asp:ListBox>
<asp:Button ID="btnTest" runat="server" Text="Test" OnClick="btnTest_Click" />
<asp:Label ID="lblTest" runat="server" />
protected void btnTest_Click(object sender, System.EventArgs e)
{
int[] selectedIndexes = lstTest.GetSelectedIndices();
lblTest.Text = selectedIndexes.Length.ToString();
}
Seems to work fine so I have to assume it has something to do with your binding or when you are fetching the indicies. Can you post a trimmed down version of your broken code?

Not really an answer, but I swapped in a checkboxlist and it worked like a champ.

Related

Missing something nested in FindControl but always get Null

Literally have read and tried all solutions in Stackoverflow to no avail.
I am trying to get the value of different Dropdownlists genereated from a Repeater and another one just generated on the go, plain and simple.
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
I am trying to get all the selectedValue's of all the dropdownLists genereated thru Repeater and the one that is plain and simply there.
<asp:DropDownList ID="reasonFamily" runat="server">
<asp:ListItem Enabled="true" Text="--------" Value="-1"></asp:ListItem>
<asp:ListItem Text="Option 1" Value="1"></asp:ListItem>
<asp:ListItem Text="Option 2" Value="2"></asp:ListItem>
which looking in the front end, I am getting something like...
<select name="ctl00$ContentPlaceHolder1$reasonFamily" id="ContentPlaceHolder1_reasonFamily">
Which looks good, since I did a button and tried to get this value...
DropDownList ctr = Page.FindControl("Content2").FindControl("reasonFamily") as DropDownList;
TextBox.Text = ctr.SelectedValue;
I could just get the value of reasonFamily.SelectedValue and get finished with... But the problem is, there is another section with a repeater that creates several DropDownList and I need to find all of them and get all their values and Send them to the DB. The DropDownList is all nested in...
<asp:Repeater ID="repStudents" runat="server">
<asp:DropDownList ID="reasonStd" runat="server">
<asp:ListItem Enabled="true" Text="--------" Value="-1"></asp:ListItem>
<asp:ListItem Text="Option 1" Value="1"></asp:ListItem>
<asp:ListItem Text="Option 2" Value="2"></asp:ListItem>
I tried getting finding all of the dropdownlist, but all I get is NULL.
UPDATE: I was able to get the one that is not in the Repeater, but other still eludes me, even tho I have almost tried all the possible choices.
<select name="ctl00$ContentPlaceHolder1$reasonFamily" id="ContentPlaceHolder1_reasonFamily"> // This I was able to access with:
DropDownList ctr = this.Master.FindControl("ContentPlaceHolder1").FindControl("reasonFamily") as DropDownList;
<select name="ctl00$ContentPlaceHolder1$repStudents$ctl01$reasonStd" id="ContentPlaceHolder1_repStudents_reasonStd_1"> //This I could not. Tried all of this:
DropDownList ctr = this.Master.FindControl("ContentPlaceHolder1").FindControl("reasonStd_1") as DropDownList;
DropDownList ctr = this.Master.FindControl("ContentPlaceHolder1").FindControl("repStudents").FindControl("reasonStd_1") as DropDownList;
DropDownList ctr = this.Master.FindControl("ContentPlaceHolder1").FindControl("repStudents")FindControl("reasonStd").FinControl("1") as DropDownList;
Ok, so the 2nd or some other repeater issue - we leave that separate for now.
that last answer SHOWS how we can grab those values - it really the same code.
So, you have a repeater. It has maybe 1 or 15 rows. So, we want to get/grab the drop down list from each row of the repeater.
So, say we have this markup in the repeater (I included your above dropdown list).
So, we have this simple markup:
<asp:Repeater ID="Repeater1" runat="server" >
<ItemTemplate>
<div style="border-style:solid;color:black;width:250px">
<div style="padding:5px;text-align:right">
First Name: <asp:TextBox ID="txtFirst" runat="server" Text ='<%# Eval("FirstName") %>' Width="130px" />
<br />
Last Name: <asp:TextBox ID="txtLast" runat="server" Text ='<%# Eval("LastName") %>' Width="130px" />
<br />
<asp:DropDownList ID="reasonFamily" runat="server">
<asp:ListItem Enabled="true" Text="--------" Value="-1"></asp:ListItem>
<asp:ListItem Text="Option 1" Value="1"></asp:ListItem>
<asp:ListItem Text="Option 2" Value="2"></asp:ListItem>
</asp:DropDownList>
<br />
</div>
</div>
</ItemTemplate>
Ok, now it don't matter if this has 2, or 30 rows. Lets assume it has 3 rows of data. so the above now shows this:
So say when we click on the above button, then we need code (the SAME code in the last question). so the code to process each row, get the values (including the dropdown) could be like this for that button click:
protected void Button1_Click(object sender, EventArgs e)
{
foreach (RepeaterItem rRow in Repeater1.Items)
{
// get First Name.
Debug.Print(rRow.FindControl("txtFirst") as TextBox.Text);
// get LastName
Debug.Print(rRow.FindControl("txtLast") as TextBox.Text);
// get value of drop down box
string strDropDownChoice = rRow.FindControl("reasonFamily") as DropDownList.Text;
Debug.Print("Drop Down option picked = " + strDropDownChoice);
}
}
And output from above loop code would be this:
Output:
Albert
Kallal
Drop Down option picked = 1
Darcy
Caroll
Drop Down option picked = 2
Don
Grant
Drop Down option picked = 2
So, once again, I don't see any real issue or problem with looping over the rows in the data repeater, and then pulling out the values from text box, check box, or a drop down list - it is all quite much the same.

disable button until value is selected ---select---doesnt appear

SO far everything working ok, button is disabled until value is selected from the drop down list,
However I want ---select--- to be the first option on the drop down list, but this is not happening...any ideas as to why?
<asp:DropDownList ID="DropDownListSubContractors" runat="server"
AppendDataBoundItems="true" DataTextField="Company_Name" DataValueField="id"
onchange='selectChanged(this);'>
<asp:ListItem Text="---Select---" Value="0" />
<asp:ListItem Text="Option 1" Value="1" />
</asp:DropDownList>
<script type="text/javascript">
function selectChanged(e) {
document.getElementById("<%= addNewSubContractor.ClientID %>").disabled
= (e.options[e.selectedIndex].value == "0") ? "disabled" : "";
}
</script>
<asp:Button ID="addNewSubContractor" Text="Add Sub Contractor"
OnClick="UploadSubContractor" runat="server" disabled='disabled' />
Showing the manually added items first followed by the data bound items is the default behavior of the drop down list, so ---Select--- should in theory be the first item.
I suspect there is some logic elsewhere(can be javascript or code behind) which sets the selected item to something else i.e:
DropDownListSubContractors.SelectedIndex = 1;
Have a good look through your code and make sure the selected item is not being re-set anywhere
Have you got append databound item set to true, this checks to see if there are any items in the collection, and adds them first before binding?

DDL SelectedIndexChanged() does not fire on first ListItem (ASP.Net C#)

I created a custom Templated User Control, for the purpose of having a standard "container" to use around our web app, but allow whatever controls you want inside of it -- pretty much like a Template Column of a GridView/DataGrid. Problem I'm having is that when I place a DropDownList control inside my custom control, the SelectedIndexChanged method of that DDL doesn't always fire, and I am stumped as to why.
I created a small test page with my custom control and a single DDL, which has some hard coded values, to replicate the problem:
<uc1:ExpandCollapseRegion ID="xpcColor" runat="server" Title="Pick a Color" AlwaysOpen="true">
<LayoutTemplate>
<table>
<tr>
<td>Color: </td>
<td>
<asp:DropDownList ID="ddlColor" runat="server" AutoPostBack="true" OnSelectedIndexChanged="ddlColor_SelectedIndexChanged">
<asp:ListItem Text="" Value="" />
<asp:ListItem Text="Red" Value="1" />
<asp:ListItem Text="Orange" Value="2" />
<asp:ListItem Text="Yellow" Value="3" />
<asp:ListItem Text="Green" Value="4" />
<asp:ListItem Text="Blue" Value="5" />
<asp:ListItem Text="Indigo" Value="6" />
<asp:ListItem Text="Violet" Value="7" />
</asp:DropDownList>
</td>
</tr>
<tr>
<td colspan="2">
<asp:Label ID="lblColorChoice" runat="server" />
</td>
</tr>
</table>
</LayoutTemplate>
The code-behind looks like this:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
((Label)xpcColor.FindControl("lblColorChoice")).Text = "";
}
}
protected void ddlColor_SelectedIndexChanged(object sender, EventArgs e)
{
using (DropDownList ddlColor = ((DropDownList)xpcColor.FindControl("ddlColor")))
{
if (!String.IsNullOrEmpty(ddlColor.SelectedValue))
{
((Label)xpcColor.FindControl("lblColorChoice")).Text = "You chose the color " + ddlColor.SelectedItem.Text;
}
else
{
((Label)xpcColor.FindControl("lblColorChoice")).Text = "";
}
}
}
All that is supposed to happen here is to show in the Label what color was picked, but if no color was picked to then just clear the label. Very simple, no biggie, however....
100% of the time, when I pick a color the SelectedIndexChanged method fires, and the Label control is updated with the text. I can pick one color, the another, then another, and so forth over and over and the thing works great. However, if after choosing a color, I select the blank item of the DDL, the SelectedIndexChanged method does not fire, ever.
I wanted to see if this had something to do with the value being selected, so I added a new ListItem before the blank one (making the blank ListItem the second option):
<asp:ListItem Text="White" Value="0" />
Now when I run the page, I can choose a color, the label is updated, choose the blank one and the label is cleared, but if I select "White", the page does a PostBack yet the SelectedIndexChanged method once again does not fire.
I have never run into this before and admit I am a bit stumped as to the cause.
The problem may well be in my custom control, but I am hesitant to think so as the DDL functions correctly for all selections, except for the first one. Also the DDL choice as well as the Label text survives a PostBack, so I am not sure this is a ViewState issue either.
I'm still Googl'ing this, but I am pretty much stumped here what's going on. If anyone else has seen this, run across this, or may have some input of possible fixes, I am all ears. Much appreciated.
-- Andrew

How to check that at least one RadioButtonList has an item selected?

I have 20 RadioButtonLists on a page.
I need to create a validation method to ensure that at least one of these RadioButtonLists has an item selected.
What kind of validation would I need to use for this?
EDIT: Updated question based on comments and clarification.
If you are validating against multiple RadioButtonLists then you need to use a CustomValidator and implement the server side check.
Here is some test markup:
<asp:RadioButtonList ID="rblstTest1" runat="server" ValidationGroup="Test">
<asp:ListItem Text="Test 1" Value="1" />
<asp:ListItem Text="Test 2" Value="2" />
<asp:ListItem Text="Test 3" Value="3" />
</asp:RadioButtonList>
<br /><br />
<asp:RadioButtonList ID="rblstTest2" runat="server" ValidationGroup="Test">
<asp:ListItem Text="Test 1" Value="1" />
<asp:ListItem Text="Test 2" Value="2" />
<asp:ListItem Text="Test 3" Value="3" />
</asp:RadioButtonList><br />
<asp:Button ID="btnTestRb" runat="server" ValidationGroup="Test" Text="Test RBL"
OnClick="btnTestRb_Click" />
<asp:CustomValidator runat="server" ValidationGroup="Test" ID="cvTest"
ControlToValidate="rblstTest1" OnServerValidate="cvTest_ServerValidate"
ValidateEmptyText="true" Enabled="true" display="Dynamic" SetFocusOnError="true"
ErrorMessage="You must select at least one item." />
Use the following extension method to find all the RadioButtonList controls (Source):
static class ControlExtension
{
public static IEnumerable<Control> GetAllControls(this Control parent)
{
foreach (Control control in parent.Controls)
{
yield return control;
foreach (Control descendant in control.GetAllControls())
{
yield return descendant;
}
}
}
}
Then implement the server side CustomValidator check:
protected void cvTest_ServerValidate(object sender, ServerValidateEventArgs e)
{
int count = this.GetAllControls().OfType<RadioButtonList>().
Where(lst => lst.SelectedItem != null).Count();
e.IsValid = (count > 0);
}
I have tested the above example and it seems to do exactly what you need. You should be able to switch it to VB pretty easily. Hope this solves your problem.
You could set a default for your RadioButtonList which would mean a user could never not select an option and you would not need all the validation code
<asp:RadioButtonList ID="RadioButtonList1" runat="server">
<asp:ListItem Selected="True">Never</asp:ListItem>
<asp:ListItem>Twice A Week</asp:ListItem>
<asp:ListItem>Every Day Baby!</asp:ListItem>
</asp:RadioButtonList>
EDIT
As pointed out in a comment below this would not be sufficient by itself as a means of validation. It is good practice to validate all user input on the server-side also.
I use an extension method that works for ListControls
public static bool IsAnyItemSelected(this ListControl input) { return input.Items.Cast<ListItem>().Aggregate(false, (current, listItem) => current | listItem.Selected); }

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>

Resources