In MVC web app it is a view with strongly typed model where a drop down is being generated / bind by model.
Below is view code:
#model LoanViewModel
<form class="wrapper minheight homeloan-form border-top" id="homeloan-form" method="post" action="LeadContact" novalidate="novalidate">
<p>#Html.ValidationSummary()</p>
<p>Select an Item : #Html.DropDownListFor(x => x.HomeLoanLead.Items, new SelectList(Model.HomeLoanLead.Items), "--Choose any Item--")</p>
<div class="formnav row">
<button class="">Show Top Home Loans <i class="fa fa-chevron-right"></i></button>
</div>
</form>
In model I m hardcoding options for drop down list:
public List<string> Items
{
get { _items = new List<string>();
_items.Add("One");
_items.Add("Two");
_items.Add("Three");
return _items;
}
}
On post back I cant get what was selected value in drop down. Please guide me how to get in post action which drop down value was selected.
A simple example of using Html.DropDownFor() to display a list of options and bind to a property:
Model
public class LoanViewModel
{
[Required]
[Display(Name="Select Item")]
public string Item { get; set; }
public SelectList ItemList { get; set; }
}
Controller
public ActionResult Edit()
{
LoanViewModel model = new LoanViewModel();
model.Item = "Two"; // this will now pre-select the second option in the view
ConfigureEditModel(model);
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(LoanViewModel model)
{
if (!ModelState.IsValid)
{
ConfigureEditModel(model); // repopulate select list
return View(model); // return the view to correct errors
}
// If you want to validate the the value is indeed one of the items
ConfigureEditModel(model);
if (!model.ItemList.Contains(model.Item))
{
ModelState.AddModelError(string.Empty, "I'm secure!");
return View(model);
}
string selectedItem = model.Item;
....
// save and redirect
}
private void ConfigureEditModel(LoanViewModel model)
{
List<string> items = new List<string>() { "One", "Two", "Three" };
model.ItemList = new SelectList(items); // create the options
// any other common stuff
}
View
#model LoanViewModel
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
#Html.DisplayFor(m => m.Item)
#Html.DropDownListFor(m => m.Item, Model.ItemList), "--Choose any Item--")
#Html.ValidationMessageFor(m => m.Item)
<input type="submit" value="Submit" />
}
Related
I have two related ddl's. When page loads, I can POST them to controller and everything is ok. But also I have some fields in page, and if they are empy I call ModalError in my controller, then page should be reloaded with text of errors. But it throughs an error, that says IEnumerable<SelectList> with name City is empty. What is the problem?
View:
#using (#Html.BeginForm())
{
<div>
#Html.LabelFor(model=>model.Buyer.buyers_name)
</div>
<div>
#Html.EditorFor(model=>model.Buyer.buyers_name)
#Html.ValidationMessageFor(model=>model.Buyer.buyers_name)
</div>
<div>
#Html.LabelFor(model=>model.Buyer.buyers_email)
</div>
<div>
#Html.EditorFor(model=>model.Buyer.buyers_email)
#Html.ValidationMessageFor(model=>model.Buyer.buyers_email)
</div>
<div>
#Html.LabelFor(model=>model.Buyer.buyers_phone)
</div>
<div>
#Html.EditorFor(model=>model.Buyer.buyers_phone)
#Html.ValidationMessageFor(model=>model.Buyer.buyers_phone)
</div>
<div>
<h2>Выберите адрес доставки:</h2>
<h3>Выберите город</h3>
#Html.DropDownList("City", ViewBag.cities as SelectList, new { id = "city" })
<h3>Выберите адрес</h3>
#Html.DropDownList("Address", ViewBag.addresses as SelectList, new { id = "address" })
</div>
<input type="submit" value="Send" class="btn" />
}
Controller:
public ActionResult GetItems(decimal id)
{
return PartialView(_db.bs_delivery_type.Where(x => x.delivery_city_id == id).ToList());
}
public ActionResult Checkout()
{
int selectedIndex = 1;
SelectList cities = new SelectList(_db.bs_cities, "cities_id", "cities_name", selectedIndex);
ViewBag.cities = cities;
SelectList addresses = new SelectList(_db.bs_delivery_type.Where(x => x.delivery_city_id == selectedIndex), "delivery_id", "delivery_address");
ViewBag.addresses = addresses;
return View();
}
[HttpPost]
public ActionResult Checkout(Cart cart, DeliveryModel deliveryModel, decimal city, decimal address)
{
if (cart.Lines.Count() == 0)
{
ModelState.AddModelError("", "Your cart is empty");
}
if (ModelState.IsValid)
{
//adds to db;
return View("Completed");
}
else
{
return View(deliveryModel);
}
}
DeliveryModel:
public class DeliveryModel
{
public bs_buyers Buyer { get; set; }
public List<bs_cities> CitiesModel { get; set; }
public SelectList FilteredDelivery { get; set; }
}
Also PartialView GetItems:
<select id="address" name="Address">
#foreach (var item in Model)
{
<option value="#item.delivery_id">#item.delivery_address</option>
}
As you invoke the Checkout Action in your Controller via HttpPost you then return the Checkout View in case the ModelState is invalid. However you do net set your ViewBag Variables as you do in your HttpGet Action.
You have to set ViewBag Variables in each and every Action. In this case I would recommend a separate method that gets invoked in both Actions.
private void SetViewBagForCheckout(){
int selectedIndex = 1;
SelectList cities = new SelectList(_db.bs_cities, "cities_id", "cities_name", selectedIndex);
ViewBag.cities = cities;
SelectList addresses = new SelectList(_db.bs_delivery_type.Where(x => x.delivery_city_id == selectedIndex), "delivery_id", "delivery_address");
ViewBag.addresses = addresses;
}
Like Title
I step by step with examples
I can pass SelectItemList to View from controller to do DropDownList
But I Can't get a value from View to Controller
Have someone can teach me how to do with MVC
this is my
Controller
var Course = getCourseList.getCourse();
if (Course.Any())
{
List<SelectListItem> items = new List<SelectListItem>();
foreach (var course in Course)
{
items.Add(new SelectListItem()
{
Text = course.RC_NAME,
Value = course.RC_MAJORCODE,
});
}
ViewBag.SelectList = items;
}
And this is my View
#using YTDT_OAuth.Models
#model List<CourseInfo>
#using (Html.BeginForm("CourseSave", "Home"))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<table class="table">
<tr>
<th scope="row">first</th>
<td>#Html.DropDownList("SelectList", null, "default", new {#id = "a" })</td>
#foreach (var item in Model)
{
<p>#item.RC_MAJORCODE</p>
}
</tr>
</table>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
and I want to do something in this controller
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult CourseSave(CourseInfo CourseDataz)
{
// the value is received in the controller.
return View();
}
I personally like to use strongly-typed Model instead of ViewBag. ViewData and ViewBag are dynamic, and they throw run-time error rather than compile-time error.
Sample Code
Model
public class CourseInfo
{
public string SelectedMajorCode { get; set; }
public IList<SelectListItem> AvailableMajorNames { get; set; }
public CourseInfo()
{
AvailableMajorNames = new List<SelectListItem>();
}
}
View
#model DemoMvc.Models.CourseInfo
#using (Html.BeginForm("Index", "Home"))
{
#Html.DropDownListFor(m => m.SelectedMajorCode, Model.AvailableMajorNames)
<input type="submit" value="Submit"/>
}
Controller
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new CourseInfo
{
AvailableMajorNames = GetColorListItems()
};
return View(model);
}
[HttpPost]
public ActionResult Index(CourseInfo model)
{
if (ModelState.IsValid)
{
var majorCode = model.SelectedMajorCode;
return View("Success");
}
// If we got this far, something failed, redisplay form
// ** IMPORTANT : Fill AvailableMajorNames again;
// otherwise, DropDownList will be blank. **
model.AvailableMajorNames = GetMajorListItems();
return View(model);
}
private IList<SelectListItem> GetMajorListItems()
{
// This could be from database.
return new List<SelectListItem>
{
new SelectListItem {Text = "One", Value = "1"},
new SelectListItem {Text = "Two", Value = "2"}
};
}
}
In my application, my model contains a field id, and in the view I need to select an id with a radio button and post back the selected id to the controller. How can I do this? My view is as follows,
#model IList<User>
#using (Html.BeginForm("SelectUser", "Users"))
{
<ul>
#for(int i=0;i<Model.Count(); ++i)
{
<li>
<div>
#Html.RadioButtonFor(model => Model[i].id, "true", new { #id = "id" })
<label for="radio1">#Model[i].Name<span><span></span></span></label>
</div>
</li>
}
</ul>
<input type="submit" value="OK">
}
You need to change you model to represent what you want to edit. It needs to include a property for the selected User.Id and a collection of users to select from
public class SelectUserVM
{
public int SelectedUser { get; set; } // assumes User.Id is typeof int
public IEnumerable<User> AllUsers { get; set; }
}
View
#model yourAssembly.SelectUserVM
#using(Html.BeginForm())
{
foreach(var user in Model.AllUsers)
{
#Html.RadioButtonFor(m => m.SelectedUser, user.ID, new { id = user.ID })
<label for="#user.ID">#user.Name</label>
}
<input type="submit" .. />
}
Controller
public ActionResult SelectUser()
{
SelectUserVM model = new SelectUserVM();
model.AllUsers = db.Users; // adjust to suit
return View(model);
}
[HttpPost]
public ActionResult SelectUser(SelectUserVM model)
{
int selectedUser = model.SelectedUser;
}
public class SaleItem
{
public int Id { get; set; }
public string Name { get; set; }
}
public class SalesDBContext
{
public static List<SaleItem> GetItems()
{
var items = new List<SaleItem>(){
new SaleItem{Id=1,Name="Soap"},
new SaleItem{Id=2,Name="Milk Power"},
new SaleItem{Id=3,Name="Toothpaste"},
new SaleItem{Id=4,Name="Ice Cream"}
};
return items.ToList();
}
}
public class SalesViewModel
{
public string Item { get; set; }
public List<SaleItem> itemlist { get; set; }
}
I have above SalesViewModel class and SalesDBContext for dummy data generation. I want to add items to a list selected from a dropdown. For that I have created the following view:
#model MVCDropdown.Models.SalesViewModel
#using MVCDropdown.Models
<form method="post">
<p>
#Html.DropDownListFor(model => model.Item, new SelectList(ViewBag.Items, "Id", "Name"), "--select--")
<input type="submit" value="Add" />
</p>
<p>
#if (Model.itemlist != null)
{
<table>
#foreach (var s in Model.itemlist)
{
<tr>
<td>#s.Name</td>
</tr>
}
</table>
}
</p>
</form>
The Controller
[HttpGet]
public ActionResult Index()
{
SalesViewModel model = new SalesViewModel
{
Item = "",
itemlist = new List<SaleItem>()
};
PopDrodown();
return View(model);
}
[HttpPost]
public ActionResult Index(SalesViewModel vm)
{
var t = SalesDBContext.GetItems().Where(x => x.Id == Convert.ToInt32(vm.Item)).FirstOrDefault();
vm.itemlist.Add(t);
PopDrodown();
return View(vm);
}
private void PopDrodown()
{
ViewBag.Items = SalesDBContext.GetItems();
}
Items added to the list should be displayed in a table under the dropdown. However, when I post post back a selected item from the dropdown by pressing add, it returns a null itemlist to the controller, and previously added items are not there. How can I avoid this problem?
You only have a single input element inside your HTML form: that's the dropdown. So the only value that is sent to your controller action when the form is submitted is the Item property. If you want to send the collection you could use hidden fields:
<table>
#for (var i = 0; i < Model.itemlist.Count; i++)
{
<tr>
<td>
#Html.HiddenFor(x => x.itemlist[i].Id)
#Html.HiddenFor(x => x.itemlist[i].Name)
#Html.DisplayFor(x => x.itemlist[i].Name)
</td>
</tr>
}
</table>
Obviously if the user is not supposed to edit the values inside the HTML form, then a much better approach is to have a POST view model that will contain only the properties that the user can modify and you will retrieve the collection elements from the same place you retrieved them in the GET action.
I have a textbox in which the user can enter their desired username and save it. Once they save it and they happen to revisit their profile page that textbox should be populated with the last username they saved to display and the user will still have the ability to change it and resave. I am fairly new to this and not sure how to start this properly. I am using vs 2012 asp.net mvc 4 c#. Here is my code so far:
#model School.Models.StudentNameModel
#using (Html.BeginForm("_StudentNamePartial", "Profile")) {
#Html.AntiForgeryToken()
#Html.ValidationSummary()
<fieldset>
<ol>
<li>
#Html.LabelFor(m => m.StudentName)
#Html.DisplayFor(m => m.StudentName)
#Html.TextBoxFor(m=>m.StudentName)
<button type="button" value="save" />
</li>
</ol>
</fieldset>
}
This is my Model:
public class StudentNameModel
{
[Display(Name = "Student Name")]
public string StudentName{ get; set; }
}
My controller:
GET - To get the student name from database if one exists.
[HttpPost]
public ActionResult _StudentNamePartial(int id)
{
id = WebSecurity.CurrentStudentId;
var model = new StudentNameModel();
using (var db = new StudentsDataContext())
{
var result = (from u in db.Students
where u.ID == id
select u.StudentName).FirstOrDefault();
if(result != null)
model.StudentName= result;
}
return View(model);
}
POST - This is where i want to save the new username for the student
[HttpPost]
public ActionResult _StudentNamePartial(StudentNameModel model)
{
if (ModelState.IsValid)
{
using (var db = new StudentDataContext())
{
try
{
}
catch (Exception)
{
throw;
}
}
return RedirectToAction("ProfileAccount");
}
return View(model);
}
Also i am having trouble that when i am displaying the username it is not hitting my Action method and it always reports that the Object reference is null. Any help will be great. Thanks :D
It would seem that you're trying to render a partial view from a controller action as part of the larger view. In this case, the partial view should be rendered within the ProfileAccount view.
You can structure the controller and views like this (rough outline):
ProfileAccount View Model:
public class ProfileAccountView
{
public StudentNameModel StudentName { get; set; }
}
Profile Controller:
[HttpGet]
public ActionResult ProfileAccount(int id)
{
// Get whatever info you need and store in a ViewModel
var model = new ProfileAccountView();
// Get the student info and store within ProfileAccountView
// Do your database reads
model.StudentName = new StudentNameModel { StudentName = result };
return View(model);
}
[HttpPost]
public ActionResult ProfileAccount(ProfileAccountView profile)
{
// Do whatever processing here
}
ProfileAccount View
#model School.Models.ProfileAccountView
#using (Html.BeginForm("ProfileAccount", "Profile"))
{
#Html.RenderPartial('_StudentNamePartial', Model.StudentName);
<button type="button" value="save" />
}
_StudentNamePartial Partial View
#model School.Models.StudentNameModel
<fieldset>
<ol>
<li>
#Html.LabelFor(m => m.StudentName)
#Html.TextBoxFor(m=>m.StudentName)
</li>
</ol>
</fieldset>