How to get selected value from DropDownList [duplicate] - c#

I have dropdownlist, which I have filled from database. Now I need to get the selected value in Controller do some manipulation. But not getting the idea. Code which I have tried.
Model
public class MobileViewModel
{
public List<tbInsertMobile> MobileList;
public SelectList Vendor { get; set; }
}
Controller
public ActionResult ShowAllMobileDetails()
{
MobileViewModel MV = new MobileViewModel();
MV.MobileList = db.Usp_InsertUpdateDelete(null, "", "", null, "", 4, MergeOption.AppendOnly).ToList();
MV.Vendor = new SelectList(db.Usp_VendorList(), "VendorId", "VendorName");
return View(MV);
}
[HttpPost]
public ActionResult ShowAllMobileDetails(MobileViewModel MV)
{
string strDDLValue = ""; // Here i need the dropdownlist value
return View(MV);
}
View
<table>
<tr>
<td>Mobile Manufacured</td>
<td>#Html.DropDownList("ddlVendor", Model.Vendor, "Select Manufacurer") </td>
</tr>
<tr>
<td>
</td>
<td>
<input id="Submit1" type="submit" value="search" />
</td>
</tr>
</table>

1st Approach (via Request or FormCollection):
You can read it from Request using Request.Form , your dropdown name is ddlVendor so pass ddlVendor key in the formCollection to get its value that is posted by form:
string strDDLValue = Request.Form["ddlVendor"].ToString();
or Use FormCollection:
[HttpPost]
public ActionResult ShowAllMobileDetails(MobileViewModel MV,FormCollection form)
{
string strDDLValue = form["ddlVendor"].ToString();
return View(MV);
}
2nd Approach (Via Model):
If you want with Model binding then add a property in Model:
public class MobileViewModel
{
public List<tbInsertMobile> MobileList;
public SelectList Vendor { get; set; }
public string SelectedVendor {get;set;}
}
and in View:
#Html.DropDownListFor(m=>m.SelectedVendor , Model.Vendor, "Select Manufacurer")
and in Action:
[HttpPost]
public ActionResult ShowAllMobileDetails(MobileViewModel MV)
{
string SelectedValue = MV.SelectedVendor;
return View(MV);
}
UPDATE:
If you want to post the text of selected item as well, you have to add a hidden field and on drop down selection change set selected item text in the hidden field:
public class MobileViewModel
{
public List<tbInsertMobile> MobileList;
public SelectList Vendor { get; set; }
public string SelectVendor {get;set;}
public string SelectedvendorText { get; set; }
}
use jquery to set hidden field:
<script type="text/javascript">
$(function(){
$("#SelectedVendor").on("change", function {
$("#SelectedvendorText").val($(this).text());
});
});
</script>
#Html.DropDownListFor(m=>m.SelectedVendor , Model.Vendor, "Select Manufacurer")
#Html.HiddenFor(m=>m.SelectedvendorText)

Model
Very basic model with Gender field. GetGenderSelectItems() returns select items needed to populate DropDownList.
public enum Gender
{
Male, Female
}
public class MyModel
{
public Gender Gender { get; set; }
public static IEnumerable<SelectListItem> GetGenderSelectItems()
{
yield return new SelectListItem { Text = "Male", Value = "Male" };
yield return new SelectListItem { Text = "Female", Value = "Female" };
}
}
View
Please make sure you wrapped your #Html.DropDownListFor in a form tag.
#model MyModel
#using (Html.BeginForm("MyController", "MyAction", FormMethod.Post)
{
#Html.DropDownListFor(m => m.Gender, MyModel.GetGenderSelectItems())
<input type="submit" value="Send" />
}
Controller
Your .cshtml Razor view name should be the same as controller action name and folder name should match controller name e.g Views\MyController\MyAction.cshtml.
public class MyController : Controller
{
public ActionResult MyAction()
{
// shows your form when you load the page
return View();
}
[HttpPost]
public ActionResult MyAction(MyModel model)
{
// the value is received in the controller.
var selectedGender = model.Gender;
return View(model);
}
}
Going further
Now let's make it strongly-typed and enum independent:
var genderSelectItems = Enum.GetValues(typeof(Gender))
.Cast<string>()
.Select(genderString => new SelectListItem
{
Text = genderString,
Value = genderString,
}).AsEnumerable();

MVC 5/6/Razor Pages
I think the best way is with strongly typed model, because Viewbags are being aboused too much already :)
MVC 5 example
Your Get Action
public async Task<ActionResult> Register()
{
var model = new RegistrationViewModel
{
Roles = GetRoles()
};
return View(model);
}
Your View Model
public class RegistrationViewModel
{
public string Name { get; set; }
public int? RoleId { get; set; }
public List<SelectListItem> Roles { get; set; }
}
Your View
<div class="form-group">
#Html.LabelFor(model => model.RoleId, htmlAttributes: new { #class = "col-form-label" })
<div class="col-form-txt">
#Html.DropDownListFor(model => model.RoleId, Model.Roles, "--Select Role--", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.RoleId, "", new { #class = "text-danger" })
</div>
</div>
Your Post Action
[HttpPost, ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegistrationViewModel model)
{
if (ModelState.IsValid)
{
var _roleId = model.RoleId,
MVC 6 It'll be a little different
Get Action
public async Task<ActionResult> Register()
{
var _roles = new List<SelectListItem>();
_roles.Add(new SelectListItem
{
Text = "Select",
Value = ""
});
foreach (var role in GetRoles())
{
_roles.Add(new SelectListItem
{
Text = z.Name,
Value = z.Id
});
}
var model = new RegistrationViewModel
{
Roles = _roles
};
return View(model);
}
Your View Model will be same as MVC 5
Your View will be like
<select asp-for="RoleId" asp-items="Model.Roles"></select>
Post will also be same
Razor Pages
Your Page Model
[BindProperty]
public int User User { get; set; } = 1;
public List<SelectListItem> Roles { get; set; }
public void OnGet()
{
Roles = new List<SelectListItem> {
new SelectListItem { Value = "1", Text = "X" },
new SelectListItem { Value = "2", Text = "Y" },
new SelectListItem { Value = "3", Text = "Z" },
};
}
<select asp-for="User" asp-items="Model.Roles">
<option value="">Select Role</option>
</select>
I hope it may help someone :)

If you want to use #Html.DropDownList , follow.
Controller:
var categoryList = context.Categories.Select(c => c.CategoryName).ToList();
ViewBag.CategoryList = categoryList;
View:
#Html.DropDownList("Category", new SelectList(ViewBag.CategoryList), "Choose Category", new { #class = "form-control" })
$("#Category").on("change", function () {
var q = $("#Category").val();
console.log("val = " + q);
});

If you're looking for something lightweight, I'd append a parameter to your action.
[HttpPost]
public ActionResult ShowAllMobileDetails(MobileViewModel MV, string ddlVendor)
{
string strDDLValue = ddlVendor; // Of course, this becomes silly.
return View(MV);
}
What's happening in your code now, is you're passing the first string argument of "ddlVendor" to Html.DropDownList, and that's telling the MVC framework to create a <select> element with a name of "ddlVendor." When the user submits the form client-side, then, it will contain a value to that key.
When MVC tries to parse that request into MV, it's going to look for MobileList and Vendor and not find either, so it's not going to be populated. By adding this parameter, or using FormCollection as another answer has suggested, you're asking MVC to specifically look for a form element with that name, so it should then populate the parameter value with the posted value.

Use SelectList to bind #HtmlDropdownListFor and specify selectedValue parameter in it.
http://msdn.microsoft.com/en-us/library/dd492553(v=vs.108).aspx
Example : you can do like this for getting venderid
#Html.DropDownListFor(m => m.VendorId,Model.Vendor)
public class MobileViewModel
{
public List<tbInsertMobile> MobileList;
public SelectList Vendor { get; set; }
public int VenderID{get;set;}
}
[HttpPost]
public ActionResult Action(MobileViewModel model)
{
var Id = model.VenderID;

I was having the same issue in asp.NET razor C#
I had a ComboBox filled with titles from an EventMessage, and I wanted to show the Content of this message with its selected value to show it in a label or TextField or any other Control...
My ComboBox was filled like this:
#Html.DropDownList("EventBerichten", new SelectList(ViewBag.EventBerichten, "EventBerichtenID", "Titel"), new { #class = "form-control", onchange = "$(this.form).submit();" })
In my EventController I had a function to go to the page, in which I wanted to show my ComboBox (which is of a different model type, so I had to use a partial view)?
The function to get from index to page in which to load the partial view:
public ActionResult EventDetail(int id)
{
Event eventOrg = db.Event.Include(s => s.Files).SingleOrDefault(s => s.EventID == id);
// EventOrg eventOrg = db.EventOrgs.Find(id);
if (eventOrg == null)
{
return HttpNotFound();
}
ViewBag.EventBerichten = GetEventBerichtenLijst(id);
ViewBag.eventOrg = eventOrg;
return View(eventOrg);
}
The function for the partial view is here:
public PartialViewResult InhoudByIdPartial(int id)
{
return PartialView(
db.EventBericht.Where(r => r.EventID == id).ToList());
}
The function to fill EventBerichten:
public List<EventBerichten> GetEventBerichtenLijst(int id)
{
var eventLijst = db.EventBericht.ToList();
var berLijst = new List<EventBerichten>();
foreach (var ber in eventLijst)
{
if (ber.EventID == id )
{
berLijst.Add(ber);
}
}
return berLijst;
}
The partialView Model looks like this:
#model IEnumerable<STUVF_back_end.Models.EventBerichten>
<table>
<tr>
<th>
EventID
</th>
<th>
Titel
</th>
<th>
Inhoud
</th>
<th>
BerichtDatum
</th>
<th>
BerichtTijd
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.EventID)
</td>
<td>
#Html.DisplayFor(modelItem => item.Titel)
</td>
<td>
#Html.DisplayFor(modelItem => item.Inhoud)
</td>
<td>
#Html.DisplayFor(modelItem => item.BerichtDatum)
</td>
<td>
#Html.DisplayFor(modelItem => item.BerichtTijd)
</td>
</tr>
}
</table>
VIEUW: This is the script used to get my output in the view
<script type="text/javascript">
$(document).ready(function () {
$("#EventBerichten").change(function () {
$("#log").ajaxError(function (event, jqxhr, settings, exception) {
alert(exception);
});
var BerichtSelected = $("select option:selected").first().text();
$.get('#Url.Action("InhoudByIdPartial")',
{ EventBerichtID: BerichtSelected }, function (data) {
$("#target").html(data);
});
});
});
</script>
#{
Html.RenderAction("InhoudByIdPartial", Model.EventID);
}
<fieldset>
<legend>Berichten over dit Evenement</legend>
<div>
#Html.DropDownList("EventBerichten", new SelectList(ViewBag.EventBerichten, "EventBerichtenID", "Titel"), new { #class = "form-control", onchange = "$(this.form).submit();" })
</div>
<br />
<div id="target">
</div>
<div id="log">
</div>
</fieldset>

Thanks - this helped me to understand better ansd solve a problem I had.
The JQuery provided to get the text of selectedItem did NOT wwork for me
I changed it to
$(function () {
$("#SelectedVender").on("change", function () {
$("#SelectedvendorText").val($(**"#SelectedVender option:selected"**).text());
});
});

Simple solution not sure if this has been suggested or not. This also may not work for some things. That being said this is the simple solution below.
new SelectListItem { Value = "1", Text = "Waiting Invoices", Selected = true}
List<SelectListItem> InvoiceStatusDD = new List<SelectListItem>();
InvoiceStatusDD.Add(new SelectListItem { Value = "0", Text = "All Invoices" });
InvoiceStatusDD.Add(new SelectListItem { Value = "1", Text = "Waiting Invoices", Selected = true});
InvoiceStatusDD.Add(new SelectListItem { Value = "7", Text = "Client Approved Invoices" });
#Html.DropDownList("InvoiceStatus", InvoiceStatusDD)
You can also do something like this for a database driven select list. you will need to set selected in your controller
#Html.DropDownList("ApprovalProfile", (IEnumerable<SelectListItem>)ViewData["ApprovalProfiles"], "All Employees")
Something like this but better solutions exist this is just one method.
foreach (CountryModel item in CountryModel.GetCountryList())
{
if (item.CountryPhoneCode.Trim() != "974")
{
countries.Add(new SelectListItem { Text = item.CountryName + " +(" + item.CountryPhoneCode + ")", Value = item.CountryPhoneCode });
}
else {
countries.Add(new SelectListItem { Text = item.CountryName + " +(" + item.CountryPhoneCode + ")", Value = item.CountryPhoneCode,Selected=true });
}
}

Related

How to fill the second dropdown on the selection of first dropdown

I'm implementing asp.net core project and I have a selectList that shows regions and after choosing a region from it, I want to fetch related data to a second dropdown that shows zones. Here is my code till now:
My edited code:
public class OperatorViewModel {
public IEnumerable<BuyWasteRequestViewModel> BuyWasteRequestVM { get; set; }
[Required] public string SelectedRegionID { get; set; }
[Required]
public string SelectedZoneID { get; set; }
public string SelectedRegionText { get; set; }
public string SelectedZoneText { get; set; }
}
And Here my view:
#model MyProject.ViewModels.OperatorViewModel
<form method="post">
#Html.DropDownListFor(m => m.SelectedRegionID, (IEnumerable<SelectListItem>)ViewBag.RegionId, "select", new { #style = "position: absolute; width: 42%; padding: 2%; border: 1px solid #ced4da; border-radius: 3px; right: 4.5rem; height: 2.35rem;" })
#Html.HiddenFor(m => m.SelectedRegionText)
<select id="SelectedZoneID" name="#Html.NameFor(c=>c.SelectedZoneID)" class="form-control statesSelect" asp-items="#(new SelectList(#ViewBag.ZoneID,"Id", "Name"))">
<option value='0'>select</option>
</select>
#Html.HiddenFor(m => m.SelectedZoneText)
</form>
<script>
jQuery(document).ready(function ($) {
$("#SelectedRegionID")
.change(function () {
var id = $(this).val();
$("#SelectedRegionText").attr("value", $("#SelectedRegionID option:selected").text());
$.getJSON('#Url.Action("GetZones", "Operator")/' + id, function (data) {
//delete the options of $("#SelectedZoneID") and add new options
$("#SelectedZoneID").empty();
$("#SelectedZoneID").append('<option value="0">select</option>');
$.each(data, function (value, text) {
$("#SelectedZoneID").append('<option value="' + text.value + '">' + text.text + '</option>');
});
});
});
$("#SelectedZoneID").change(function () {
$("#SelectedZoneText").attr("value", $("#SelectedZoneID option:selected").text());
});
$("#SelectedRegionID")
.change(function() {
$('#SelectedRegionText').val($(this).find("option:selected").text());
});
In my controller:
public class OperatorController : Controller
{
private readonly WasteAPIContext _context;
public OperatorController(WasteAPIContext context)
{
_context = context;
}
[HttpPost]
public IActionResult Index(OperatorViewModel buywastervm)
{
return BuildIndexModel(buywastervm.SelectedRegionID, buywastervm.SelectedRegionText, buywastervm.SelectedZoneID, buywastervm.SelectedZoneText);
}
public IActionResult BuildIndexModel(string selectedRegionID, string selectedRegionText,string selectedZoneID, string selectedZoneText){
ViewData["RegionId"] = new SelectList(_context.Region, "Id", "Name", "select");
ViewData["ZoneId"] = new SelectList(_context.Zone.Where(c => c.RegionId == selectedZoneID), "Id", "Name", "select");
OperatorVM.BuyWasteRequestVM = bwrvm;
OperatorVM.SelectedRegionID = selectedRegionID;
OperatorVM.SelectedRegionText = selectedRegionText;
OperatorVM.SelectedZoneID = selectedZoneID;
OperatorVM.SelectedZoneText = selectedZoneText;
return View(OperatorVM);
}
public JsonResult GetZones(string ID)
{
List<SelectListItem> ZoneList = new List<SelectListItem>();
var zones = _context.Zone.Where(c => c.RegionId == ID).Select(c => new
{
Value = c.Id,
Text = c.Name
}).ToList();
foreach (var item in zones)
{
SelectListItem slist = new SelectListItem();
slist.Value = item.Value; /*0 + mvalue*/
slist.Text = item.Text;
ZoneList.Add(slist);
}
ViewData["ZoneId"] = new SelectList(_context.Zone.Where(c => c.RegionId == ID), "Id", "Name", "select");
return Json(ZoneList);
}
Now my problem is, I want after choosing my considering region from region selectlist and accordingly choosing an item from zone selectlist and then submitting the form, I have the ability to see all populated related zones to selected region displayed before submitting the form in zone selectlist. Right now, after submitting the form, I'm just able to see item in zone selectlist. Moreover, I need after submitting the form, the user can see the selected item in zone list as the selected option. Now I can see the selected region in Region selectlist after submitting the form which I set its data in my model after submitting the form. I kindly appreciate of any help.
Here is a working demo:
View(TestOperatorViewModel.cshtml):
<form method="post" style="height: 4rem;">
<table cellspacing="5" cellpadding="5" border="0">
<tbody>
<tr>
<td>
<label>
region:
#Html.DropDownListFor(m => m.SelectedRegionID, (IEnumerable<SelectListItem>)ViewBag.RegionId, "select")
#Html.HiddenFor(m => m.SelectedRegionText)
</label>
</td>
<td>
<label>
Zone:
#* I change the dropdownlist *#
<select id="SelectedZoneID" name="SelectedZoneID">
<option value='0'>select</option>
</select>
#Html.HiddenFor(m => m.SelectedZoneText)
</label>
</td>
</tr>
</tbody>
</table>
<button>submit</button>
</form>
#section scripts{
<script>
$("#SelectedRegionID")
.change(function () {
var id = $(this).val();
$("#SelectedRegionText").attr("value", $("#SelectedRegionID option:selected").text());
$.getJSON('#Url.Action("GetZones", "Test")/' + id, function (data) {
//delete the options of $("#SelectedZoneID") and add new options
$("#SelectedZoneID").empty();
$("#SelectedZoneID").append('<option value="0">select</option>');
$.each(data, function (value, text) {
$("#SelectedZoneID").append('<option value="' + value + '">' + text.text + '</option>');
});
});
});
$("#SelectedZoneID").change(function () {
$("#SelectedZoneText").attr("value", $("#SelectedZoneID option:selected").text());
})
</script>
}
Controller(I use fake data to test,ControllerName is TestController):
[HttpGet]
public IActionResult TestOperatorViewModel()
{
List<SelectListItem> RegionId = new List<SelectListItem>();
RegionId.Add(new SelectListItem { Value = "r1", Text = "id1" });
RegionId.Add(new SelectListItem { Value = "r2", Text = "id2" });
RegionId.Add(new SelectListItem { Value = "r3", Text = "id3" });
ViewBag.RegionId = RegionId;
return View();
}
[HttpPost]
public IActionResult TestOperatorViewModel(OperatorViewModel operatorViewModel)
{
return Ok();
}
public JsonResult GetZones(string ID)
{
List<SelectListItem> ZoneList = new List<SelectListItem>();
ZoneList.Add(new SelectListItem { Value = "1", Text = "one"+ID });
ZoneList.Add(new SelectListItem { Value = "2", Text = "two"+ID });
ZoneList.Add(new SelectListItem { Value = "3", Text = "three"+ID });
return Json(ZoneList);
}
result:

ViewModel enumeration is empty on HttpPost

I'm working in ASP.Net, and have an enumeration of viewmodels I want to display in a page. They contain a dropdown, and when said dropdown is updated, I have to take that enumeration of viewmodels, change the hirearchy inside it, and post it back with the changes. However, when I make my post, instead of sending the contained viewmodels, it sends an empty enumeration.
So far, I've tried switching my "foreach" in my view for a "for". I've also tried changing some names, seeing if the model binder was being the issue, but it doesn't seem so.
Here is the code for, respectively, the view, the viewmodel and the controller.
View
#using (Html.BeginForm())
{
#Html.AntiForgeryToken();
for (int i = 0; i < Model.Count(); i++)
{
#Html.DropDownListFor(model => model.ElementAt(i).PickedNormId, Model.ElementAt(i).PickableNorms, UiText.Prosyn.N_A, htmlAttributes: new { #class = "form-control dropdown_search", #name="NormPicker"#*, #onchange = "this.form.submit();"*# })
}
<div>
<input name="selectedNormList" type="submit">
</div>
}
ViewModel
public class NormPickerViewModel : ViewModel
{
public SelectList PickableNorms { get; set; }
public int PickedNormId { get; set; }
}
Controller
public virtual ActionResult Index()
{
List<NormPickerViewModel> viewModels = new List<NormPickerViewModel>();
viewModels.Add(new NormPickerViewModel()
{
PickableNorms = new SelectList(
_normRepository.GetAll().Where(x => x.Depth == 1).ToList(),
"Id",
"Description"
)
});
return View(viewModels);
}
[HttpPost]
public virtual ActionResult Index(IEnumerable<NormPickerViewModel> selectedNormList)
{
// selectedNormList's count is always zero.
}
Normally, I'd expect to find the dropdowns I passed in the "Get" with their updated selected values, but what I'm getting is an empty enumeration.
I tried reproducing your source code, you need update 2 items and it worked:
Change from IEnumerable<NormPickerViewModel> selectedNormList to IEnumerable<NormPickerViewModel> normPickerViewModel in controller.
Add name for select tag (DropDownListFor) Name = "normPickerViewModel[" + i + "].PickedNormId" in cshtml file.
Here is Controller code
[HttpGet]
public virtual ActionResult Index()
{
List<NormPickerViewModel> viewModels = new List<NormPickerViewModel>();
viewModels.Add(new NormPickerViewModel()
{
PickableNorms = new SelectList(
new List<dynamic> { new { Id = 1, Description = "Test1" }, new { Id = 2, Description = "Test2" } },
"Id",
"Description"
)
});
viewModels.Add(new NormPickerViewModel()
{
PickableNorms = new SelectList(
new List<dynamic> { new { Id = 3, Description = "Test3" }, new { Id = 4, Description = "Test4" } },
"Id",
"Description"
)
});
return View(viewModels);
}
[HttpPost]
public virtual ActionResult Index(IEnumerable<NormPickerViewModel> normPickerViewModel)
{
// selectedNormList's count is always zero.
return null;
}
and cshtml code
#using (Html.BeginForm())
{
#Html.AntiForgeryToken();
for (int i = 0; i < Model.Count(); i++)
{
#Html.DropDownListFor(model => model.ElementAt(i).PickedNormId, Model.ElementAt(i).PickableNorms, "NA", htmlAttributes: new
{
#class = "form-control dropdown_search",
Name = "normPickerViewModel[" + i + "].PickedNormId"#*, #onchange = "this.form.submit();"*#
})
}
<div>
<input name="selectedNormList" type="submit">
</div>
}

DropDownList - How to add SelectListItem ASP.NET MVC

I have an DropDownList ,which is showing list of Status,but when i Select an item from DropDownlist and than i Checked HTML Markup i can see there isnt Selected attr and than i researched and find out I need SelectListItem in my Controller and than i tried to implement it in my Controller,but i got some errors :) as usually i implement DropDown in my Razor View (static) , but this time which is first time :) i want implement in my Controller so it becomes dynamic.
Can anyone point me in right direction :)
Thanks in advance :)
Controller:
//DropDown
public List<VMRMA.NameStatusDropDown> GetStatusForDropDown()
{
List<VMRMA.NameStatusDropDown> result = new List<VMRMA.NameStatusDropDown>();
var obj = db.RMAStatus.Select(u => u).ToList();
if (obj != null && obj.Count() > 0)
{
foreach (var data in obj)
{
VMRMA.NameStatusDropDown model = new VMRMA.NameStatusDropDown();
model.Status = data.Status;
model.ID = data.ID;
result.Add(model);
}
}
return result;
}
//Dropdown runs in this Action
public ActionResult RMA ()
{
VMRMA model = new VMRMA();
model.NameStatusDropDowns = GetStatusForDropDown();
//RMA query and some an other stuff
return View(model);
}
ViewModel:
public class VMRMA
{
public List<NameStatusDropDown> NameStatusDropDowns { get; set; }
//DropDown
public class NameStatusDropDown
{
public NameStatusDropDown()
{
}
public NameStatusDropDown(int ID, string Status)
{
this.ID = ID;
this.Status = Status;
}
public int ID { get; set; }
public string Status { get; set; }
}
}
View:
#using ModelNamespace.Models
#model VMRMA
<form>
<div class="form-group">
<label class="form-control-label">Select a status</label>
<br />
<select>
<option>Select</option>
#foreach (var item in Model.NameStatusDropDowns)
{
<option value="#item.ID">#item.Status</option>
}
</select>
</div>
<div class="form-group">
<input type="submit" value="Send data" class="btn btn-primary">
</div>
</form>
HTML Markup:
<div class="form-group">
<label class="form-control-label">Select a status</label>
<br>
<select>
<option>Select</option>
<option value="1">Sendt</option>
<option value="2">Under behandling</option>
<option value="3">Blive behandlet</option>
<option value="4">Modtaget</option>
</select>
</div>
This two Post helped me out to solve the problem and Thanks to #Stephen Muecke with his good post, Which is wroted Here and Thanks to this post with great explanation, which is wroted Here.
Here is what i did , maybe it helped someone one day :) :
Add To Property to my View Model :
public class VMRMA
{
public List<SelectListItem> Status { set; get; }
public int? SelectedStatus { set; get; }
}
Change my ActionResult to :
public ActionResult RMA (int Id)
{
VMRMA model = new VMRMA();
model.Status = new SelectList(DatabaseNameSpace.RMAStatus, "ID",
"Status").ToList();
//some an other stuff
return View(model);
}
and than change my View to :
#Html.DropDownListFor(s => s.SelectedStatus, Model.Status, "- Select -", new { #class = "form-control" })
Controller:
ViewBag.Statuses= new SelectList(_context.RMAStatus
.Select(item => new { value = item.Id, text = item.Status}), "value", "text", selectedId);
View:
#Html.DropDownListFor(x => x.StatusId, ViewBag.Statuses as SelectList, "- please select -")
Create a partial view as this:
#model MyApp.Models.MyClass
#{
Layout = null;
}
#*#Html.Partial("ActionMethod", "Controller", new ViewDataDictionary { { "Name", "TestName" } })*#
#Html.DropDownList((String)TempData["Name"], new SelectList( ViewBag.Specialities,"Value","Text"),
new { #class = "form-control", #multiple="multiple" });
Then in your controller
List<MyClass> lstSpecialities =
ViewBag.Specialities = lstSpecialities; // Now it is available for the view
Last step, load your view using #Html.RenderAction()

MVC ViewModel not posting back

I have seen lots of examples on this, but cannot get any working. I have built this example to prove/disprove passing back of the view model SomeDataViewModel.
I am trying to post back the dropdownlist data. Everything works ok, but the OtherData property on TestViewModel never returns the collect that was passed in.
Have tried adding:
#Html.HiddenFor(m => Model.OtherData)
but again this just produces the following error;
The parameter conversion from type 'System.String' to type 'SomeDataViewModel' failed because no type converter can convert between these types
The Code:
ViewModels
TestViewmodel
public class TestViewModel
{
public TestViewModel()
{
OtherData = new List<SomeDataViewModel>();
}
public int Id { get; set; }
public String Name { get; set; }
public DateTime DoB { get; set; }
public int SelectedOtherData { get; set; }
public List<SomeDataViewModel> OtherData { get; set; }
public IEnumerable<SelectListItem> TolistData()
{
IEnumerable<SelectListItem> ret = OtherData.Select(i => new SelectListItem() { Text = i.Text, Value=i.Value });
return ret;
}
}
SomeDataViewmodel
public class SomeDataViewModel
{
public string Value { get; set; }
public string Text { get; set; }
}
View
#model TestViewModel
#{
ViewBag.Title = "Home Page";
}
#using (Html.BeginForm("Index","Home"))
{
<div class="row">
<div class="col-md-12">
<br />
#Html.EditorFor(m => Model.Id)
<br />
#Html.EditorFor(m => Model.Name)
<br />
#Html.EditorFor(m => Model.DoB)
<br/>
#Html.DropDownListFor(m => Model.SelectedOtherData, Model.TolistData(), new { id = "OtherData" })
<p><a class="btn btn-default" href="http://go.microsoft.com/fwlink/?LinkId=301865">Learn more ยป</a></p>
</div>
</div>
<button id="dosomething" formmethod="post">Post</button>
}
Controller
public ActionResult Index()
{
var model = new TestViewModel() {
Id = 99,
Name = "Billy",
DoB = DateTime.Now
};
model.OtherData.Add(
new SomeDataViewModel { Text = "Bob", Value = "1" });
model.OtherData.Add(
new SomeDataViewModel { Text = "Sally", Value = "2" });
return View(model);
}
[HttpPost]
public ActionResult Index(TestViewModel retModel)
{
if (ModelState.IsValid)
{
if (retModel.OtherData.Count() == 0)
{
var dud = true;
}
}
return View(retModel);
}
You can't render hidden inputs for complex data with #Html.HiddenFor helper.
You should use it only with simple types. Becouse you got array you should write something like this:
#for(int i = 0; i < Model.OtherData.Count(); i++)
{
#Html.HiddenFor(m => Model.OtherData[i].Text)
#Html.HiddenFor(m => Model.OtherData[i].Value)
//... other fields.
#Html.HiddenFor(m => Model.OtherData[i].OtherProperty)
}
Use for loop instead of foreach becouse you should same your mappings for right binding on form POST.
Certainly there is a type conversion error. your SelectedOtherData is type of int while selectlistitem value is type of string

ViewModel post back a null Collection in asp.net mvc 5

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.

Categories