My project is MVC.Net Core project with Razor pages.
My Dto class:
public class TicketDto
{
public Guid Id { get; set; }
public IList<KeyValuePair<int, string>> Areas { get; set; }
}
In view i create select list using #Html.ListBoxFor
#Html.ListBoxFor(model => model.Areas, (MultiSelectList)ViewBag.AreaId, new { #class="custom-select", #id="inputGroupSelect01", size = 5 })
View also has ViewData/ViewBag:
ViewData["AreaId"] = new MultiSelectList(areaService.GetAreas().Select( a => new { a.Id, a.Name }), "Id", "Name");
Razor render next:
<select class="custom-select" id="inputGroupSelect01" multiple="multiple" name="Areas" size="5"><option value="1">A</option>
<option value="2">P</option>
<option value="3">S</option>
<option value="10">AB</option>
<option value="11">AB</option>
</select>
image of select list
Controler takes TicketDto:
public IActionResult Create(TicketDto ticketDto)
When i select multiple items and POST form to controller the ticketDto.Areas count = 0
How shoud i post model class with List and #Html.ListBoxFor choice to my controller?
Multiselectlist will post through an array of the selected values by default. If you want to get all the selected items it could be done like this:
public class MyData
{
public string Id { get; set; }
public string Value { get; set; }
}
public class MyViewModel
{
public int[] SelectedIds { get; set; }
public IEnumerable<SelectListItem> Items { get; set; }
}
public IActionResult Index()
{
var data = new List<MyData>
{
new MyData() {Id = "2", Value = "P"}, new MyData() {Id = "3", Value = "S"},
new MyData() {Id = "10", Value = "AB"}
};
var model = new MyViewModel
{
Items = data.Select(x => new SelectListItem
{
Value = x.Id,
Text = x.Value
})
};
return View(model);
}
public IActionResult Create(MyViewModel model)
#using (Html.BeginForm("Create", "Home", FormMethod.Post))
{
#Html.ListBoxFor(x => x.SelectedIds, Model.Items)
<p><input type="submit" value="Submit" /></p>
}
Thanks
Related
I have the following view model code:
public class TestCheckboxlistParentModel
{
public TestCheckboxlistParentModel()
{
CBL = new TestCheckboxlistModel();
}
public TestCheckboxlistModel CBL { get; set; }
}
public class TestCheckboxlistModel
{
public string TextField { get; set; }
public IList<string> SelectedFruits { get; set; }
public IList<SelectListItem> AvailableFruits { get; set; }
public TestCheckboxlistModel()
{
SelectedFruits = new List<string>();
AvailableFruits = new List<SelectListItem>();
}
}
controller:
public ActionResult TestCheckboxlist()
{
var model = new TestCheckboxlistParentModel
{
CBL = new TestCheckboxlistModel()
{
AvailableFruits = GetFruits()
}
};
return View(model);
}
[HttpPost]
public ActionResult TestCheckboxlist(TestCheckboxlistParentModel model)
{
if (ModelState.IsValid)
{
// Save data to database, and redirect to Success page.
return RedirectToAction("Success");
}
//model.AvailableFruits = GetFruits();
return View(model);
}
public ActionResult Success()
{
return View();
}
private IList<SelectListItem> GetFruits()
{
return new List<SelectListItem>
{
new SelectListItem {Text = "Apple", Value = "1"},
new SelectListItem {Text = "Pear", Value = "2"},
new SelectListItem {Text = "Banana", Value = "3"},
new SelectListItem {Text = "Orange", Value = "4"},
};
}
partial view:
#model Web.ViewModels.TestCheckboxlistModel
<div class="form-group">
#Html.LabelFor(model => model.TextField)
<div class="col-md-10">
#Html.EditorFor(model => model.TextField)
</div>
</div>
#foreach (var item in Model.AvailableFruits)
{
<div class="checkbox">
<label>
<input type="checkbox"
name="#Html.IdFor(p=>p.SelectedFruits)"
value="#item.Value" /> #item.Text
</label>
</div>
}
view:
#model Web.ViewModels.TestCheckboxlistParentModel
#{
ViewBag.Title = "TestCheckboxlist";
Layout = "~/Views/Shared/_LayoutApplicationDriver.cshtml";
}
#using (Html.BeginForm())
{
#Html.Partial("TestPartialCheckboxlist", Model.CBL, new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "CBL" } })
<div class="form-group text-center">
<input type="submit" class="btn btn-primary" value="Submit" />
</div>
}
Problem is SelectedFruits always does not have any elements in post method. The same code work correctly, if I don't use nested Partial view. Property TextField works fine with Partial
PS. It's not a dublicate of How to make Check Box List in ASP.Net MVC question. That question is a base of my answer. In my case, I need to have checkboxlist in partial view, where it does not work!
You use of name="#Html.IdFor(p => p.SelectedFruits)" generates name="CBL_SelectedFruits", but in order to bind to your model, you would need name="CBL.SelectedFruits" (note the . dot, not _ underscore) which you could generate using
name="#Html.NameFor(p => p.SelectedFruits)"
However there are other issues with your code. Your not strongly binding to your model, you get no validation, your generating a IList<SelectListItem> for property AvailableFruits when you don't need it (it could be just IList<string> AvailableFruits, and most importantly, if you return the view, all the checkboxes the user checked are lost (all checkboxes will be unchecked).
Change your view models so that you can strongly bind to your properties
public class FruitVM
{
public string Name { get; set; }
public bool IsSelected { get; set; }
}
public class ParentVM
{
public string TextField { get; set; }
public List<FruitVM> Fruits { get; set; }
}
and in the GET method
ParentVM model = new ParentVM
{
Fruits = new List<FruitVM>{
new FruitVM{ Name = "Apple" },
new FruitVM{ Name = "Pear" },
....
}
};
return View(model);
and create an EditorTemplate for FruitVM - in /Views/Shared/EditorTemplates/FruitVM.cshtml
#model FruitVM
#Html.CheckBoxFor(m => m.IsSelected)
#Html.LabelFor(m => m.IsSelected, Model.Name)
and in the view
#Html.ParentVM
....
#using (Html.BeginForm())
{
#Html.LabelFor(m => m.TextField)
#Html.EditorFor(m => m.TextField)
#Html.EditorFor(m => m.Fruits)
<input type="Submit" value="Save" />
}
The EditorFor() method will generate the correct html for each item in your collection.
Then in the POST method, you can get the selected items with
[HttpPost]
public ActionResult TestCheckboxlist(ParentVM model)
{
....
List<string> selectedFruits = model.Fruits.Where(x => x.IsSelected);
Let's say i want to show multiple DropDownList. Values are same but in view they need to be shown as name of Each value and count of all values in dropdown. Please check out the below data and sample of requirement.
ID 1,2,3,4,5
Name A,B,C,D,E
view now should create 5 dropdownlist as [A] ==== [1,2,3,4,5], [B] ==== [1,2,3,4,5] and so on. What is the easiest way to do .Please suggest
What I would do in this situation is take #Matteo1010's suggestion and create a view model. I had to do this recently and so I have a solution readily available.
You'll first want to create a model containing the values you need for the dropdown list; generally these would be something like
public class DropDownA
{
public int id {get;set;}
public string value {get;set;}
public bool IsSelected{get;set;}
}
Now you want a ViewModel with a list of DropDownA
public class MyViewModel
{
List<DropDownA> dropDownA {get;set;}
public IEnumerable<SelectListItem> ddaSLI { get { return new SelectList(dropDownA, "id", "value"); } }
}
Of course, you're going to have to initialize the list
for(int i = 0; i < YourItems.Count; i++)
{
dropDownA.Add(new DropDownA { id = i, value = "something", IsSelected = false});
}
And in the View it's easy to render and there will be model binding
#Html.DropDownListFor(model => model.id, Model.ddaSLI)
Just repeat for any other dropdowns you want and everything should be just fine. :)
The view model
public class CustomViewModel
{
public string A { get; set;}
public string B { get; set;}
public string C { get; set;}
public string D { get; set;}
public string E { get; set;}
}
the controller
public ActionResult Test()
{
List<SelectListItem> lista = new List<SelectListItem>();
lista.Add(new SelectListItem()
{
Text = "1",
Value = "1"
});
lista.Add(new SelectListItem()
{
Text = "2",
Value = "2"
});
lista.Add(new SelectListItem()
{
Text = "3",
Value = "3"
});
lista.Add(new SelectListItem()
{
Text = "4",
Value = "4"
});
lista.Add(new SelectListItem()
{
Text = "5",
Value = "5"
});
ViewBag.list = lista;
return View(new CustomViewModel());
}
[HttpPost]
public ActionResult Test(CustomViewModel customViewModel)
{
//your code
//if return the same view create again the List<SelectListItem>
return View(customViewModel);
}
The view
#model test.Models.CustomViewModel
#{
ViewBag.Title = "Test";
List<SelectListItem> list = ViewBag.list as List<SelectListItem>;
}
<h2>Test</h2>
#using (Html.BeginForm())
{
<div>
#Html.DropDownListFor(model => model.A, new SelectList(list))
</div>
<div>
#Html.DropDownListFor(model => model.B, new SelectList(list))
</div>
<div>
#Html.DropDownListFor(model => model.C, new SelectList(list))
</div>
<div>
#Html.DropDownListFor(model => model.D, new SelectList(list))
</div>
<div>
#Html.DropDownListFor(model => model.E, new SelectList(list))
</div>
}
Hope this can help you
Hey I have tried following to set the selected value for dropdownlist.
In My controller:
u.Roles = new List<AspNetRole>();
foreach (var role in db.AspNetRoles)
{
u.Roles.Add(role);
}
And in my View:
#Html.DropDownList(Model.role.Id, new SelectList(Model.Roles, "Id", "Name"), htmlAttributes: new { #class = "form-control"})
But still not working, I did not got the selected value. When debugging I can see that Model.role.Id contains the selected value.
Note also that the Id is of type string, because it is hashed.
What I am doing wrong?
There are few ways of display DropDownList in MVC. I like the following approach.
Note: You need a collection of SelectListItem in model.
Model
public class MyModel
{
public int SelectedId { get; set; }
public IList<SelectListItem> AllItems { get; set; }
public MyModel()
{
AllItems = new List<SelectListItem>();
}
}
Controller
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyModel();
model.AllItems = new List<SelectListItem>
{
new SelectListItem { Text = "One", Value = "1"},
// *** Option two is selected by default ***
new SelectListItem { Text = "Two", Value = "2", Selected = true},
new SelectListItem { Text = "Three", Value = "3"}
};
return View(model);
}
[HttpPost]
public ActionResult Index(MyModel model)
{
// Get the selected value
int id = model.SelectedId;
return View();
}
}
View
#model DemoMvc.Controllers.MyModel
#using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
#Html.DropDownListFor(x => x.SelectedId, Model.AllItems)
<input type="submit" value="Submit" />
}
Model
public class AllControls
{
public List<Group> getChkItems { get; set; }
public bool chk { get; set; }
}
public class Group
{
public int ID { get; set; }
public string Name { get; set; }
}
Controller:
[HttpGet]
public ActionResult Index()
{
List<Group> li = new List<Group>()
{
new Group() { ID = 1, Name = "C#" },
new Group() { ID = 1, Name = "Asp.NET" },
new Group() { ID = 1, Name = "SQL" }
};
AllControls model = new AllControls();
model.getChkItems = li;
return View(model);
}
[HttpPost]
public ActionResult Index(AllControls e)
{
return View(e);
}
View:
#using (Html.BeginForm())
{
foreach (var x in #Model.getChkItems)
{
#Html.CheckBoxFor(m => m.chk, new { value = #x.ID }) #x.Name
<br />
}
<input type="submit" value="Submit" id="btn" />
}
How can I get the selected checkbox value and text in the controller?
Here goes my solution. Let your model be as shown below.
public class CheckboxModel
{
public int Id { get; set; }
public string Name { get; set; }
public bool Checked { get; set; }
}
public class MainModel
{
public List<CheckboxModel> CheckBoxes { get; set; }
}
And let your Controller GET Action be as shown below.
public ActionResult GetDatas()
{
MainModel model = new MainModel();
var list = new List<CheckboxModel>
{
new CheckboxModel{Id = 1, Name = "India", Checked = false},
new CheckboxModel{Id = 2, Name = "US", Checked = false},
new CheckboxModel{Id = 3, Name = "UK", Checked = false}
};
model.CheckBoxes = list;
return View(model);
}
And POST Action be as shown below.
[HttpPost]
public ActionResult PostDatas(MainModel model)
{
return View(model);
}
The View should be as shown below.
#model WebApplication1.Controllers.MainModel
#using (Html.BeginForm("PostDatas","Home"))
{
for (var i = 0; i < Model.CheckBoxes.Count; i++)
{
<table>
<tr>
<td>
#Html.HiddenFor(m => Model.CheckBoxes[i].Id)
#Html.HiddenFor(m => Model.CheckBoxes[i].Name)
#Html.CheckBoxFor(m => Model.CheckBoxes[i].Checked)
</td>
<td>
#Html.DisplayFor(m => Model.CheckBoxes[i].Name)
</td>
</tr>
</table>
}
<input id="submit" type="submit" value="submit" />
}
View will be rendered as shown below.
When you select India and US and click on submit button, you will get POST parameters as below.
I have got a drop downlist that, and i need to set the selected value in a view ,later on when the user selected any item in drop down list , i need to pass that one to model.. I am binding dropdown list in controller like this way ..
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Index()
{
var itemsforDropdown = new List<SelectListItem> {
new SelectListItem{ Text = "Amount" , Value = "Amount"},
new SelectListItem{Text= "Pound", Value ="Pound"},
new SelectListItem {Text ="Percent", Value ="Percent"}
};
ViewBag.ItemsforDrop = itemsforDropdown;
//ViewData["listitem"] = itemsforDropdown;
return View("DdlCrossFields");
}
and I have got a property in my model like this...
public class CrossFieldValidation
{
[ValueMustbeInRange]
public string DDlList1
{ get; set; }
public string SelectedValue
{ get; set; }
// [Required(ErrorMessage = "Quantity is required")]
[Display(Name = "Quantity:")]
public string TxtCrossField
{ get; set; }
}
and this is my view ...
#using (Html.BeginForm("PostValues", "CrossFieldsTxtboxes"))
{
#Html.ValidationSummary(true)
<div class ="editor-field">
#Html.TextBoxFor(m => m.TxtCrossField)
#Html.ValidationMessageFor(m=>m.TxtCrossField)
</div>
#Html.DropDownList("ItemsforDrop", ViewBag.ItemsforDrop as SelectList,"Select A state", new {id= "State"})
//here i need to get the selected value and i need to pass the this on to model fro future purpose "
<input id="PostValues" type="Submit" value="PostValues" />
}
would any one pls help on this ...
many thanks.....
I'm finding it hard to figure out exactly what you are trying to achieve here but I would set up the page like below.
This way, the CrossFieldValidation is sent to the PostValues with the selected value in the list
Model
public class CrossFieldValidation
{
[ValueMustbeInRange]
public string DDlList1
{ get; set; }
/* add the items list into the model */
public IEnumerable<SelectListItem> Items
{ get; set; }
public string SelectedValue
{ get; set; }
[Display(Name = "Quantity:")]
public string TxtCrossField
{ get; set; }
}
Controller
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Index()
{
var model = new CrossFieldValidation {
Items = new [] {
new SelectListItem{ Text = "Amount" , Value = "Amount"},
new SelectListItem{Text= "Pound", Value ="Pound"},
new SelectListItem {Text ="Percent", Value ="Percent"}
}
};
return View(model);
}
View
#model CrossFieldValidation
#using (Html.BeginForm("PostValues", "CrossFieldsTxtboxes"))
{
#Html.ValidationSummary(true)
<div class ="editor-field">
#Html.TextBoxFor(m => m.TxtCrossField)
#Html.ValidationMessageFor(m=>m.TxtCrossField)
</div>
#Html.DropDownListFor(m=>m.SelectedValue, new SelectList(Model.Items, "Value", "Text"))
<input id="PostValues" type="Submit" value="PostValues" />
}
In your controller [HttpPost] action add below.
string selectedVal = Request.Form["ItemsforDrop"].ToString();