Determining which items are selected in CheckBoxList using Request.Form
Asked Answered
P

4

6

Using the approach shown in the question here, I am able to get the selected items values from my CheckBoxList:

var selectedCheckBoxItems = from key in Request.Form.AllKeys
                        where key.Contains(cbl.ID)
                        select Request.Form.Get(key);

I can then iterate over the results:

foreach (var item in selectedCheckBoxItems)
{

}

The problem is that item is just the posted value, which for a checkbox, is simply the string "on".

on

I need to be able to determine which item is "on", either by index or some other method.

Question: How do I determine which items in the CheckBoxList are selected, using Request.Form ?

Here is my CheckBoxList definition:

<asp:CheckBoxList runat="server" ID="cblAnimalType" SelectionMode="Multiple" DataTextField="OptionText" DataValueField="OptionId"  AutoPostBack="True"/>

Items are added to the list from code behind:

DataTable dt = GetData(SqlGetListOptions, paramList);
cbl.DataSource = dt;
cbl.DataBind();

The other important thing to know is that ViewStateMode="Disabled", so I must use Request.Form to get the selected items.


In response to a comment, here is how the HTML for the CheckBoxList renders:

html


@Leopard pointed out that he sees values rendered in the HTML which is not occurring in my situation. AdamE's answer to this question explains why. I have the following line in web.config:

<pages validateRequest="false" controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID">

which explains why I see "on" instead of the actual value of the selected items. I am not able to just yank the compatibility out of web.config without verifying it won't break something else, but it appears that if that setting is safe to remove, the checkbox list values will be accessible from codebehind.

Paraformaldehyde answered 7/6, 2016 at 22:9 Comment(13)
Are you saying that when you set ViewStateMode="Enabled" then getting the checked state of the items of CheckListBox works fine?Yea
I'm saying View State is disabled, so I must use Request.Form. If View State were enabled, I would just get the selected items from the control's view state, like thisParaformaldehyde
"On" is the DataValueField for all items in the CheckBoxList?Nace
Sorry for asking this question: why don't you enable the ViewState for that list?Naquin
@ConnorsFan - there are multiple reasons. One being performance issues faced by remote users trying to interact with a form bloated by View State.Paraformaldehyde
The ViewState could be disabled for the whole form and enabled only for the CheckBoxList (given that it would make your job so much easier).Naquin
@ConnorsFan - I know it's easier, but that's not the point. I need to not use View State, for various reasons.Paraformaldehyde
@devlincarnate you want all this code on PostBack of checkboxlist ?Eloiseloisa
@MairajAhmad - yes. The question is how to get the checked boxes on postbackParaformaldehyde
@devlincarnate and why have you used AutoPostBack="true" on checkboxlist ?Eloiseloisa
@MairajAhmad - I've changed that since I originally posted the question. It's inconsequential to the question, and can be ignored.Paraformaldehyde
In which method are you calling cbl.DataBind()?Fluor
@MichaelLiu - A method called LoadListOptions(CheckBoxList cbl, string listName) which is called in Page_LoadParaformaldehyde
E
3

As you are binding the checkboxList from Database with OptionId feild you can check which checkboxes are selected and store their value in List<int> assuming their value is int.

Then again when you populate the checkboxlist you can check which value is present in the list stored earlier and based on value you can select the relevant checkbox.

Here is a sample code

List<int> SelectedCheckBoxes = new List<int>();
var selectedCheckBoxItems = from key in Request.Form.AllKeys
                                    where key.Contains(cblAnimalType.ID)
                                    select Request.Form.Get(key);
foreach (var item in selectedCheckBoxItems)
{
  SelectedCheckBoxes.Add(int.Parse(item.ToString()));
}

Then again when you populate the checkboxlist you can find the items by value and select them

foreach (ListItem listItem in cblAnimalType.Items)
{
  if (SelectedCheckBoxes.Contains((int.Parse(listItem.Value))))
   {
     listItem.Selected = true;
   }
}

You may need to store the SelectedCheckBoxes List in session depending on how you are populating the checkboxlist.

Update

As per discussion with you you were using Asp.net 4.0 but your checkboxes didn't have a value attribute which should have been there.

This is happening because you are using controlRenderingCompatibilityVersion="3.5" which is no longer needed as you are already using Asp.Net 4.0.

So removing this line from web.congif will solve the issue and you will be able to get the value of checkbox instead of just getting on

<pages controlRenderingCompatibilityVersion="3.5" />
Eloiseloisa answered 11/6, 2016 at 15:49 Comment(14)
Why do you assume that the value is an integer? Wouldn't it be simpler and safer to store List<string> SelectedValues and avoid int.Parse (even if the value is actually an integer)?Naquin
@ConnorsFan because the value is bind to the property ID which seems to be int. And int.parse because the .Value is string and item is of type var.Eloiseloisa
@MairajAhmad - The problem with this solution is that item.ToString() is "on", which can't be parsed to Int, and can't be related to the items in the list ("on" doesn't tell me which checkbox is selected). You can see this in my original question, where I've posted the screenshot showing the content of item in the foreach which iterates over selectedCheckBoxItemsParaformaldehyde
I used same code and was able to do this. have you tried this ?Eloiseloisa
one mre thing you have shown cblanimaltype in aspc but used cbl.id in c# code is this correct.Eloiseloisa
@MairajAhmad - Yes, I've tried it. And yes, I'm sure cbl.id is correct. I pass the control to a method: private List<int> GetCheckBoxListSelections(string listName, CheckBoxList cbl). And call the method like this: var animalIndexes = GetCheckBoxListSelections(AnimalType, cblAnimalType);Paraformaldehyde
Which asp.net version are you using ? Because i have tried same approach on different machines and it works perfectly ? Also can u please tell what are values of OptionId. Are they int ? Inspect html of your page in browser to see if checkboxes are getting the values from optionid feild correctly.Eloiseloisa
@devlincarnate I have updated the answer with a new approach please see update.Eloiseloisa
@MairajAhmad - I've updated my question with a screenshot of how the HTML renders. I'll look at your updated answer shortly.Paraformaldehyde
The updated approach will allow me to re-select the checkboxes after postback, but it will not allow me to save the selections to the database. I'm still stuck with parsing item.Key to get the index of the selected options. This means I might as well skip the JavaScript part, and used the indexes obtained from parsing item.Key to set the selections from codebehind.Paraformaldehyde
Let us continue this discussion in chat.Eloiseloisa
Removing controlRenderingCompatibilityVersion="3.5" from web.config made it so that I now get the OptionId as the value instead of just "on" since we are using ASP.NET 4.0. This was a solution discovered during chat. ASP.NET 3.5 and earlier will show "on" and the compatibility setting was preventing me from getting the actual value from the items. If you update your answer by clarifying this point, I will mark it as the solution.Paraformaldehyde
Please see the update in answer and feel free to edit if you want to add something in it.Eloiseloisa
@devlincarnate Please see the update in answer and feel free to edit if you want to add something in it.Eloiseloisa
P
2

I thought of one way to do it, by adding the key to the results. I'm not entirely happy with this method due to the string parsing that's required to get the index. Perhaps someone else has a better method?

The general idea is to add the key to the results:

var selectedCheckBoxItems = from key in Request.Form.AllKeys
                        where key.Contains(cbl.ID)
                        select new {Value = Request.Form.Get(key), Key = key};
foreach (var item in selectedCheckBoxItems)
{
   var val = item.Value;
   var key = item.Key;
}

I can then parse the key to find the index, which is what I need in order to set the selected option(s):

var selectedCheckBoxItems = from key in Request.Form.AllKeys
                        where key.Contains(cbl.ID)
                        select new {Value = Request.Form.Get(key), Key = key};

string[] stringParse = new string[] {listName.Replace(" ", "") + '$'};

foreach (var item in selectedCheckBoxItems)
{
    var val = item.Value;
    var key = item.Key;
    var idxArray = key.Split(stringParse, StringSplitOptions.None);
    var idxString = idxArray[idxArray.Length - 1];
    int idxInt;
    if (Int32.TryParse(idxString, out idxInt))
    {
        cbl.Items[idxInt].Selected = true;
    }
}
Paraformaldehyde answered 7/6, 2016 at 23:13 Comment(0)
N
1

Here is another way to parse the key to get the selected indexes. It also uses the UniqueID property to find the relevant keys.

var selectedCheckBoxItems = from key in Request.Form.AllKeys
                            where key.Contains(cblAnimalType.UniqueID)
                            select new { Value = Request.Form.Get(key), Key = key };

foreach (var item in selectedCheckBoxItems)
{
    var val = item.Value;
    string indexToken = item.Key.Replace(cblAnimalType.UniqueID, "");
    int index = int.Parse(Regex.Replace(indexToken, @"[^\d]", ""));
    ...
}
Naquin answered 13/6, 2016 at 15:21 Comment(1)
I was hoping to get away from parsing to get the index. However, I understand if it's the only way, it will be what I need to do. This approach to parsing seems better than the one I came up with.Paraformaldehyde
F
0

I realize this is very close to previous responses so I am not sure if it is adding anything but it is a little more succinct so I will add it. In Request.Form.AllKeys, The Key is the html name of the checkbox. The html name of the checkbox contains the index. I would just change you linq query to only select the items that are "on" and then return the list of keys. After that you can just parse the keys to get the index.

var selectedCheckBoxItems = from key in Request.Form.AllKeys
                            where key.Contains(cbl.ID) && Request.Form.Get(key) == "on"
                            select key;

foreach (var item in selectedCheckBoxItems)
{
     var index = 0;
     if (int.TryParse(item.Substring(item.LastIndexOf("$") + 1), out index))
     {
         //do what you will
     } 
}

Also, string parsing in this instance is pretty safe since the field names are generated by the framework in a very specific and formulaic way. The odds of them ever being different are close to if not zero.

Frankenstein answered 16/6, 2016 at 20:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.