I can't get the selected value to work with HTML.dropwdownlistfor
Here is what I have trying to get to work, ALL DATA IS THERE, the select statement finds the selected item, the ienumerable of SelectListItems has an item that has the "select = true" I'm not sure where I'm going wrong.
MODEL:
[SitecoreIgnore]
public virtual IEnumerable<Sitecore.Data.Items.Item> List_Location { get; set; }
public virtual Sitecore.Data.Items.Item Location { get; set; }
[SitecoreIgnore]
public virtual string Location_Model { get; set; }
HELPER METHOD:
public static IEnumerable<SelectListItem> SelectListConstructor(Item selectedItem, IEnumerable<Item> options)
{
IEnumerable<SelectListItem> listings = from o in options
select new SelectListItem
{
Selected = (selectedItem.ID == o.ID),
Text = o.DisplayName,
Value = o.ID.ToString()
};
return listings;
}
Controller: (The casting works fine, data is there)
[HttpPost]
public ActionResult CreateAdStep(Classified model)
{
if(ModelState.IsValid)
{
return RedirectToAction("PreviewAd", model);
}
var allerrrors = ModelState.Values.SelectMany(v => v.Errors);
return View(Sitecore.Context.Database.GetItem("{69040A7B-5444-4ECF-A081-C4A3B26876B5}").GlassCast<Classified>());
}
[HttpGet]
public ActionResult CreateAdStep()
{
var trial = Sitecore.Context.Database.GetItem("{69040A7B-5444-4ECF-A081-C4A3B26876B5}").GlassCast<Classified>();
return View(trial);
}
CSHTML LINE ATTEMPTS:
1)
#{ var emo = CalCPA.Source.Models.Utility.Utility.SelectListConstructor(Model.Location, Model.List_Location);
var emo2 = emo.Where(i=> i.Selected == true).FirstOrDefault();
}
#Html.DropDownListFor(m => m.Location_Model, new SelectList(emo, "Value", "Text", emo2.Value))
2)
#{ var emo = CalCPA.Source.Models.Utility.Utility.SelectListConstructor(Model.Location, Model.List_Location);
var emo2 = emo.Where(i=> i.Selected == true).FirstOrDefault();
}
#Html.DropDownListFor(m => m.Location_Model, new SelectList(emo, "Value", "Text", emo2))
3)
#{ var emo = CalCPA.Source.Models.Utility.Utility.SelectListConstructor(Model.Location, Model.List_Location);
var emo2 = emo.Where(i=> i.Selected == true).FirstOrDefault();
}
#Html.DropDownListFor(m => m.Location_Model, emo)
Thanks for any insight/help!!!
If your going to use DropDownListFor you need to set the selected value in the model first.
In your action (or model builder):
model.Location_Model = "my selected value";
Then your view:
#Html.DropDownListFor(m => m.Location_Model, new SelectList(emo, "Value", "Text"))
Related
I know that there are another similar questions, but i can't find working solution anywhere.
The point is that i want from user to select date in dropDownList, get that date as an argument for action method and depending on selected date show results from database. But all the time, after choosing any item in dropDownList it returns null to controller.
Here is my controller's methods:
public ActionResult Index(DateViewModel dateViewModel)
{
dateViewModel.Dates = GetDates();
return View(dateViewModel);
}
private IEnumerable<SelectListItem> GetDates()
{
var dbContext = new DbContext();
var dates = dbContext .TestResults
.Where(result => result.CompletedOn != null)
.OrderBy(result => result.CompletedOn)
.Select(result => result.CompletedOn).ToList();
var sortedDates = dates
.GroupBy(date => date.Month)
.Select(date => date.First())
.Select(date => new SelectListItem { Text = date.ToString("MMMM yy"), Value = date.Month.ToString() + " " + date.Year.ToString()})
.ToList();
return new SelectList(sortedDates, "Value", "Text");
}
[HttpPost]
public ActionResult ShowDepartmentArchive(string date)
{
//some logic with date here
return PartialView(depResults);
}
I have a ViewModel for dropDownList:
public class DateViewModel
{
[Display(Name = "Выбранная дата")]
public string SelectedDate { get; set; }
[Display(Name = "Выберите дату: ")]
public IEnumerable<SelectListItem> Dates { get; set; }
}
And, finally in my view:
#model QA.Web.App.Models.DateViewModel
#using (Html.BeginForm("ShowDepartmentArchive", "Archive"))
{
#Html.Hidden("SelectedDate", Model.SelectedDate)
#Html.DropDownListFor(m => m.SelectedDate, Model.Dates, "Выберите
дату", new {onchange = "this.form.submit();"})}
I have a simple select with an option selected from the model that is loaded.
To start here is my simple model
public class invoice
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public invoice_state invoice_state { get; set; }
}
public class invoice_state
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public string alias { get; set; }
public List<invoice> invoices { get; set; }
[Display(Name = "title")]
public string title { get; set; }
}
Here is what I have that works in one view.
in controller:
public IActionResult Create()
{
string state = "start_finish";
ViewBag.State = state;
var states = _context.invoice_state.Select(c => new {
id = c.ID,
title = c.title
}).ToList();
ViewBag.States = new SelectList(states, "id", "title", _context.invoice_state.Where(e => e.alias == state).FirstOrDefault().ID);
return View();
}
in the view
#Html.DropDownList("invoice_state", (SelectList)ViewBag.States, "--Select One--")
That works fine, the option is selected... but on my edit view which is set up mostly the same is not working.
in controller:
public async Task<IActionResult> Edit(int? id)
{
var invoice = await _context.invoice
.Include(_item => _item.invoice_state).SingleOrDefaultAsync(m => m.ID == id);
if (invoice == null)
{
return NotFound();
}
string state = "start_finish"; // as a default
var states = _context.invoice_state.Select(c => new { id = c.ID, title = c.title }).ToList();
if (null != invoice.invoice_state)
{
ViewBag.State = invoice.invoice_state.alias;
}
else
{
ViewBag.State = state;
}
ViewBag.States = new SelectList(states, "id", "title", _context.invoice_state.Where(e => e.alias == state).FirstOrDefault());
return View(invoice);
}
and in the edit view
#Html.DropDownList("invoice_state", (SelectList)ViewBag.States, "--Select One--")
I have read all over the place and can't find a simple answer that isn't wire up more files, and even those haven't helped get me to the need. I have tried to force it too and it is not working, but figured it was worth placing here too.
ViewBag.States = _context
.invoice_state
.Select(c => new SelectListItem {
Value = c.ID.ToString(),
Text = c.title
})
.Select(l => new SelectListItem {
Selected = (l.Value == invoice.invoice_state.ID.ToString()),
Text = l.Text,
Value = l.Value
});
but only get 'Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable<Microsoft.AspNetCore.Mvc.Rendering.SelectListItem>' to 'Microsoft.AspNetCore.Mvc.Rendering.SelectList' or the list version of the error if i add .ToList() on the select like before.
Some people have suggested to set the selected value, and as i read it it would be like,
if (null != invoice.invoice_state)
{
ViewBag.invoice_stateID = invoice.invoice_state.ID;
}
else
{
ViewBag.invoice_stateID = _context.invoice_state.Where(e => e.alias == "start_finish").FirstOrDefault().ID;
}
if i use
<select asp-for="invoice_state" asp-items="#ViewBag.States" >
<option>Please select one</option>
</select>
It doesn't work either, see the list but nothing selected. Last note, if I select it and submit it, it does set the value in the database, just when I get back to the edit it again fails to again select anything.
Also to be clear there is the data
which came from
<dt>
#Html.DisplayNameFor(model => model.invoice_state)
</dt>
<dd>
#Html.DisplayFor(model => model.invoice_state)
</dd>
#Stephen Muecke is right, the ticket is the ViewModel. Not a fan fully here but I'll simmer. The solution is not just getting it to show, you need to save is too. Here is the whole of it.
ViewModel
namespace project_name.Models.InvoiceViewModel
{
public class EditInvoiceViewModel
{
public int invoice_stateID { get; set; }
public invoice invoice { get; set; }
public List<SelectListItem> States { set; get; }
}
}
edit in action on controller
public async Task<IActionResult> Edit(int? id)
{
var invoice = await _context.invoice
.Include(_item => _item.invoice_state).SingleOrDefaultAsync(m => m.ID == id);
string state = "start_finish"; // as a default
var states = _context.invoice_state.Select(c => new { id = c.ID, title = c.title }).ToList();
if (null != invoice.invoice_state)
{
ViewBag.State = invoice.invoice_state.alias;
}
else
{
ViewBag.State = state;
}
var vm = new EditInvoiceViewModel();
vm.invoice = invoice;
vm.States = _context
.invoice_state
.Select(c => new SelectListItem
{
Value = c.ID.ToString(),
Text = c.title
})
.ToList();
if (null != invoice.invoice_state)
{
vm.invoice_stateID = invoice.invoice_state.ID;
} else {
vm.invoice_stateID = _context.invoice_state.Where(e => e.alias == "start_finish").FirstOrDefault().ID;
}
return View(vm);
}
to save in action on controller
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(EditInvoiceViewModel model)
{
if (ModelState.IsValid)
{
try
{
model.invoice.creator = await GetCurrentUserAsync();
model.invoice.invoice_state = await _context.invoice_state.SingleOrDefaultAsync(m => m.ID == model.invoice_stateID);
_context.Update(model.invoice);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!invoiceExists(model.invoice.ID))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction("Index");
}
return View(model);
}
And in the view
<div class="form-group">
<label asp-for="#Model.invoice_stateID" class="col-md-2 control-label"></label>
<select asp-for="#Model.invoice_stateID" asp-items="#Model.States" >
<option>Please select one</option>
</select>
</div>
The thing I guess I was having a hard time with is all supporting questions that are like this, and all the blogs focus on the display, but i still need to save it, and that was not clear. I had to skip the [bind()] but I'll get back to that.
I have a View Model that looks like this:
public class SomeViewModel
{
public SomeViewModel(IEnumerable<SelectListItem> orderTemplatesListItems)
{
OrderTemplateListItems = orderTemplatesListItems;
}
public IEnumerable<SelectListItem> OrderTemplateListItems { get; set; }
}
I then have an Action in my Controller that does this:
public ActionResult Index()
{
var items = _repository.GetTemplates();
var selectList = items.Select(i => new SelectListItem { Text = i.Name, Value = i.Id.ToString() }).ToList();
var viewModel = new SomeViewModel
{
OrderTemplateListItems = selectList
};
return View(viewModel);
}
Lastly my view:
#Html.DropDownListFor(n => n.OrderTemplateListItems, new SelectList(Model.OrderTemplateListItems, "value", "text"), "Please select an order template")
The code works fine and my select list populates wonderfully. Next thing I need to do is set the selected value that will come from a Session["orderTemplateId"] which is set when the user selects a particular option from the list.
Now after looking online the fourth parameter should allow me to set a selected value, so if I do this:
#Html.DropDownListFor(n => n.OrderTemplateListItems, new SelectList(Model.OrderTemplateListItems, "value", "text", 56), "Please select an order template")
56 is the Id of the item that I want selected, but to no avail. I then thought why not do it in the Controller?
As a final attempt I tried building up my select list items in my Controller and then passing the items into the View:
public ActionResult Index()
{
var items = _repository.GetTemplates();
var orderTemplatesList = new List<SelectListItem>();
foreach (var item in items)
{
if (Session["orderTemplateId"] != null)
{
if (item.Id.ToString() == Session["orderTemplateId"].ToString())
{
orderTemplatesList.Add(new SelectListItem { Text = item.Name, Value = item.Id.ToString(), Selected = true });
}
else
{
orderTemplatesList.Add(new SelectListItem { Text = item.Name, Value = item.Id.ToString() });
}
}
else
{
orderTemplatesList.Add(new SelectListItem { Text = item.Name, Value = item.Id.ToString() });
}
}
var viewModel = new SomeViewModel
{
OrderTemplateListItems = orderTemplatesList
};
return View(viewModel);
}
Leaving my View like so:
#Html.DropDownListFor(n => n.OrderTemplateListItems, new SelectList(Model.OrderTemplateListItems, "value", "text"), "Please select an order template")
Nothing!
Why isn't this working for me?
You say "56 is the Id of the item that I want selected, but to no avail"
Should the fourth parameter you refer to be a string, not an integer, like so:
#Html.DropDownListFor(n => n.OrderTemplateListItems, new SelectList(Model.OrderTemplateListItems, "value", "text", "56"), "Please select an order template")
I have a page that has two drop down lists and based upon the selection of these two lists I would like to populate a textarea with some data on submit button press.
The behavior that I am seeing while debugging is that the page is rendered, I make my selections and press submit. The DataAccess returns the correct results and the View returns, but with an exception "There is no ViewData item of type 'IEnumerable' that has the key 'People'.
I can see that I could re-setup the drop down lists, but it feels like I'm approaching this incorrectly. Is there another approach for doing this sort of action in MVC 3?
public ActionResult Test()
{
//People for dropdownlist 1
var db = peopleRepository.People;
var query = db.Select(c => new {c.Id, c.Name});
ViewBag.People = new SelectList(query.AsEnumerable(), "Id", "Name");
//Elements for dropdownlist 2
var list = new Dictionary<string, string> {{"1", "Name"}, {"2", "Address"}, {"3", "Zip"}};
ViewBag.Elements = new SelectList(list, "Key", "Value");
return View();
}
// This part is what I'm confused about.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Test(string people, string elements)
{
if (ModelState.IsValid)
{
// Output from persistent storage query
var da = new DatabaseAccess(people, elements);
ViewBag.Results = da.Execute();
}
return View();
}
View:
#using (Html.BeginForm("Test", "Home", FormMethod.Post))
{
#Html.DropDownList("People", (SelectList)ViewBag.People, "--Select One--")
#Html.DropDownList("Elements", (SelectList)ViewBag.Elements, "--Select One--")
#Html.TextArea("Results", (string)ViewBag.Results, 10, 120, "")
}
Here is how I would quickly construct it :
Model :
public class People
{
public int Id { get; set; }
public string Name { get; set; }
}
ViewModel (everything needed by the view):
public class TestViewModel
{
public int SelectedPeopleId { get; set; }
public string SelectedElementId { get; set; }
public SelectList People { get; set; }
public SelectList Elements { get; set; }
public String Results { get; set; }
}
Controller (used Index as the default Action, create an init function for the view model that can be adapted)to anything more appropriate :
public class HomeController : Controller
{
private static TestViewModel InitTestVM()
{
//People for dropdownlist 1
var db = new List<People>();//peopleRepository.People;
db.Add(new People { Id = 1, Name = "Name 1" });
db.Add(new People { Id = 2, Name = "Name 2" });
var query = db.Select(c => new { c.Id, c.Name });
//Elements for dropdownlist 2
var list = new Dictionary<string, string> { { "1", "Name" }, { "2", "Address" }, { "3", "Zip" } };
TestViewModel testVM = new TestViewModel
{
People = new SelectList(query.AsEnumerable(), "Id", "Name"),
Elements = new SelectList(list, "Key", "Value")
};
return testVM;
}
public ActionResult Index()
{
return View(InitTestVM());
}
// This part is what I'm confused about.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(TestViewModel testVM)
{
var vm = InitTestVM();
if (ModelState.IsValid && testVM != null)
{
ModelState.Clear();
// Output from persistent storage query
//var da = new DatabaseAccess(people, elements);
vm.Results = "sfdfsdfsdfsdfsdfsdfsdfsdf";//da.Execute();
vm.SelectedElementId = testVM.SelectedElementId;
vm.SelectedPeopleId = testVM.SelectedPeopleId;
return View(vm);
}
return View(vm);
}
}
And finally the View :
#model ViewModels.TestViewModel
#using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
#Html.DropDownListFor(m => m.SelectedPeopleId, Model.People, "--Select One--")
#Html.DropDownListFor(m => m.SelectedElementId, Model.Elements, "--Select One--")
#Html.TextAreaFor(m => m.Results, 10, 120, "")
<input type="submit" value="Test" />
}
I'd like to edit an object like the one below. I'd like the UsersSelectedList populated with one or more Users from the UsersGrossList.
Using the standard edit-views in mvc, I get only strings and booleans (not shown below) mapped.
Many of the examples I find on google utilizes early releases of the mvc framework whereas I use the official 1.0 release.
Any examples of the view is appreciated.
public class NewResultsState
{
public IList<User> UsersGrossList { get; set; }
public IList<User> UsersSelectedList { get; set; }
}
Assuming that User model has Id and Name properties:
<%= Html.ListBox("users", Model.UsersGrossList.Select(
x => new SelectListItem {
Text = x.Name,
Value = x.Id,
Selected = Model.UsersSelectedList.Any(y => y.Id == x.Id)
}
) %>
Or with View Model
public class ViewModel {
public Model YourModel;
public IEnumerable<SelectListItem> Users;
}
Controller:
var usersGrossList = ...
var model = ...
var viewModel = new ViewModel {
YourModel = model;
Users = usersGrossList.Select(
x => new SelectListItem {
Text = x.Name,
Value = x.Id,
Selected = model.UsersSelectedList.Any(y => y.Id == x.Id)
}
}
View:
<%= Html.ListBox("users", Model.Users ) %>
Use Html.ListBox in combination with IEnumerable SelectListItem
View
<% using (Html.BeginForm("Category", "Home",
null,
FormMethod.Post))
{ %>
<%= Html.ListBox("CategoriesSelected",Model.CategoryList )%>
<input type="submit" value="submit" name="subform" />
<% }%>
Controller/Model:
public List<CategoryInfo> GetCategoryList()
{
List<CategoryInfo> categories = new List<CategoryInfo>();
categories.Add( new CategoryInfo{ Name="Beverages", Key="Beverages"});
categories.Add( new CategoryInfo{ Name="Food", Key="Food"});
categories.Add(new CategoryInfo { Name = "Food1", Key = "Food1" });
categories.Add(new CategoryInfo { Name = "Food2", Key = "Food2" });
return categories;
}
public class ProductViewModel
{
public IEnumerable<SelectListItem> CategoryList { get; set; }
public IEnumerable<string> CategoriesSelected { get; set; }
}
public ActionResult Category(ProductViewModel model )
{
IEnumerable<SelectListItem> categoryList =
from category in GetCategoryList()
select new SelectListItem
{
Text = category.Name,
Value = category.Key,
Selected = (category.Key.StartsWith("Food"))
};
model.CategoryList = categoryList;
return View(model);
}
# eu-ge-ne < thankyou so much for your answer - was having real trouble finding a way to multiselect a list of values from and to model.
Using your code I used the ListBoxFor Html control in my Edit/Update page and passed the whole model back to my controller (including the mulisple selected values) on Save.
<%= Html.ListBoxFor(model => model, Model.UsersGrossList.Select(
x => new SelectListItem {
Text = x.Name,
Value = x.Id,
Selected = Model.UsersSelectedList.Any(y => y.Id == x.Id)
}
) %>