I would like to pass a number selected from DropDownlist to a GET Create method in other Controller. It looks like:
[HttpGet]
public ActionResult Details(int? id, string error)
{
{...}
var numbers = Enumerable.Range(1, 100);
ViewBag.Quantity = numbers.Select(i => new SelectListItem { Value = i.ToString(), Text = i + "%" });
return View(viewModel);
}
public ActionResult Create(int ID, int quantity)
{
{...}
}
Details View looks like:
<div>
#if (Model.ItemRent.Zatwierdzony == false)
{
using (Html.BeginForm("Create", "ItemRentLists", new { ID = #Model.ItemRent.ItemRentID }, FormMethod.Get))
{
#Html.DropDownList("quantity", new SelectList(ViewBag.Quantity, "Text", "Value"))
<input type="submit" value="Dodaj przedmioty"/>
}
}
</div>
DropDownList doesn't pass a Value to "quantity" parameter in Create method, what is wrong here?
OK I changed #Html.DropDownList("quantity", ViewBag.Quantity as SelectList) and now it works as it should work.
Related
In a ASP.NET MVC (Razor) project, I'm using a ListBox with Multi Select option in a Edit View,
CONTROLLER
public ActionResult Edit(int id)
{
Post post = db.Posts.Find(id);
string selectedValues = post.Tags; //This contains Selected values list (Eg: "AA,BB")
ViewBag.Tagslist = GetTags(selectedValues.Split(','));
return View(post);
}
private MultiSelectList GetTags(string[] selectedValues)
{
var tagsQuery = from d in db.Tags
orderby d.Name
select d;
return new MultiSelectList(tagsQuery, "Name", "Name", selectedValues);
}
HTML
<div class="editor-field">
#Html.ListBox("Tags", ViewBag.Tagslist as MultiSelectList)
</div>
This loads the items (Tag List) in to ListBox, but does not highlight the items in the Selected Values list.
How to fix this issue?
Thanks in advance.
I suspect that your Post class (to which your view is strongly typed) has a property called Tags. You also use Tags as first argument of the ListBox helper. This means that the helper will look into this property first and ignore the selected values you passed to the MultiSelectList. So the correct way to set a selected value is the following:
public ActionResult Edit(int id)
{
Post post = db.Posts.Find(id);
ViewBag.Tagslist = GetTags();
return View(post);
}
private MultiSelectList GetTags()
{
var tagsQuery = from d in db.Tags
orderby d.Name
select d;
return new MultiSelectList(tagsQuery, "Name", "Name");
}
and in the view:
<div class="editor-field">
#Html.ListBoxFor(x => x.Tags, ViewBag.Tagslist as MultiSelectList)
</div>
And here's a full example that should illustrate:
public class HomeController : Controller
{
public ActionResult Index()
{
var post = new Post
{
Tags = new[] { "AA", "BB" }
};
var allTags = new[]
{
new { Name = "AA" }, new { Name = "BB" }, new { Name = "CC" },
};
ViewBag.Tagslist = new MultiSelectList(allTags, "Name", "Name");
return View(post);
}
}
Also I would recommend you using view models instead of passing your domain entities to the view. So in your PostViewModel you will have a property called AllTags of type MultiSelectList. This way you will be able to get rid of the weak typed ViewBag.
I can't figure out why when it hits my action method, carFileName is null. I debugged the view and when I iterate through that foreach loop, there is indeed different values in each iteration of that loop for carContent.CarFileName. So for each button when submitted, it should submit the carFileName associated with that particular button.
#if (Model.CarFiles != null && Model.CarnFiles.Count > 0)
{
#foreach (CarContent carContent in Model.CarFiles)
{
using (Html.BeginForm("GetfileDownloadUrl", "Car", FormMethod.Get, new { carId = Model.CarId, userId = Model.UserId, #carFileName = carContent.CarFileName }))
{
#Html.Hidden("userId", Model.UserId);
#Html.Hidden("carId", Model.CarId);
#Html.Hidden("carFileName", carContent.CarFileName);
<p><input type="submit" name="SubmitCommand" value="download" /> #carContent.Name</p>
}
}
}
Here's my action method signature:
[HttpGet]
public string GetFilDownloadUrl(string carFileUrl, int carId, int userId)
{
...
}
Here's the route:
routes.MapRoute("CarDownloadFile", "Cars/{carId}/{userId}/{carFileName}", new { controller = "Car", action = "GetFileDownloadUrl", carnId = UrlParameter.Optional, userId = UrlParameter.Optional, carFileName = UrlParameter.Optional });
Could be because in your route you refer to carFileName, but your action method takes carFileUrl and you carId in your RouteValueDictionary is spelt carnId
How to get the radio button options from database using in MVC3 Razor. I have 4 options for each question, the options should be populated from the database and should be grouped.
#Html.RadioButtonFor(model => Model.AAAa, 'Y', new { title = "Please check this if AAA has been updated" })
Yes
This gives me hard coded value as Yes but text needs to be populated with DB Table.
How would I bind it back the selected value back to the database?. An Example would be more helpful.
Thank you
As always you start by defining a view model that will represent the information you will be dealing with in the view:
public class MyViewModel
{
public string SelectedValue { get; set; }
// In your question you seem to be dealing with a title attribute as well
// If this is the case you could define a custom view model ItemViewModel
// which will contain the Value, the Text and the Title properties for
// each radio button because the built-in SelectListItem class that I am using here
// has only Value and Text properties
public SelectListItem[] Items { get; set; }
}
then you write a controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel
{
// Obviously those will come from your database or something
Items = new[]
{
new SelectListItem { Value = "Y", Text = "Yes" },
new SelectListItem { Value = "N", Text = "No" },
new SelectListItem { Value = "D", Text = "Dunno" }
}
};
return View(model);
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
return View(model);
}
}
then a corresponding view:
#model MyViewModel
#using (Html.BeginForm())
{
for (int i = 0; i < Model.Items.Count; i++)
{
#Html.RadioButtonFor(x => x.SelectedValue, Model.Items[i].Value, new { id = "item_" + i })
#Html.Label("item_" + i, Model.Items[i].Text)
<br/>
}
<button type="submit">OK</button>
}
or to make the view less messy you could write a custom HTML helper that will render those radio buttons for you:
public static class HtmlExtensions
{
public static IHtmlString RadioButtonListFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
IEnumerable<SelectListItem> items
)
{
var sb = new StringBuilder();
var i = 0;
foreach (var item in items)
{
var id = string.Format("item{0}", i++);
var radio = htmlHelper.RadioButtonFor(expression, item.Value, new { id = id });
var label = htmlHelper.Label(id, item.Text);
sb.AppendFormat("{0}{1}<br/>", radio, label);
}
return new HtmlString(sb.ToString());
}
}
and now your view will simply become:
#model MyViewModel
#using (Html.BeginForm())
{
#Html.RadioButtonListFor(x => x.SelectedValue, Model.Items)
<button type="submit">OK</button>
}
which obviously is nicer to look.
How can I create a checkboxList in asp.net MVC and then to handle the event with the checkboxList
You could have a view model:
public class MyViewModel
{
public int Id { get; set; }
public bool IsChecked { get; set; }
}
A controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new[]
{
new MyViewModel { Id = 1, IsChecked = false },
new MyViewModel { Id = 2, IsChecked = true },
new MyViewModel { Id = 3, IsChecked = false },
};
return View(model);
}
[HttpPost]
public ActionResult Index(IEnumerable<MyViewModel> model)
{
// TODO: Handle the user selection here
...
}
}
A View (~/Views/Home/Index.cshtml):
#model IEnumerable<AppName.Models.MyViewModel>
#{
ViewBag.Title = "Home Page";
}
#using (Html.BeginForm())
{
#Html.EditorForModel()
<input type="submit" value="OK" />
}
and the corresponding Editor template (~/Views/Home/EditorTemplates/MyViewModel.cshtml):
#model AppName.Models.MyViewModel
#Html.HiddenFor(x => x.Id)
#Html.CheckBoxFor(x => x.IsChecked)
Now when you submit the form you would get a list of values and for each value whether it is checked or not.
There is even simpler way - use custom #Html.CheckBoxList() extension from here:
http://www.codeproject.com/KB/user-controls/MvcCheckBoxList_Extension.aspx
Usage example (MVC3 view with Razor view engine):
#Html.CheckBoxList("NAME", // NAME of checkbox list
x => x.DataList, // data source (list of 'DataList' in this case)
x => x.Id, // field from data source to be used for checkbox VALUE
x => x.Name, // field from data source to be used for checkbox TEXT
x => x.DataListChecked // selected data (list of selected 'DataList' in thiscase),
// must be of same data type as source data or set to 'NULL'
)
This is how I create my dropdown
#Html.DropDownListFor(model => model.NewPageModel.AvailablePageModels, new SelectList(Model.NewPageModel.AvailablePageModels, "Text", "Value"))
and this is how my AvailablePageModels looks like
public IEnumerable<SelectListItem> AvailablePageModels
{
get
{
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
foreach (var type in assembly.GetTypes())
{
if (type.GetCustomAttributes(typeof(PageModelAttribute), true).Length > 0)
{
yield return new SelectListItem { Text = type.Name, Value = type.Name };
}
}
}
}
}
and when I post my form to the following action my modelstate is always invalid and the error occur on the AvailablePageModel value? Maybe I cannot use the NewPageModel as a parameter this way?
public ActionResult Create([Bind(Prefix = "NewPageModel")] NewPageModel newPageModel, FormCollection collection)
{
if(ModelState.IsValid) {
// always invalid
}
}
You need 2 fields, one for the available options in the drop down list and one for storing the selected value
Html.DropDownListFor(m => m.NewPageModel.SelectedModel,
new SelectList(Model.NewPageModel.AvailablePageModels, "Text", "Value"))