Getting all selected checkboxes from a FormCollection - asp.net-mvc

I have a form which contains a whole bunch of checkboxes and some other types of control too. I need to retrieve the names of each selected checkbox.
What is the best way to do this? Can I do it with a linq query maybe?
So in pseudocode, I'm looking to do something like this:
var names = formCollection
.Where(c => c is Checkbox && c.Checked)
.Select(c => c.Name);
Update It seems the way MVC submits checkboxes is different from how a normal form would behave, as an hidden field is also rendered. I found the details here: How to handle checkboxes in ASP.NET MVC forms?
Anywho, I've got it working with the help of that thread and the answer from BuildStarted below. The following code did the trick.
var additionalItems = form.AllKeys
.Where(k => form[k].Contains("true") && k.StartsWith("addItem"))
.Select(k => k.Substring(7));

Unfortunately that type of information isn't available in the collection. However if you prepend all your checkboxes with something like <input type='checkbox' name='checkbox_somevalue' /> then you can run a query like
var names = formCollection.AllKeys.Where(c => c.StartsWith("checkbox"));
Since only the checked values will be posted back you don't need to validate that they're checked.
Here's one that grabs only checked values
var names = formCollection.AllKeys.Where(c => c.StartsWith("test") &&
formCollection.GetValue(c) != null &&
formCollection.GetValue(c).AttemptedValue == "1");

This is one of the old questions not active for years but I stumbled on it. My problem was that I have an array of check boxes - let's say the name is 'IsValid' and wanted to get the status of each of the check boxes (my project was in MVC 5). On form submit i did the loop of form collection and got the values as...
if (key.Contains("IsValid"))
sV = (string[])collection.GetValue(key.ToString()).RawValue;
Since on form post the hidden field value was also posted with the checked check boxes; the array contained one additional value of 'false' for ONLY checked check box. To get rid of those i used following function; I hope that it helps somebody and if my approach is wrong then a better solution would be helpful to me as well!
sV = FixCheckBoxValue(sV);
private string[] FixCheckBoxValue(string[] sV)
{
var iArrayList = new List<string>(sV);
for (int i = 0; i < iArrayList.Count; i++)
{
if (iArrayList[i].ToString() == "true")
{
iArrayList.RemoveAt(i + 1);
}
}
return iArrayList.ToArray();
}

Answering the post about the array of checkboxes, you could initially filter out the checkboxes by name.
var keys = formCollection.AllKeys.Where(x => x.StartsWith("IsValid");
Then you could just loop through them as a collection.

Related

I'm having troubles getting drop-down-menus in MVC to return data

I am very new to MVC as a whole, and I was sent to create a web application that would give the user options then change the view based on these options. First I created a simple "select" html drop down menu but I am under the assumption that this won't work.
I can supply all the actual code I currently have, I just don't know what would be important to see and what would just be bothersome to wade through.
When I had created a constructor for the model, it wouldn't go through that constructor or else it would be easier.
Sorry since this all sounds probably bad, but any help would be amazing.
There are couple ways to do that , here's what i do :
create the function in your controller (The one that returns the list of items you want to include in the dropdownmenu) . let's name it getNames();
Then return that to the view using #viwbag.Names;
In the view you can declare a variable , something like:
#{
SelectListItem[] Names = ViewBag.Name;
}
and the dropdown menu code should be something like this:
#Html.DropDownList("Names", Names)
Finally, here is sample code for the controller:
IEnumerable<SelectListItem> Names =
(from names in YourDB.students.ToArray()
select new SelectListItem
{
Text = names.Name,
Value = names.Id
}).ToArray();
var Templist = names.ToList();
ViewBag.Roles = Templist.ToArray();

How will model binder deals with Readonly & disabled

I have the following two items , one which is readonly:-
#Html.TextBoxFor(model => model.Technology.Tag, new
{ #readonly = "readonly" })
While the other is Disabled:-
#Html.DropDownListFor(model => model.Customer.NAME, ((IEnumerable<TMS.Models.AccountDefinition>)ViewBag.Customers).Select(option => new SelectListItem
{
Text = (option == null ? "None" : option.ORG_NAME),
Value = option.ORG_NAME.ToString(),
Selected = (Model != null) && (Model.Customer != null) & (option.ORG_NAME == Model.Customer.NAME)
}), "Choose...", new { disabled = "disabled" })
so will the asp.net mvc model binder bind the two items? , or it will ignore any read-only and any disabled fields ?
It will bind them, but as long as you have populated them with the correct data, that shouldn't matter. Also, you can have your code that maps these models to the entity, assuming you are using view models, just ignore the values in question. Assuming this is a standard HTTP Post from the form, HTTP will not post disabled or readonly fields, which means they will be null or the default value in the model, so you need to account for that.
If you want the binder to ignore these values, use TextBox and DropDownList and make sure they are not named the same as your properties. If you do not use 'For' you will need to add code in the view to set the values.
ReadOnly text fields get bound.
I've been trying to find a way around the unbound dropdownboxfor values. Here's what I came up with:
$('#xxx').change(function() {$(this).val(lastSel_xxx);});
var lastSel_xxx = $("#xxx option:selected").val();
Use the code above for each HTML element in your view (this will require you to document each ID output) and replace 'xxx' with the element name.
When a user selects another option besides the initial option selected, it reverts back to the original.
HOpe this helps!

asp.net mvc html helper Dropdownlist issues

I use mvc html helper checkbox like this:
#Html.DropDownList(item.QuestionId.ToString(),
new SelectList(((DropDownList)item).Options, "OptionId", "Name"),
"Select Please")
and when i submit, in my [http] controller, i can get the value by
[HttpPost]
public ActionResult TestList(FormCollection formCollection)
{
foreach (var res in formCollection.AllKeys)
{
string Selected = null;
Selected = formCollection[res];
}
but when I select "A" for example, I get A, but when I select nothing (it shows "Select Please" as I defined), I want it to be null,but now it's "", it means it has value...I just want it to be like: I submit nothing if I selected nothing, I mean nothing in AllKeys, neither in StringSelected, I want allkeys has nothing if I don't select, thank you
ps:
for e.g:
foreach (var SubItem in ((RadioButtonList)item).Options)
{
#Html.RadioButton(item.SurveyItemId.ToString(), SubItem.OptionId) #SubItem.Name
}
it will show options of a question, if i chose A, i can get A form my controller, i didnt choose B,so in my controller AllKeys, it doesnt contain B or C or D, so i want dropdownlist just like this, if i didnt choose anyone, it wont show "" or something else just like i didnt choose B or C or D, nothing will show in AllKeys
First, that's not a check box. That's a drop down list. Asking questions with correct information is important, or you will get the wrong answers.
Second, this is not possible, and it has nothing to do with MVC, this is done by the browser. There's no way to make the browser submit "null" when you're actually submitting something. There is no concept of "null" in an http post.
The only way you get null is if the value is not posted at all. Otherwise, the model binder could not know the difference between an actual null and when you actually wanted to post an empty string.
You can't even create a custom model binder, because you're bypassing model binding by going directly to the forms collection.

MVC4 EF cannot get saved value to display in dropdown on page load

I have never asked a question on StackOverflow before, and never wanted to, but I am desperate, so here we go: I cannot get a saved value to show up as the default value/display in a dropdown.
I set up the list in my controller:
public ActionResult Index()
{
//User Dropdown List
var users = Roles.GetUsersInRole("Manager");
SelectList list = new SelectList(users);
ViewBag.Users = list;
return View();
}
Then in the view an admin can then select one of these users and save it to my database via EF:
#Html.DropDownList("Users", ViewBag.Users as SelectList, "--Select Manager--")
This all works great, however, when you edit this entry, I want the dropdown list to show the current saved manager, not the first name in the list. I was hoping on my edit action that I could pull the current manager out of the database and pass it back into the dropdown as the default selected item, but no go:
public ActionResult Edit(int id = 0)
{
var theOwner = (from v in _db.Location where v.LocationID == id select v.Owner).FirstOrDefault();
var users = Roles.GetUsersInRole("Manager");
SelectList list = new SelectList(users, theOwner);
ViewBag.Users = list;
From all the examples I have read over the last 2 weeks, everyone has had 3 different values to work within their dropdowns, making it possible to use all the overloads in the SelectList method. However, my problem is that I just have this string list with only one item in it, so I can't utilize the overloads as I want.
So does anyone have an idea on how I can get this to work? Thanks a lot in advance for your time on this!
I'm pretty sure that if you modify the second parameter on the line where you create your SelectList, it should work -- it does for me.
Here is what I think the trouble is: Currently you are specifying the second parameter as 'theOwner', which is an object reference from the earlier Linq statement. But the SelectList contains a bunch of strings (the UserNames of the users which match the specified rolename). As a result, the SelectList doesn't 'know' how to match what you specified as the SelectedItem to something in the list of strings it contains.
But if you refine that second parameter so it specifies the USERNAME of the Owner that you just looked up, it should work. However I do not know what the correct property name is from your Location table. If the field you are currently selecting (v.Owner) contains the UserName itself rather than some Key then the syntax would be:
SelectList list = new SelectList(users, theOwner.Owner);
If that column actually contains a key for the User like an int or a Guid then you will have query for the UserName using the key, but the nature of the fix is the same.
Hope that helps.
A quick workaround is not to use #Html.DropDownList but plain html code.
As an example for your case, use the following html code in your View instead of Html.DropDownList helper:
<!-- NOTE: the ID and name attributes of "select" tag should be the same as
the name of the corresponding property in your Model in order for ASP.NET MVC
to edit your Model correctly! -->
<select id="User" name="User">
#foreach (var user in (SelectList)ViewBag.Users)
{
if (user == ViewBag.TheOwner)
{
<option value="#user" text="#user" selected = "selected" />
}
else
{
<option value="#user" text="#user" />
}
}
</select>
Also , for this to work you need to add one more line to your Edit method:
ViewBag.TheOwner = theOwner;
Another solution is also possible using #Html.DropDownListFor() however you haven't shown your model so I can't tell you what exactly to use. When DropDownListFor is used, ASP.NET MVC will select an option automatically based on the value in your model.

How to loop through the FormCollection to check if textboxes have values?

I have a search page that has 6 textboxes which i pass as FormCollection to the action in the controller. I dont want to search for records if ther is no values in textboxes.
Is there a way to loop through all textboxes in FormCollection to check which ones have values in them?
I am a student in the college and this project is part of my summer experience program.
I realize that this is a newbie question :)
Thank you!
You can loop through the FormCollection like this:
foreach( string key in forms.Keys )
{
...
}
However, note that the browser only sends you names and values. It does not send you the types of inputs, so you have no way to check if the value is a checkbox, unless you know all checkboxes names in advance. But if that's the case, you don't need to loop - just take them out of the collection by name.
List<string> list = new List<string>();
for(int i= 0; i< form.AllKeys.Count(); ++i)
{
list.Add(form.Get(i));
}
This will give you all the actual values for each key

Resources