I need help to bind drop-down values from models.
Model.cs
public class BloodGroup
{
public BloodGroup()
{
ActionsList = new List<SelectListItem>();
}
[Display(Name="Blood Group")]
public int Group { get; set; }
public IEnumerable<SelectListItem> ActionsList { get; set; }
}
public class ActionType
{
public int GroupId { get; set; }
public string BloodGroup { get; set; }
}
In the Controller:
List<ActionType> actionType = GetCourses();
bGroup.ActionsList = from action in actionType
select new SelectListItem
{
Text = action.BloodGroup,
Value = ((int)action.GroupId).ToString(),
Selected = action.BloodGroup.Equals("A+")?true:false
};
return view;
public List<ActionType> GetCourses()
{
return new List<ActionType> {
new ActionType () { GroupId = 1, BloodGroup = "A+"},
new ActionType () { GroupId = 2, BloodGroup = "B+"},
new ActionType () { GroupId = 3, BloodGroup = "O+" },
new ActionType () { GroupId = 4, BloodGroup = "AB+" },
new ActionType () { GroupId = 5, BloodGroup = "A-"},
new ActionType () { GroupId = 6, BloodGroup = "B-"},
new ActionType () { GroupId = 7, BloodGroup = "O-" },
new ActionType () { GroupId = 8, BloodGroup = "AB-" }
};
}
It successfully return to view. But in view when bind dropdown it throws an error.
in view
#model MyMVC.Models.BloodGroup
#Html.DropDownListFor(m => m.Group, new SelectList(Model.ActionsList, "Value", "Text",true), "-- Select --")</li>
It returns error.
Object reference not set to an instance of an object.
Model.ActionsList is set a Null.
I don't know why it shows null, though I inherit the model.
I need help on how to bind the SelectList value to dropdown
You need to pass a instance of BloodGroup class to the view in your action method, like below:
public ActionResult YourAction()
{
List<ActionType> actionType = GetCourses();
var model = new BloodGroup()
{
ActionsList = (from action in actionType
select new SelectListItem
{
Text = action.BloodGroup,
Value = ((int) action.GroupId).ToString(),
Selected = action.BloodGroup.Equals("A+")
})
};
return View(model);
}
Then in your view:
#model BloodGroup
#Html.DropDownListFor(m => m.Group, Model.ActionsList,"-- Select --")
Notice
Using above example it'll show you the view without errors, but the selected item in your downdownList will NOT show correctly. For showing the selected item correctly, you need to change the type of Grop property to String, like below:
public class BloodGroup
{
//
[Display(Name = "Blood Group")]
public string Group { get; set; }
//
}
Then use above same action method, make your view like:
#model BloodGroup
#Html.DropDownList("Group", Model.ActionsList, "-- Select --")
Related
I have a select control with static values in my view and I intend the user select a value and it binds to my controller so I can use it in the required action method.
My View -
#model StockProject.ViewModels.EquityViewModel
#using (Html.BeginForm(FormMethod.Post)){
#{
var selectList = new SelectList(
new List<SelectListItem>
{
new SelectListItem {Text = "BOOKED", Value = "1"},
new SelectListItem {Text = "EXECUTING", Value = "2"},
new SelectListItem {Text = "EXECUTED", Value = "3"},
new SelectListItem {Text = "SUSPENDED", Value = "4"},
new SelectListItem {Text = "CANCELLED", Value = "5"},
}, "Value", "Text");
}
#Html.DropDownListFor(model => model.status, selectList, new { #class = "form-control", name = "status", id = "status" })
<div class="col-md-3 form-group">
<button type="button" class="btn btn-success btn-block form-control" onclick="location.href='#Url.Action("Equity", "Order")'">
Go
<i class="fa fa-arrow-circle-right"></i>
</button>
</div>
}
ViewModel -
public class EquityViewModel
{
public int CustomerId { get; set; }
public string status { get; set; }
public DateTime startdate { get; set; }
public DateTime enddate { get; set; }
public List<ListEquityOrder> ListOrderEquity { get; set; }
public EquityViewModel()
{
ListOrderEquity = new List<ListEquityOrder>();
}
}
Controller -
[HttpGet]
public IActionResult Equity()
{
var modelview = new EquityViewModel();
var model = new EquityRequest();
model.CustomerId = _appSettings.TestCustomerId;
model.RequestStartPoint = 0;
model.NoOfRequests = 1000000;
model.Null = null;
model.Status = modelview.status;
model.StartDate = modelview.StartDate;
model.EndDate = modelview.EndDate;
model.Equity = "EQUITY";
EquityResponse ListEquityOrders = _genericService.CallSoapAction<EquityResponse, EquityRequest>(model, "findCustomerOrdersBySecurityType");
List<ListEquityOrder> findCusOrder = new List<ListEquityOrder>();
foreach (var t in ListEquityOrders.Item)
{
ListEquityOrder listOrder = new ListEquityOrder();
listOrder.BusinessOffice = t.BusinessOffice;
listOrder.CustomerLabel = t.CustomerLabel;
listOrder.CustomerName = t.CustomerName;
listOrder.Exchange = t.Exchange;
listOrder.FixOrderStatus = t.FixOrderStatus;
//adding other data values to the list
findCusOrder.Add(listOrder);
}
modelview.ListOrderEquity = findCusOrder;
return View(modelview);
}
Anytime the user clicks on the submit button, no values are passed the controls - the DropDownListFor and TexBoxes. I have tried FormCollection but that doesn't work. Please how do I resolve this?
You can use the following code getting the expected output.
In your model
public enum BookingDetails
{
BOOKED = 1, EXECUTING = 2, EXECUTED = 3, SUSPENDED = 4, CANCELLED = 5
}
public class SomeModel
{
public BookingDetails bookingDetails { get; set; }
public static IEnumerable<SelectListItem> GetBookingDetailsSelectItems()
{
yield return new SelectListItem { Text = "BOOKED", Value = "1" };
yield return new SelectListItem { Text = "EXECUTING", Value = "2" };
yield return new SelectListItem { Text = "EXECUTED", Value = "3" };
yield return new SelectListItem { Text = "SUSPENDED", Value = "4" };
yield return new SelectListItem { Text = "CANCELLED", Value = "5" };
}
}
Note : The above model only deals with dropdown values. If you want to do more then fell free to extend the class
Then your controller should be like below
public class MyController : Controller
{
// GET: My
public ActionResult MyAction()
{
// shows your form when you load the page
return View();
}
[HttpPost]
public ActionResult MyAction(SomeModel model)
{
var selectedBookingDetails = model.bookingDetails;// this will be the selected dropdown item text.
return View(model);
}
}
then view
#model SomeModel
#using (Html.BeginForm("MyAction", "My", FormMethod.Post))
{
#Html.DropDownListFor(m => m.bookingDetails, SomeModel.GetBookingDetailsSelectItems())
<input type="submit" value="Send" />
}
Note : please include the correct namespace of model
Theres links already on how to use multiple models for a view with different ways to do it, however, I tried those and could not get them to work, what am I doing wrong?
I simply want two form inputs in 1 view, and one model, but one of the form inputs uses a list<'model'> and the other uses 'model', here's what I mean:
UPDATE: copy/paste this code, if you select and submit any check box items you will get an error at #Model.input.passWord and I have no idea why, checkbox items wont show either, need help.
View (Index.cshtml):
#using stupidassTests.Models
#model MyViewModel
#{
ViewBag.Title = "Index";
}
<h2>Password Input</h2>
<div>
<p>Enter Password</p>
#using (Html.BeginForm("Index", "Home", FormMethod.Get))
{
#Html.TextBox("password")
<button type="submit" value="Search"></button>
}
<p>#Model.input.passWord</p> <!--passWord is underlined with red because it conflicts with the List'model'-->
</div>
<h2>Checkbox</h2>
<div>
#using (Html.BeginForm())
{
for (var i = 0; i < Model.inputCollection.Count; i++)
{
<p>
#Html.HiddenFor(n => n.inputCollection[i].Id)
#Html.DisplayFor(n => n.inputCollection[i].Name)
#Html.HiddenFor(n => n.inputCollection[i].Name)
#Html.CheckBoxFor(n => n.inputCollection[i].Checked)
</p>
}
<input id="Submit1" type="submit" value="submit" />
if (ViewBag.Values != null)
{
foreach (var item in ViewBag.Values)
{
<p>#item</p>
}
}
}
So as you can see, copy/paste my code and try to run it, 'password' form input is being shoved out by 'checkbox' input, it seems the two '#model' are conflicting under one model class, how do I fix this?
Controller (HomeController.cs):
public ActionResult Index()
{
return View();
}
[HttpGet, ActionName("Index")]
public ActionResult PasswordInput(string password)
{
FormInputs pss = new FormInputs();
pss.passWord = password;
MyViewModel mvm = new MyViewModel() { input = pss, isList = false };
return this.View("Index", mvm);
}
[HttpGet]
public ActionResult CheckBoxGet()
{
var list = new List<FormInputs>
{
new FormInputs { Id = 1, Name = "Aquafina", Checked = false },
new FormInputs { Id = 2, Name = "Mulshi Springs", Checked = false },
new FormInputs { Id = 3, Name = "Alfa Blue", Checked = false },
new FormInputs { Id = 4, Name = "Atlas Premium", Checked = false },
new FormInputs { Id = 5, Name = "Bailley", Checked = false },
new FormInputs { Id = 6, Name = "Bisleri", Checked = false },
new FormInputs { Id = 7, Name = "Himalayan", Checked = false },
new FormInputs { Id = 8, Name = "Cool Valley", Checked = false },
new FormInputs { Id = 9, Name = "Dew Drops", Checked = false },
new FormInputs { Id = 10, Name = "Dislaren", Checked = false },
};
MyViewModel mvm = new MyViewModel() { inputCollection = list, isList = true };
return this.View("Index", mvm);
}
[HttpPost]
public ActionResult CheckBoxPost(List<FormInputs> list)
{
var selected = list.Where(x => x.Checked).Select(x => x.Name);
ViewBag.Values = selected;
MyViewModel mvm = new MyViewModel() { inputCollection = list, isList = true };
return this.View("Index", mvm);
}
Model (FormInputs.cs):
public class MyViewModel
{
public FormInputs input;
public List<FormInputs> inputCollection;
public bool isList;
}
public class FormInputs
{
public string passWord = "";
public int Id { get; set; }
public string Name { get; set; }
public bool Checked { get; set; }
public List<string> checkBox = new List<string>();
}
So just as a summary, because I'm a beginner at MVC, how do I re-work this code (btw copy/paste it) so that both form inputs can co-exist in 1 view?
You can use viewmodel.
Use ViewModel
For view model you have to create a class and in this class you will define all models as properties of this class.Here are two classes.
public class EmployeeDetails
{
[Required]
[Display(Name = "Name")]
public string Name { get; set; }
}
public class Employee
{
public int Id { get; set; }
}
Here is viewmodel
public class ViewModel
{
public Employee emp { get; set; }
public EmployeeDetails empdet{ get; set; }
}
Now in Controller you will do like this
public ActionResult About()
{
ViewModel vm = new ViewModel();
vm.emp = new Employee();
vm.empdet = new EmployeeDetails();
return View(vm);
}
And in view you will receive it like this
#model ViewModel
This might be a good example to use the Composite Pattern. You can have a ViewModel with two properties:
public class MyViewModel{
public FormInputs input;
public List<FormInputs> inputCollection;
public bool isList;
}
And arrange the data accordingly:
public ActionResult PasswordInput(string password)
{
FormInputs pss = new FormInputs();
pss.passWord = password;
MyViewModel mvm = new MyViewModel(){input = pss, isList = false}
return this.View("Index", mvm);
}
AND
public ActionResult CheckBoxGet()
{
var list = new List<FormInputs>
{
new FormInputs { Id = 1, Name = "Aquafina", Checked = false },
new FormInputs { Id = 2, Name = "Mulshi Springs", Checked = false },
new FormInputs { Id = 3, Name = "Alfa Blue", Checked = false },
new FormInputs { Id = 4, Name = "Atlas Premium", Checked = false },
new FormInputs { Id = 5, Name = "Bailley", Checked = false },
new FormInputs { Id = 6, Name = "Bisleri", Checked = false },
new FormInputs { Id = 7, Name = "Himalayan", Checked = false },
new FormInputs { Id = 8, Name = "Cool Valley", Checked = false },
new FormInputs { Id = 9, Name = "Dew Drops", Checked = false },
new FormInputs { Id = 10, Name = "Dislaren", Checked = false },
};
MyViewModel mvm = new MyViewModel(){inputCollection = list , isList = true}
return this.View("Index", mvm);
}
AND in view, use this:
#model MyViewModel
Check the isList property before using the input/inputCollection
I'm trying to return a SelectList with <optgroup>'s using SelectListGroup, but the code below only returns the values in the SelectList without the groups. How can I have my select list separated by groups?
public SelectList MyList()
{
var group1 = new SelectListGroup() { Name = "Group 1" };
var group2 = new SelectListGroup() { Name = "Group 2" };
var items = new List<SelectListItem>();
items.Add(new SelectListItem() { Value = "1", Text = "Item 1", Group = group1 });
items.Add(new SelectListItem() { Value = "2", Text = "Item 2", Group = group2 });
return new SelectList(items, "Value", "Text");
}
I find this method works, which uses a strongly-typed approach:
View model:
public class PageViewModel
{
public int SelectedDropdownItem { get; set; }
public IEnumerable<SelectListItem> DropdownList { get; set; }
}
Example entity model (for this example):
public class Entity
{
public int Id { get; set; }
public string Name { get; set; }
public bool IsActive { get; set; }
public bool IsDefault { get; set; }
}
Controller:
// Get list for the dropdown (this uses db values)
var entityList = db.Entity.ToList();
// Define the Groups
var group1 = new SelectListGroup { Name = "Active" };
var group2 = new SelectListGroup { Name = "Allowed" };
// Note - the -1 is needed at the end of this - pre-selected value is determined further down
// Note .OrderBy() determines the order in which the groups are displayed in the dropdown
var dropdownList = new SelectList(entityList.Select(item => new SelectListItem
{
Text = item.Name,
Value = item.Id,
// Assign the Group to the item by some appropriate selection method
Group = item.IsActive ? group1 : group2
}).OrderBy(a => a.Group.Name).ToList(), "Value", "Text", "Group.Name", -1);
// Assign values to ViewModel
var viewModel = new PageViewModel
{
// Assign the pre-selected dropdown value by appropriate selction method (if needed)
SelectedDropdownItem = entityList.FirstOrDefault(a => a.IsDefault).Id,
DropdownList = dropdownList
};
View:
<!-- If needed, change 'null' to "Please select item" -->
#Html.DropDownListFor(a => a.SelectedDropdownItem, Model.DropdownList, null, new { #class = "some-class" })
Hope it helps someone.
My model is a generic List. I want to use DropDownList for foreign key property binding.
My code is
Model
public class PersonViewModel
{
public int Id { get; set; }
public string LastName{get;set;}
public int NationalityId { get; set; }
}
public class Nationality
{
public int Id { get; set; }
public string Name { get; set; }
}
Controller
public ActionResult Index()
{
var nationalities = new List<Nationality>
{
new Nationality{Id = 0, Name = "CHOOSE NATIONALITY..."},
new Nationality{Id = 1, Name = "POLAND"},
new Nationality{Id = 2, Name = "USA"},
new Nationality{Id = 3, Name = "CANADA"}
};
var Nationalities = new SelectList(nationalities, "Id", "Name");
var persons = new List<PersonViewModel>
{
new PersonViewModel{Id = 1, LastName = "KOWALSKI", NationalityId = 1},
new PersonViewModel{Id = 1, LastName = "SMITH", NationalityId = 2},
new PersonViewModel{Id = 1, LastName = "SCHERBATSKY", NationalityId = 3}
};
ViewBag.Nationalities = Nationalities;
return View(persons);
}
View
#model List<PersonViewModel>
#Html.EditorFor(m=> Model[0].LastName)
#Html.DropDownListFor(m => Model[0].NationalityId, (SelectList)ViewBag.Nationalities)
#Html.EditorFor(m => Model[1].LastName)
#Html.DropDownListFor(m => Model[1].NationalityId, (SelectList)ViewBag.Nationalities)
#Html.EditorFor(m => Model[2].LastName)
#Html.DropDownListFor(m => Model[2].NationalityId, (SelectList)ViewBag.Nationalities)
Anyone can tell me why NationalityId property is not bound well
I can't upload image but it's not binding at all. Every DropDownList has 'CHOOSE NATIONALITY...' .
I would recommend you using Editor templates:
First - create view Shared\EditorTemplates\PersonViewModel.cshtml containing:
#model PersonViewModel
#Html.EditorFor(m => Model.LastName)
#Html.DropDownListFor(m => Model.NationalityId, (SelectList)ViewBag.Nationalities)
And in your current view
#for (int i = 0; i < Model.Count; i++)
{
#Html.EditorFor(x => Model[i])
}
Change your view model to this
public class PersonViewModel
{
public int Id { get; set; }
public string LastName{get;set;}
public int NationalityId { get; set; }
public IEnumerable<Nationality> Nationalities {get;set;}
}
In your controller
public ActionResult Index()
{
var nationalities = new List<Nationality>
{
new Nationality{Id = 0, Name = "CHOOSE NATIONALITY..."},
new Nationality{Id = 1, Name = "POLAND"},
new Nationality{Id = 2, Name = "USA"},
new Nationality{Id = 3, Name = "CANADA"}
};
var nationalities = new SelectList(nationalities, "Id", "Name");
var persons = new List<PersonViewModel>
{
new PersonViewModel{Id = 1, LastName = "KOWALSKI", NationalityId = 1 , Nationalities = nationalities},
new PersonViewModel{Id = 1, LastName = "SMITH", NationalityId = 2, Nationalities = nationalities},
new PersonViewModel{Id = 1, LastName = "SCHERBATSKY", NationalityId = 3, Nationalities = nationalities}
};
return View(persons);
}
And in your view
#model List<PersonViewModel>
#Html.EditorFor(m => m[0].LastName)
#Html.DropDownListFor(m => m[0].NationalityId, Model[0].Nationalities)
#Html.EditorFor(m => m[1].LastName)
#Html.DropDownListFor(m => m[1].NationalityId, Model[1].Nationalities)
#Html.EditorFor(m => m[2].LastName)
#Html.DropDownListFor(m => m[2].NationalityId, Model[2].Nationalities)
Two things:
Each dropdown needs its own select list. Currently you are using the same select list for each dropdown.
You need to specify a selected value for each select list, like so:
new SelectList(nationalities, "Id", "Name", persons[0].NationalityId);
I have been reading tutorials on Linq and Lambda expressions all afternoon. I'll get it eventually and it won't take me that long, but maybe someone can show me an example of how to do what I'm trying for and I'll grasp it quicker.
I have a client side jQuery script that calls a routine in my Controller that returns a JsonResult.
Given ViewModels of:
public class Country
{
[Key]
public int Id { get; set; }
[Index("UX_Country_CountryCode", IsUnique = true)]
[MaxLength(5)]
public string CountryCode { get; set; }
public string CountryName { get; set; }
public virtual ICollection<State> States { get; set; }
}
public class State
{
[Key]
public int Id { get; set; }
[Index("UX_State_StateCodeCountryId", IsUnique = true, Order = 1)]
[MaxLength(5)]
public string StateCode { get; set; }
public string StateName { get; set; }
[ForeignKey("Country")]
[Index("UX_State_StateCodeCountryId", IsUnique = true, Order = 0)]
public int CountryId { get; set; }
public virtual Country Country { get; set; }
}
Example data:
new Country { Id = 1, CountryCode = "USA", CountryName = "United States" };
new Country { Id = 2, CountryCode = "CAN", CountryName = "Canada" };
new State { Id = 1, StateCode = "FL", StateName = "Florida", CountryId = 1 };
new State { Id = 2, StateCode = "CA", StateName = "California", CountryId = 1 };
new State { Id = 3, StateCode = "IA", StateName = "Iowa", CountryId = 1 };
Call the following with a URI of /Controller/StateList/USA
[AllowAnonymous]
[AcceptVerbs(HttpVerbs.Get)]
public JsonResult StateList(string Id)
{
// I need to know the Id of CountryCode == "USA"
// Get <Country> with CountryCode == "USA". (I think this works)
IEnumerable<SelectListItem> country = from c in GetCountryList()
where c.Value == Id
select c;
// Now get all states where <State>.CountryId == country.Id
var state = from State s in dbLocations.States
where s.CountryId == country.id
select s;
return Json(new SelectList(state.ToArray(), "StateCode", "StateName"), JsonRequestBehavior.AllowGet);
}
public IEnumerable<SelectListItem> GetCountryList()
{
var countries = new SelectList(dbLocations.Countries, "CountryCode", "CountryName").ToList();
countries.Insert(0, (new SelectListItem { Text = "Select Country", Value = "-1" }));
countries.Insert(1, (new SelectListItem { Text = "United Sates", Value = "USA" }));
countries.Insert(2, (new SelectListItem { Text = "Canada", Value = "CAN" }));
countries.Insert(3, (new SelectListItem { Text = "Mexico", Value = "MEX" }));
countries.Insert(4, (new SelectListItem { Text = "Brazil", Value = "BRA" }));
countries.Insert(5, (new SelectListItem { Text = "------------------------", Value = "-1" }));
IEnumerable<SelectListItem> countrylist =
countries.Select(m => new SelectListItem()
{
Text = m.Text,
Value = m.Value
});
return countrylist;
}
I've made several attempts at the StateList() code and just not grasping how to do this using Linq. I think GetCountryList() is ok - I use it many times elsewhere in the app. How would StateList() best be coded?
Also, I've found some Linq tutorials, but they're not clicking. Anyone know of a good one?
The simplest way would be to access dbLocations and fetch the country from the database directly.
[AllowAnonymous]
[AcceptVerbs(HttpVerbs.Get)]
public JsonResult StateList(string Id)
{
// Get the country by Country Code
var country = dbLocations.Countries.FirstOrDefault(c => c.CountryCode == Id);
// Get all states where countryId equals the Id from the action
var states = from State s in dbLocations.States
where s.CountryId == country.Id
select s;
return Json(new SelectList(states.ToArray(), "StateCode", "StateName"), JsonRequestBehavior.AllowGet);
}
EDIT: You may think of switching the Value of SelectedListItem to the Country.Id instead of Country.CountryCode the value is not seen in the UI anyway. This way it would be easier to access the country by its Id instead of CountryCode