In relation to this question:
StackOverflow - Grouping radio buttons in c# mvc
I have managed now to load and save the selected options from the form into a database but now the user may need to edit this.
How do I load the view with the selected user's choices? I cannot see where you can set selected Answer. On load I am getting the default values selected
You can set the SelectedAnswer property value for each Course in your GET action and your EditorTemplate will take care of the rest.
public ActionResult Index()
{
var vm= new OrderViewModel();
//the below is hard coded for DEMO. you may get the data from some
//other place and set the course and options
var q1 = new Course { ID = 1, Name= "Starters" };
q1.Options.Add(new Option{ ID = 12, Title = "Prawn Cocktail " });
q1.Options.Add(new Option{ ID = 13, Title = "Soup" });
q1.SelectedAnswer = 13; //to do : get the selected answer value from DB
vm.Courses.Add(q1);
var q2 = new Course { ID = 1, Name= "Mains" };
q2.Options.Add(new Option{ ID = 42, Title = "Beef" });
q2.Options.Add(new Option{ ID = 43, Title = "Lamp" });
q2.SelectedAnswer = 16;// to do :get the selected answer value from DB
vm.Courses.Add(q2);
return View(vm);
}
There is no change to be made to your editor template. It stays same as the previous answer.
#model Course
<div>
#Html.HiddenFor(x=>x.ID)
<h3> #Model.Name</h3>
#foreach (var a in Model.Options)
{
<p>
#Html.RadioButtonFor(b=>b.SelectedAnswer,a.ID) #a.Title
</p>
}
</div>
Use this:
<%= Html.RadioButtonFor(m => m.Something, "something", new { Checked = "checked" })%>
Related
I have multiple dropdownlists which are rendered with a for loop and I'm having a problem getting them to post the selected value to the controller. In my query my selectlist is made like this:
model.CreateGroupForm.Genders = new List<SelectListItem>
{
new SelectListItem() {Text = "Either", Value = "Either"},
new SelectListItem() {Text = "Male", Value = "Male"},
new SelectListItem() {Text = "Female", Value = "Female"},
};
My first problem was even getting my dropdown to display the database value, even though I confirmed it was retrieving the correct value. It wouldn't work with this:
#for (var c = 0; c < Model.ExistingGroups.Count; c++)
{
#using (Html.BeginForm("EditGroup", "Group", new { id = Model.Id.StripCollectionName(), slug = Model.Slug, innerid = Model.ExistingGroups[c].Id }, FormMethod.Post, new { id = "editcommunityteamform" + c.ToString(CultureInfo.InvariantCulture), #class = "nomarginbottom" }))
{
...
#Html.DropDownListFor(x => x.ExistingGroups[c].Gender, Model.Createform.Genders)
<button type="submit" class="btn btn-primary" title="Update name and description of this group">Update</button>
}
}
After doing some digging on Stack, I discovered that each dropdown rendered needs it's own separate list. So I changed it to:
#Html.DropDownListFor(x => x.ExistingGroups[c].Gender,
new SelectList( Model.CreateGroupForm.Genders,"Value", "Text",Model.ExistingGroups[c].Gender))
This then correctly displays the queried value, however it just posts null to the controller when I submit the form. I'm having the same issue with a checkboxfor boolean within the for loop.
My ActionResult in the controller just expects a string value and looks like this:
public ActionResult EditGroup(EditGroupInput input)
{
var command = new EditGroupCommand(input.Gender);
....
My view model looks like this:
public IList<CommunityGroup> ExistingGroups { get; set; }
public CreateGroupInput CreateGroupForm { get; set; }
And then the above 2 classes have the properties mentioned in the code.
I've discovered the problem, which is that dropdownlistfor, checkboxlistfor etc do not like operating within a 'for' loop. I certainly don't have the technical know-how to understand why, but when I changed dropdownlistfor to dropdownlist it worked. So the solution looks like this:
#for (var c = 0; c < Model.ExistingGroups.Count; c++)
{
#using (Html.BeginForm("EditGroup", "Group", new { id = Model.Id.StripCollectionName(), slug = Model.Slug, innerid = Model.ExistingGroups[c].Id }, FormMethod.Post, new { id = "editcommunityteamform" + c.ToString(CultureInfo.InvariantCulture), #class = "nomarginbottom" }))
{
...
#Html.DropDownList("Gender", new SelectList(Model.CreateGroupForm.Genders, "Value", "Text", Model.ExistingGroups[c].Gender))
...
}
}
EditGroupInput should be a collection of ExistingGroups as controller action method are strongly binded with view.or use formcollection as parameter and see what are all the keys being posted from view to controller.
I am building a shopping portal where I need to accept quantity of products and pass it to an action named order
As you can see in picture above, I added a textbox for accepting quantity for each of the product, then I built an actionlink using following code
#Html.ActionLink("Order Now", "OrderNow", "ShoppingCart", new { id = item.prod_id, qty = #quantity }, new { style = "color: white;" })
to get quantity I added new int quantity attribute to view, as
int quantity = 1;
but how to update this quantity variable when users change the text in qty textbox.
Below is my View code:
#Html.TextBox("qty","", new { id=#item.prod_name, placeholder="Qty", style="width:20px; height:15px; font-size:small;" })
<script type="text/javascript">
$('##item.prod_name').change(function () {
}
});
</script>
#Html.ActionLink("Order Now", "OrderNow", "ShoppingCart", new { id = item.prod_id, qty = #quantity }, new { style = "color: white;" })
Here is my controller action method
public ActionResult OrderNow(int id, int qty)
{
if (Session["cart"] == null)
{
List<Item> cart = new List<Item>();
cart.Add(new Item(p.FirstOrDefault(), qty));
Session["cart"] = cart;
return RedirectToAction("ViewCart", new { ids = p.FirstOrDefault().prod_sub_cat_id });
}
else
{
List<Item> cart = (List<Item>)Session["cart"];
cart[index].quantity = qty;
Session["cart"] = cart;
return RedirectToAction("ViewCart", new { ids = p.FirstOrDefault().prod_sub_cat_id });
}
}
You don't really want a link to a GET method here. Your modifying data (and would not want this to be added to the browser history) so you should be posting the data. For each product, add a form element with a textbox for the quantity and a submit button for the 'Order Now` action (style it to look like a link if you want)
#using (Html.BeginForm("OrderNow", "ShoppingCart", new { id = item.prod_id })
{
<input type="text" class="???" name="qty" placeholder="Qty" />
<input type="submit" value="Order Now" class="???" />
}
Side notes:
Add class names and use css rather than including inline styles such
as style="width:20px; height:15px; font-size:small;"
You could also use #Html.TextBox("qty", new { id = "",
#class="???", placeholder = "Qty"), but note the id = "" which
removes the id attribute to prevent invalid html due to duplicates
I have many DropDownLists on page
class BigViewModel
{
public List<SmallViewModel> SmallVM {get;set;}
public List<SelectListItem> Items {get;set;}
//some other properties
}
class SmallViewModel
{
public string ItemId {get;set;}
//some other properties
}
<table>
#for( var i = 0;i<Model.SmallVM.Count();i++)
{
<tr>
<td>
#Html.DropdownListFor(m=> m.SmallVM.ItemId, Model.Items)
</td>
</tr>
}
//display other properties
</table>
in controller
bigViewModel.Items = List<SelectListItem>
{
new SelectListItem{Value = "1", Text = "aaa"},
new SelectListItem{Value = "2", Text = "bbb"},
new SelectListItem{Value = "3", Text = "ccc"},
}
bigViewModel.SmallVM = new List<SmallViewModel>
{
new SmallViewModel{ItemId = 3},
new SmallViewModel{ItemId = 2},
}
In controller I set diffrent ItemId for every SmallVM and each DropDownList uses the same Items collection. I want to set default Value from SmallViewModel for each DropDownList. For example in this case there are two DropDownLists first should display default text "ccc" and second "bbb".
Should I put diffrent List<SelectedListItem> for every SmallViewModel and set them Selected property or there is other way?
This behavior has been reported as a bug on CodePlex but not yet fixed. Using DropDownListFor() in a for loop does not bind correctly and the first option is always selected despite the value of the property. In order for DropDownListFor() to work correctly when using a collection, you need to use an EditorTemplate for the model.
In /Views/Shared/EditorTemplates/SmallViewModel.cshtml
#model SmallViewModel
#Html.DropdownListFor(m => m.ItemId, (SelectList)ViewData["Items"])
Then in the main view
#model BigViewModel
#using(Html.BeginForm())
{
// Pass the select list to the EditorTemplate as addtionalViewData
#Html.EditorFor(m => m.SmallVM, new { Items = Model.Items })
<input type="submit" />
}
You should now have 2 <select> controls displaying "ccc" and "bbb" respectively.
Based on your code updates, I think you just need to modify your view code to:
#Html.DropdownListFor(m=> m.SmallVM[i].ItemId, Model.Items)
However, I have distinct feeling that this is very much an XY problem, and although this change will make everything wire up on post, you're still not going to be getting what you actually need for the true problem you're trying to solve.
I have a dropdownlist which is stored within TitleEditorTemplate:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %>
<%=Html.DropDownList("",
new SelectList(
new[] { "MR", "MRS", "MISS", "MS", "SIR", "REV", "DR"}
)
)%>
View
<%=Html.EditorFor(x => x.Title, "TitleEditorTemplate")%>
ViewModel
[UIHint("TitleEditorTemplate")]
[Required(ErrorMessage = "Please select a title")]
public string Title { get; set; }
Controller
//Results of a query of textboxes
Title = data.Title,
Problem
My problem occurs when I'm trying to edit (pulling data from a database) the information and then write an UPDATE to the database, everything else is pulled back correctly and inserted into the correct textboxes.
However the dropdownlist automatically selects the first option 'MR' rather than 'MRS'.
I know it must have something to do with how it generates the dropdownlistbut I don't know how to fix this.
DropDownList Code
<select id="Title_TitleDropDown" name="Title.TitleDropDown"><option>MR</option>
<option>MRS</option>
<option>MISS</option>
<option>MS</option>
<option>SIR</option>
<option>REV</option>
<option>DR</option>
</select>
What am I missing? How do I get it to choose the option selected from the database as the default selection?
For example:
Database columns
Title: DR
Forename: John
Surname: Smith
When the user wants to update this information, they can do so. Within my aspx page it will popluate both the forename/surname textboxes however not the dropdownlist, this instead becomes the default value of "MR" so the name becomes Mr John Smith rather than Dr John Smith.
SelectList takes a selected value as well as available options.
So this example should select MRS.
new SelectList(new[] { "MR", "MRS", "MISS", "MS", "SIR", "REV", "DR"}, "MRS")
UPDATE
Here is an example using RenderPartial...
<% Html.RenderPartial("ViewUserControl1", new DropDownModel {Name = "Title", SelectedValue = "MISS"});%>
You can use Model.Title instead of "MISS"...
Here is the DropDownModel
public class DropDownModel
{
public string Name { get; set; }
public object SelectedValue { get; set; }
}
Here is the partial view:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcApplication2.Models.DropDownModel>" %>
<%= Html.DropDownList("test", new SelectList(new[] { "MR", "MRS", "MISS", "MS", "SIR", "REV", "DR"}, Model.SelectedValue)) %>
This is just a quick mock-up that shows how you could do it - you might want to improve upon the concept!
I believe the problem is that the property name and the control name don't match. I suspect, though I haven't tested, that the select control is ultimately named Title.TitleDropDown. This prevents the default mapper from assigning the value.
Changing your drop down control to:
<%=Html.DropDownList("",new SelectList(new[] { "MR", "MRS", "MISS", "MS", "SIR", "REV", "DR"}))%>
should fix the problem.
I almost have this solved but need a little push.
Here's what I have:
In the database I have a field called active that is a bit field (True/False)
I have placed a dropdownlist on the View form like this:
<%= Html.DropDownList("lstActive", new SelectList((IEnumerable)ViewData["ActiveList"])) %>
In my controller, I simply have this code to generate the True/False in the dropdown:
List<string> activeList = new List<string>();
activeList.Add("True");
activeList.Add("False");
ViewData["ActiveList"] = new SelectList(activeList);
I want to bind to the field in the database called active and select it in the dropdown. When I view it like this I get this:
alt text http://rjmueller.net/sitesimages/temp/dropdown.gif
So the questions are these:
Obviously I am not pointing to the Value and Text property but what is that in this case?
And how do I select the value that is in the database?
Any help would be appreciated.
First, this is probably better suited to radio buttons, not a select. Second, you really ought to have a view model with a property that is an IEnumerable<SelectListItem> that supplies the values for the select. You can construct that directly in the model.
var model = new ViewModel();
model.ActiveList = new List<SelectListItem>
{
new SelectListItem { Text = "Yes", Value = "true" },
new SelectListITem { Text = "No", Value = "false" }
};
model.Active = false; // this will be the default
return View( model );
Then in your view (strongly-typed to your view model type):
<%= Html.DropDownListFor( m => m.Active, Model.ActiveList ) %>
Using radio buttons, you can omit the list (since there are only the two choices).
<%= Html.RadioButtonFor( m => m.Active, true ) %> Yes
<%= Html.RadioButtonFor( m => m.Active, false ) %> No
Here's a couple of suggestions for you.
First, your DropdownList's name is "lstActive", so if you create a List<SelectListItem> called "lstActive" and pass that back in ViewData, you don't have to do anything fancy with boxing. Then your declaration looks like:
<%= Html.DropDownList("lstActive") %>
easy, huh?
In your controller, you create your List. Here's a method I've used:
private List<SelectListItem> GetAccounts(User user)
{
var items = new List<SelectListItem>();
foreach (Account account in user.Accounts)
{
var item = new SelectListItem();
item.Text = account.Name;
item.Value = account.AccountId.ToString();
if (ActiveAccount == account.AccountId)
item.Selected = true;
items.Add(item);
}
return items;
}
Basically, what I'm trying to point out is that you can set a property on your SelectListItem that you wish to be displayed as selected. Here, I'm using my own code for Users and Accounts, but you'd substitute your own data based on your db query.
First thing, you're recreating a SelectList the ViewData data, you should declare the DropBox as follows:
<%= Html.DropDownList("lstActive", ViewData["ActiveList"]) %>
Second, instead of creating a generic list on the controller, create a SelectList and add SelectListItems to it:
var activeList = new SelectList
{
new SelectListItem { Text = "True", Value = true },
new SelectListItem { Text = "False", Value = false }
};
ViewData["ActiveList"] = activeList;
This should clarify:
Drop-down Lists and ASP.NET MVC
For each select list element you need to set the Text and Value properties...
One solution could be as follows:
Model:
public class NameValue
{
public string Name { get; set; }
public string Value { get; set; }
}
Controller:
string currentActiveValue = myDB.active.ToString();
List<NameValue> yesNoList = new List<NameValue>
{
new NameValue { Name = "Yes", Value = "True" },
new NameValue { Name = "No", Value = "False" }
};
SelectList myActiveList = new SelectList(yesNoList, "Name", "Value", currentActiveValue);
ViewData["ActiveList"] = myActiveList;
View:
div>Is Active: <%= Html.DropDownList("ActiveList") %></div>