I have MVC3 website with edit form. On this form there is DropDownList that shows list of values that can be chosen. I want it to be set at previously selected value(on create form). This value is in Model.Status. I thought that this code would work:
#Html.DropDownList("Status",
new SelectList(ViewBag.Status as System.Collections.IEnumerable, "Id", "Status", Model.Status))
But the DropDownList is always set on first value from the list. I have checked - the correct value is in Model.Status.
Value of Model.Status is an id of status from list. ViewBag.Status is a list with id and string description - Status.
How to make it show the right value?
Any help much appreciated!
Have you checked this bug
Avoid to use same name of DropDownListand SelectList.
#Html.DropDownListFor(x=>x.SelectedItemId,
new SelectList(ViewBag.Status as System.Collections.IEnumerable,"Id",
"Status"),"Select Item")
But If i am writing this code, i would get rid of the ViewBag and change that to use another strongly typed object
public class YourMainViewModel
{
public int ID { set;get;}
public int SelectedItemId { set;get;}
public IEnumerable<Item> Items();
//other properties
}
public class Item
{
public int Id { set;get;}
public string Status { set;get;}
}
Instead of sending the collection in Viewbag, i would use my new model properties now
public ActionResult EditUser(int id)
{
var user=myRepositary.GetUser(id);
user.Items=myRepositary.GetAllItems();
user.SelectedItemId=5; // replace with the value from your database here,
}
Now in my View which is strongly typed to YourMainViewModel, I will write this
#Html.DropDownListFor(x=>x.SelectedItemId,
new SelectList(Model.Items,"Id",
"Status"),"Select Item")
Here is some sample code that you can modify and use in your scenario. I have an Edit view, on this view are a list of banks in a dropdown, and the bank that is associated with this application is already pre-selected in the list.
My view:
#model MyProject.ViewModels.MyViewModel
My banks dropdown:
<td><b>Bank:</b></td>
<td>
#Html.DropDownListFor(
x => x.BankId,
new SelectList(Model.Banks, "Id", "Name", Model.BankId),
"-- Select --"
)
#Html.ValidationMessageFor(x => x.BankId)
</td>
My MyViewModel:
public class MyViewModel
{
// Partial class
public int BankId { get; set; }
public IEnumerable<Bank> Banks { get; set; }
}
My Edit action method:
public ActionResult Edit(int id)
{
// Get the required application
GrantApplication application = grantApplicationService.FindById(id);
// Mapping
MyViewModel viewModel = (MyViewModel)
grantApplicationMapper.Map(
application,
typeof(GrantApplication),
typeof(MyViewModel)
);
// BankId comes from my table. This is the unique identifier for the bank that was selected when the application was added
// Get all the banks
viewModel.Banks = bankService.FindAll().Where(x => x.IsActive);
return View(viewModel);
}
My bank class:
public class Bank
{
public int Id { get; set; }
public string Name { get; set; }
public bool IsActive { get; set; }
}
Doing it this way will have a selected value in your dropdown after the form has loaded.
I hope this helps :)
Related
The scenario is:
Data is stored in database in project and neighbourhood tables both.
Now, i want to populate dropdown with project id and project name and neighbourhoodId and neighbourhood name.
i am right now sending through viewBag like this:
ViewBag.NeighbourhoodId = new SelectList(allNeighbourhood(), "Id", "NeighbourhoodName");
on view page, getting dropdown populated like this:
#Html.DropDownList("Locations", ViewBag.NeighbourhoodId as SelectList, "Select a location")
Now,how to send another viewBag in this dropdownList.
Second ques, My dropdown is in partial view So, i am sending data to partial view like this:
#Html.Partial("_CommentBoxSection",new Neighbourhood())
how to send new Project()) along with neighbourhood. Is there any overload of partial where i can send both of them.
i have seen some posts relating to this title but they are something different
I have recently tried this:
public class ProjectAndNeighbourhoodListItemViewModel
{
public Project Project { get; set; }
public Neighbourhood Neighbourhood { get; set; }
public string ProjectName { get; set; }
public int Id { get; set; }
public bool IsSelected { get; set; }
// public IEnumerable<SelectListItem> ToSelectListItem { get; set; }
public SelectListItem ToSelectListItem()
{
return new SelectListItem
{
Text = Project.ProjectName,
Value = Neighbourhood.Id.ToString(),
Selected = IsSelected
};
}
}
and on view page directly,
#model #model IEnumerable<ProjectAndNeighbourhoodListItemViewModel>
#Html.DropDownList("Locations", Model.Select(m => m.ToSelectListItem()), "Select a location")
but getting System.ArgumentNullException value cannot be null i have no code in controller do i have to pass something in controller too
Do not use ViewBag to pass values to your view, use ViewModels instead, it is much cleaner. The ViewModel is also a good place to create your SelectListItems. Create or map the ViewModel in your controller.
// ViewModel for a single selectable entry
public class ProjectAndNeighbourhoodListItemViewModel {
public string ProjectName { get; set; }
public long NeighbourhoodId { get; set; }
public bool IsSelected { get; set; }
public SelectListItem ToSelectListItem() {
return new SelectListItem {
Text = ProjectName,
Value = NeighbourhoodId.ToString(),
Selected = IsSelected
}
}
}
In your Razor View:
#model IEnumerable<ProjectAndNeighbourhoodListItemViewModel>
#* Would be even better to use a wrapper model that contains the collection of list items as property! *#
#Html.DropDownList("Locations", Model.Select(m => m.ToSelectListItem()) , "Select a location")
I have two classes many-to-many the first is "Anuncios" and the second "SubCategorias"
public class Anuncios {
public int AnuncioId {get;set;}
public string Titulo {get;set;}
public ICollection<SubCategorias> SubCategorias {get;set;}
}
public class SubCategorias {
public int SubCategoriaId {get;set;}
public string Nome {get;set;}
public ICollection<Anuncios> Anuncios {get;set;}
}
In DAL layer I did method to save the "Anuncio" in DB.
public void Salvar(Anuncio entidade) {
entidade.SubCategorias = entidade.SubCategorias.Select(subcat => _contexto.SubCategorias.FirstOrDefault(x => x.SubCategoriaId == subcat.SubCategoriaId)).ToList();
_contexto.Anuncios.Add(entidade);
_contexto.SaveChanges();
}
I Create the Action "Create":
private readonly Context _ctx = new Context();
public ActionResult Create()
{
var model = new Anuncios {SubCategorias = _ctx.SubCategorias.ToList()};
return View(model);
}
In View I made DropDownList with "SubCategorias":
#Html.LabelFor(model => model.SubCategorias)
#Html.DropDownListFor(model => model.SubCategorias, new SelectList(Model.SubCategorias, "SubCategoriaId", "Nome"))
The DropDownListFor is populated with sucess..
Fine....
But when submit form the value selected in DropDownListFor not pass to method Create. The anuncio.SubCategorias is null!
private readonly AnunciosDal _anuncio = new AnunciosDal();
[HttpPost]
public ActionResult Create(Anuncio anuncio)
{
_anuncio.Salvar(anuncio);
return View(anuncio);
}
I have sought in various forums the solution, but could not find
Somebody help me?!
Sorry about my english rs...
Thank You!
Fabrício Oliveira
The first parameter of DropDownListFor needs to be the object holding the selected value, where the second parameter contains the list:
#Html.DropDownListFor(model => model.SOME_ID_FOR_SELECTED_VALUE,
new SelectList(Model.SubCategorias, "SubCategoriaId", "Nome"))
Currently the example you have also maps the same list as the first property. You should use an ID like #Maess suggested, and then bind it via:
#Html.DropDownListFor(model => model.SubCategoriaID, new SelectList(Model.SubCategorias, "SubCategoriaId", "Nome"))
Selecting a value will then post it back to the server to this SubCategoriaID field.
You need to have another property to store the selected value from the dropdown. It is best if you create a viewmodel with properties which are needed for your view.
public class CreateAnuncios
{
public string Title {set;get;}
public int SelectedSubCategoryId {set;get;}
public List<SelectListItem> SubCategories {set;get;}
public CreateAnuncios()
{
this.SubCategories = new List<SelectListItem>();
}
}
Now in your create action, create an object of this view model, Fill the SubCategories property and send to the view.
public ActionResult Create()
{
var vm=new CreateAnuncios();
vm.SubCategories = ctx.SubCategorias
.Select(s=> new SelectListItem
{ Value = s.SubCategoriaId .ToString(),
Text=s.Nome}).ToList();
return View(vm);
}
Your create view should be strongly typed to the CreateAnuncios class
#model YourNameSpaceHere.CreateAnuncios
#using(Html.Beginform())
{
#Html.TextBoxFor(s=>s.Title)
#Html.DropdownListFor(s=>s.SelectedSubCategoryId,Model.SubCategories,"Select")
<input type="submit" />
}
Now when user posts the form, Read the Properties of the posted model and use that to save to db.
[HttpPost]
public ActionResult Create(CreateAnuncios model)
{
//Check for model.Title and model.SelectedSubCategoryId and use it to save
// to do :Save and redirect
}
You need to provide a collection of SelectListItems that populate your DropDownList as well as a property to hold the currently selected SelectListItems' Id (which will be posted back to the server):
public class Anuncios {
public int AnuncioId {get;set;}
public string Titulo {get;set;}
public ICollection<SubCategorias> SubCategorias {get;set;}
public int SelectedSubCategoryId {get;set;}
public IEnumerable<SelectListItem> SubCategoryListItems {get;set;}
}
then, present them to the user via:
#html.DropDownListfor(x => x.SelectedSubCategoryId, Model.SubCategoryListItems)
The SubCategoryListItems will have to be populated from the server, typically something like this:
this.SubCategoryListItems = this.SubCategorias.Select(x => new SelectListItem { Text = x.Name, Value = x.Id });
You need an id property for the SubCategoria you have it in your binding, but not in the model
public class Anuncios {
public int AnuncioId {get;set;}
public string Titulo {get;set;}
public ICollection<SubCategorias> SubCategorias {get;set;}
public int SubCategoriaId{get;set;}
}
I'm really stumped right now. I've been stuck with this problem for a number of days now and frankly, I'm getting sick and tired of it.
I have this database table: https://gyazo.com/9d1b014ecdba1e244c2f6957b6d9397c
(notice FlightsTable)
My goal is to populate a dropdown menu based on the values from the "Departure" section.
I've tried lots of things and yet I still cannot get to grips with it.
Here's my model:
public class FlightModel
{
public int FlightID { set; get; }
public string Departure { set; get; }
public string Arrival { set; get; }
public int NumberOfSeats { set; get; }
public int NumberOfFlights { set; get; }
}
Controller:
public ActionResult BookFlight()
{
return View();
}
FlightDBEntities (from the FlightsDBModel)
namespace Project_v3.Models
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class FlightsDBEntities : DbContext
{
public FlightsDBEntities()
: base("name=FlightsDBEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public DbSet<FlightsTable> FlightsTables { get; set; }
}
}
Screenshot of the files: http://gyazo.com/31b447387f349fbbe541f44a358c3096
How do I make the dropdown work in my view for BookFlight? I'm really struggling with this so step-by-step solutions so I can understand every step would be greatly appreciated. Please and thank you.
There are a few ways to do this, this is an example:
You'll need something that actually creates your selectlist:
public SelectList GetAsSelectList()
{
var depts = from f in db.FlightsTables
select new SelectListItem
{
Value = f.Departure,
Text = f.Departure
};
return new SelectList(depts, "Value", "Text");
}
If departures are held in their own table, then it would be better to select them from there, using the Id primary key field as the selectlist's value field
I've assumed that the selectlist will be shown on the same page as FlightModel. If this is the case, then your model needs a property for the selectlist:
public SelectList DepartureList { get; set; }
Your controller method needs to create a FlightModel instance, populate it with whatever you want to show (including the selectlist) and pass it to the View:
public ActionResult BookFlight()
{
var model = new FlightModel
{
DepartureList = GetAsSelectList()
};
return View(model);
}
Depending on what you want the user to do with the selectlist, you display it in the view like this:
#Html.DropDownList("Departure", Model.DepartureList)
In your controller, select the distinct departures
IEnumerable<string> departures = db.FlightsTables.Select(f => f.Departure).Distinct();
and assign to to a ViewBag property (or better, use a view model with a property for the SelectList)
ViewBag.DepartureList = new SelectList(departures);
and in the view (unsure what the property you want to bind to - you have not shown your model for the Booking)
#Html.DropDownListFor(m => m.YourProperty, (SelectList)ViewBag.DepartureList, "-Please select-")
I suspect you may need to modify your flight table. You have a ID column but the have a column for number of flights. Surely you would need information about departure and arrival times for each flight?
Edit
Further to comments, your booking model may look something like.
public class BookingVM
{
public List<FlightModel> FlightList { get; set; } // to display available flights
public string Departure { get; set; } // bind to DepartureList
public int FlightID { get; set; } // bind to FlightID in a dropdown that displays the arrival locations
public int Seats { get; set; } // number of seats booked
public SelectList DepartureList { get; set; } // unique departures
}
You would need to handle the .change() event of the Departure dropdownlist, use ajax to pass the selected departure to a controller method that returns the flightID and arrival locations (and probably the number of available seats for each flight) and use that to populate the second dropdownlist (bound to FlightID and displaying the arrival locations).
Trying to unpack some inherited code and I am new to ASP.NET. My question:
What is available in the controller from a post action in a dropdownlist in C# (ASP.NET MVC5)?
Here is what I have in the view:
#using (Html.BeginForm("SignUp", "Location", FormMethod.Post))
....
#Html.DropDownListFor(
model => model.Member.PillarId, new SelectList (Model.Pillars, "Id", "Title"))
Here is the MemberViewModel:
public class MemberViewModel : IValidatableObject{
public int? LocationId { get; set; }
public int? PillarId { get; set; }
}
Here is the Member model:
public class Member
{
public int Id { get; set; }
public string Name { get; set; }
public int? LocationId { get; set; }
public int? PillarId { get; set; }
public String PillarTitle { get; set; }
Here is the Member model constructor(s):
public Member() { }
public Member(MemberViewModel member)
{
PillarId = member.PillarId;
///
}
Here is the Controller
public ActionResult SignUp(MemberViewModel member){///}
My form is correctly pulling the information from the DB to display, as well as posting correctly to the DB via the Controller. I do not want to change the visual options for the user to choose from (i.e. I think ListBox is out?).
Rather, I want to assign both Member.PillarId as well as the Member.Title based on their choice and have it available in the Controller for non-DB operations.
What is currently available in the SignUp method in the Controller? Can I call Model.Pillars.Title? Is it member.PillarId.Pillars.Id? If not, how can I assign it dynamically based on the user choice?
There are views and modelviews flying around in this code, and I am not sure what is available...
SO has a bunch of answers on the DropDownList, so here's a sampling of articles that are somewhat related to what I am getting at...
* This answer
* ListBox
* ListBoxFor: not MVC dynamic
* SelectList Constructor: Not MVC
With a dropdownlist the only value that will come back is the value of the selected item when posting back.
If you want something else to come back you would need a hidden field on the page and bind a change event listener to the dropdown to set the title in the hidden field
public class MemberViewModel : IValidatableObject{
public int? LocationId { get; set; }
public int? PillarId { get; set; }
public string Title { get; set;}
}
#using (Html.BeginForm("SignUp", "Location", FormMethod.Post))
....
#Html.DropDownListFor(
model => model.Member.PillarId, new SelectList (Model.Pillars, "Id", "Title"))
#Html.HiddenFor(model => model.Title);
javascript
$('#idofdropdown').on('change', function()
{
var selectedTitle = $(this).find(":selected").text();
$('#Title').val(selectedTitle);
});
How to get selected title from a drop down list: Get selected text from a drop-down list (select box) using jQuery
Then in your controller your viewmodel will have the title text inside the Title string :)
I have two models and I want to insert a row in the database with a foreign key relationship populated in the DropDownList. The Item model's data insert without problems but ManufacturerID does not get inserted (it inserts null). I could not find why.
Update: Uploaded the project to: http://mvcapplication2.codeplex.com/
<div class="editor-label">
#Html.LabelFor(model => model.ManufacturerID,"Manufacturer")
</div>
<div class="editor-field">
#Html.DropDownList("ManufacturerID",string.Empty)
#Html.ValidationMessageFor(model => model.ManufacturerID)
</div>
public class Item
{
public int ItemID { get; set; }
public string Serial { get; set; }
public string ItemName { get; set; }
public int? ManufacturerID { get; set; }
public Manufacturer Manufacturer { get; set; }
}
public class Manufacturer
{
public int ManufacturerID { get; set; }
public string ManufacturerName { get; set; }
public List<Item> Items { get; set; }
}
public ActionResult Create()
{
ViewBag.ManufacturerID = new SelectList(db.Manufacturers, "ManufacturerID", "ManufacturerName");
return View();
}
[HttpPost]
public ActionResult Create(Item ıtem)
{
if (ModelState.IsValid)
{
db.Items.Add(ıtem);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(ıtem);
}
I would prefer to NOT use the domain model in the view. I would create some view models specific to the view. Also, to transfer data from action method (ex : dropdown list), i would use a strongly typed approach, instead of the dynamic viewbag/ viewdata approach.
Create a view model class
public class CreateItemVM
{
public string SerialNumber { set;get;}
public int SelectedManufactureID { set;get;}
public List<SelectListItem> Manufacturers { set;get;}
public CreateItemVM()
{
Manufacturers =new List<SelectListItem>();
}
}
Now in your GET action method, create an object of our viewmodel, initialize the relevant values and send to the view.
public ActionResult Create()
{
var vm=new CreateItemVM();
vm.Manufacturers=GetManufacturerList();
return View(vm);
}
private List<SelectListItem> GetManufacturerList()
{
List<SelectListItem> manuList=new List<SelectListItem>();
manuList=(from p in db.Manufacturers
select new SelectListItem {
Value=p.ID.ToString(),
Text=p.Name}
).ToList();
return manuList;
}
Now in our view, which is strongly typed to our Viewmodel,
#model CreateItemVM
#using(Html.Beginform())
{
#Html.DropDownListfor(x=>x.SelectedManufactureID ,
Model.Manufacturers,"select")
<input type="submit" />
}
And finally in our POST action method, we will read values from our posted viewmodel and assign it as the property values of our domain object and save it. the selected manufacturers ID value will be in the SelectedManufactureID property of our viewmodel.
[HttpPost]
public ActionResult Create(CreateItemVM model)
{
if(ModelState.IsValid)
{
Item domainObject=new Item();
domainObject.ManufacturerID =model.SelectedManufactureID ;
//set other relevant properties also
db.Items.Add(ıtem);
db.SaveChanges();
return RedirectToAction("Index");
}
// reload the dropdown before returning to the view
model.Manufacturers=GetManufacturerList();
return View(model);
}
Try to make the relationship more explicit, making properties virtual and adding an attribute:
public class Item
{
...
[ForeignKey("Manufacturer")]
public int? ManufacturerID { get; set; }
public virtual Manufacturer Manufacturer { get; set; }
}
public class Manufacturer
{
...
public virtual List<Item> Items { get; set; }
}
Edit:
And you can use a more tied way of building the drop down:
#Html.DropDownListfor(x=>x.SelectedManufactureID ,
ViewBag.ManufacturerID as SelectList,"Choose one")
Edit 2:
A better approach is to make a specific model for the view (called ViewModel) to represent data and build the view like #Shyju said.
Found the problem. The Viewbag I was sending to the view should be named as ManufacturerID, I was sending Manufacturers and somehow it was not matching although it populated the dropdown.