MVC4 Get listboxfor Text & Value properties - asp.net-mvc-4

In My MVC4 EF5 App i'm using 2 listboxes. each listbox is bounded to a List property of my view model.
i would like to get all listboxes items (and i mean all SelectedListItem - Selected, Text, Value) when i submit a from.
This is how i do so (with no sucess..)
My View Model:
public class PriorityViewModel
{
public List<SelectListItem> lst_fromCEID { get; set; }
public List<SelectListItem> lst_C2C { get; set; }
public PriorityViewModel()
{
lst_C2C = new List<SelectListItem>();
lst_fromCEID = new List<SelectListItem>();
}
}
My Action:
public ActionResult Index()
{
var model = new PriorityViewModel();
var c2c_ceid_source = _unitOfWork.ActionRepository.GetC2C_SourceCEID();
model.lst_fromCEID = _unitOfWork.EntityRepository.GetEntitiesByC2CSource(c2c_ceid_source);
return View(model);
}
public ActionResult UpdatePriority(PriorityViewModel model)
{
//save manual changes to DB
SaveManualPriorityToDB(model);
...
}
My View:
#model TRM.Models.ViewModel.PriorityViewModel
#{
ViewBag.Title = "Index";
}
#*#Html.Action("Run");*#
#using (Html.BeginForm("UpdatePriority", "Priority", FormMethod.Post))
{
#Html.Hidden("demoQuantity", Model.demoQuantity)
#Html.Hidden("installQuantity", Model.installQuantity)
#Html.Hidden("CIP_Quantity", Model.CIP_Quantity)
#Html.Hidden("C2C_Quantity", Model.C2C_Quantity)
<table>
<tr>
<td>
From CEID
#Html.ListBoxFor(model => model.lst_fromCEID, #Model.lst_fromCEID, new { width = "50px" })
</td>
<td style="width:50px">
<input id="btnRemoveAllC2C" type="button" value=" << " onclick="removeallItemsC2C();" />
<input id="btnAddAllC2C" type="button" value=" >> " onclick="addallItemsC2C();" />
<input id="btnAddC2C" type="button" value=" > " onclick="addItemC2C();" />
<input id="btnRemoveC2C" type="button" value=" < " onclick="removeItemC2C();" />
</td>
<td style="width:50px">
C2C
#Html.ListBoxFor(model => model.lst_C2C, new MultiSelectList(Model.lst_C2C), new { width = "50px" })
</td>
</tr>
<tr>
<td>
<h2>Install & Orphan</h2>
</td>
</tr>
</table>
<input type="submit" value="Run Transition!" onclick="SelectAllItems()"/>
}
#section scripts {
<script src="~/Scripts/MyScripts/PriorityScript.js"></script>
}
My Js File:
function addItemC2C() {
$("#lst_fromCEID option:selected").appendTo("#lst_C2C");
$("#lst_C2C option").attr("selected", false);
}
function addallItemsC2C() {
$("#lst_fromCEID option").appendTo("#lst_C2C");
$("#lst_C2C option").attr("selected", false);
}
function removeItemC2C() {
$("#lst_C2C option:selected").appendTo("#lst_fromCEID");
$("#lst_fromCEID option").attr("selected", false);
}
function removeallItemsC2C() {
$("#lst_C2C option").appendTo("#lst_fromCEID");
$("#lst_fromCEID option").attr("selected", false);
}
if i set the viewModel properties to List i can get the listbox text out on button submit. but this is not enough for me, i need Text and Value.
Thx..

Related

Model binding with multiple rows in ASP.NET Core MVC

I've been stuck on this for so long, any help or direction is appreciated.
Basically I want my controller to pass a json data like this:
Initially, I wanted to do it with model binding, but at this moment even jQuery will be fine.
Model class:
public class Orders
{
public int Id { get; set; }
public int CustomerId { get; set; }
public string ItemName { get; set; }
public double Price { get; set; }
public IEnumerable<SelectListItem> CustomersList { get; set; }
}
Controller code:
// GET: OrdersController/Create
public ActionResult Create()
{
var listCustomers = dbContext.Customers
.Select(x => new SelectListItem
{
Value = x.Id.ToString(),
Text = x.DepName
});
var orders = new Orders()
{
CustomersList = listCustomers
};
//var orders = new List<Orders>();
return View(orders);
}
// POST: OrdersController/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(List<Orders> ordersList)
{
Orders newOrders = new Orders();
foreach (var order in ordersList)
{
newOrders.Id = 0;
newOrders.CustomerId = order.CustomerId;
newOrders.ItemName = order.ItemName;
newOrders.Price = order.Price;
}
// I will be processing newOrders into application/json and sending to the backend API
}
View markup:
#model List<NameSpace.Web.Models.Orders>
#{
ViewData["Title"] = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="row">
<div class="col-md-8">
<div class="form-group">
#Html.LabelFor(model => model.CustomerId, htmlAttributes: new { #class = "control-label col-md-6" })
#Html.DropDownListFor(model => model.CustomerId, Model.CustomersList, "Select Customer ", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.DepId, "", new { #class = "text-danger" })
</div>
</div>
<hr>
<div class="col-md-12">
<div class=''></div>
<thead>
<tr>
//<th style="width:150px">Cust. Id</th>
<th style="width:150px">Item Name</th>
<th style="width:150px">Price</th>
</tr>
</thead>
<tbody id="tblOrdersBody">
<tr>
//<td><input name='Orders[0].CustomerId' class="form-control" /></td>
<td><input name='Orders[0].ItemName' class="form-control" /></td>
<td><input name='Orders[0].Price' class="form-control" /></td>
</tr>
</tbody>
<tfooter>
<tr><a hre="#" class="btn btn-success" id="addOrder"></a> </tr>
</tfooter>
</table>
<div class="row">
<div class="tile-footer d-flex justify-content-around">
#Html.ActionLink("Cancel", "Index", null, new { #class = "btn btn-danger" })
<input id="btnSave" type="submit" value="Save Order" class="btn btn-primary" />
</div>
</div>
</div>
</div>
}
#section Scripts {
<script>
var i = 1;
$(document).on("click", "#addOrder", function () {
$("#tblOrdersBody").append("<tr>"
//+ "<td><input name='Orders[" + i + "].CustomerId' class='form-control' /></td>"
+ "<td><input name='Orders[" + i + "].ItemName' class='form-control'/></td>"
+ "<td><input name='Orders[" + i + "].Price' class='form-control'/></td>"
+ "<td><button type='button' class='btn btn-danger' id='btnRemove' </buuton></td>"
+ "</tr > ");
i++;
});
</script>
}
I have seen many similar questions , the closest one being this one, but I could figure it out, the controller receives 0 in item counts
public ActionResult Create(List ordersList)
You action parameter named ordersList, please try to modify the name attribute of your input(s) on view page, like below.
<tbody id="tblOrdersBody">
<tr>
<td><input name='ordersList[0].CustomerId' class="form-control" /></td>
<td><input name='ordersList[0].ItemName' class="form-control" /></td>
<td><input name='ordersList[0].Price' class="form-control" /></td>
</tr>
</tbody>
JS code
<script>
var i = 1;
$(document).on("click", "#addOrder", function () {
$("#tblOrdersBody").append("<tr>"
+ "<td><input name='ordersList[" + i + "].CustomerId' class='form-control' /></td>"
+ "<td><input name='ordersList[" + i + "].ItemName' class='form-control'/></td>"
+ "<td><input name='ordersList[" + i + "].Price' class='form-control'/></td>"
+ "<td><button type='button' class='btn btn-danger' id='btnRemove' </buuton></td>"
+ "</tr > ");
i++;
});
</script>
Test Result

Razor Engine Issue in MVC4

When I declare a text box in view page the below error will appear
The type arguments for method 'System.Web.Mvc.Html.InputExtensions.TextBoxFor<TModel,TProperty>(System.Web.Mvc.HtmlHelper<TModel>,
System.Linq.Expressions.Expression<System.Func<TModel,TProperty>>)'
cannot be inferred from the usage. Try specifying the type arguments
explicitly
even I included
<compilation debug="true" targetFramework="4.0">
<!-- ... -->
</compilation>
this in webconfig file
but the same error shows .
............
my code
#Html.TextBoxFor(x => x.Entity, new { #id = "Entityname" })
//..........
model
public string Entity { set; get; }
//.........
//..............
.cshtml page
#model BOSSNew.Models.NewQuantifierM
#{Layout = "../Shared/_Layout.cshtml";}
<div class="breadCrumbHolder">
#{Html.RenderAction("BreadCrumb", "Base", new { menulist = new string[] { "Quantifier", "New Quantifier" }, CurrentURL = new string[] { "#", "#" } });}
</div>
<div class="divContentPane">
<div class="contentPaneHead">
<span class="contentPaneTitle">Users Details </span>
</div>
<table class="ClsTable ClsPad0">
<tr class="even">
<th>#LabelHelper.GetLabel("THLentity", 3)
</th>
<td>
#Html.TextBoxFor(x => x.Entity, new { #id = "Entityname" })
<img title="" id="selectentit" style="margin: 5px" onclick="getentity('txtentity','optentity')"
alt="" src="../../../Name.Controls/Themes/Name-Theme/images/entity.png">
</td>
</tr>
</table>
</div>
//.............
Any idea ?
Any help will be appreciated
You haven't defined model for a view, so you can't use
x => x.Field
expression.
It should look more or less like that:
SomeView.cshtml
#model SomeModel
#{Layout = "../Shared/_Layout.cshtml";}
<div class="breadCrumbHolder">
#{Html.RenderAction("BreadCrumb", "Base", new { menulist = new string[] { "Quantifier", "New Quantifier" }, CurrentURL = new string[] { "#", "#" } });}
</div>
<div class="divContentPane">
<div class="contentPaneHead">
<span class="contentPaneTitle">Users Details </span>
</div>
<table class="ClsTable ClsPad0">
<tr class="even">
<th>#LabelHelper.GetLabel("THLentity", 3)
</th>
<td>
#Html.TextBoxFor(x => x.Entity, new { #id = "Entityname" })
<img title="" id="selectentit" style="margin: 5px" onclick="getentity('txtentity','optentity')"
alt="" src="../../../Name.Controls/Themes/Name-Theme/images/entity.png">
</td>
</tr>
</table>
</div>
SomeModel.cs
public class SomeModel
{
public string Entity { set; get; }
}
And finally in your action method...
public ActionResult SomeMethod()
{
var model = new SomeModel();
//here fill the entity field
return View(model);
}

Mvc 4 model binding not working dynamically added partial view

I am trying to create a form where in user can add controls. I have main view
#model MVCDynamicFormGenerator.Models.FormViewModel
#{
ViewBag.Title = "Create";
}
#using (#Html.BeginForm())
{
<fieldset>
#Html.HiddenFor(form => form.Form.Uid)
#Html.Hidden("ListFields", ViewData["ListFields"])
<p>
#Html.LabelFor(form => form.Form.FormName)
#Html.TextBoxFor(form => form.Form.FormName)
</p>
<div id="FormFieldList">
#foreach (var formfield in Model.FormFields)
{
switch (formfield.ControlType)
{
case ("Textbox"):
Html.RenderPartial("Textbox", formfield);
break;
}
}
</div>
<h4>
[+] Add a Field
</h4>
<div id="FieldType">
<table>
<tr>
<th>
Select a Field Type
</th>
</tr>
<tr>
<td>
#Html.DropDownList("FieldTypes", new SelectList(Model.FormFields[0].FormFieldTypes, "Value", "Text"), new { id = "SelectedFieldUid" })
#Html.ActionLink("Add Field", "NewFormField", new { formId = ViewContext.FormContext.FormId, selectedFieldType = "SelectedFieldUid" }, new { id = "newFormField" })
#Html.ValidationMessageFor(model => model.FormFields)
</td>
</tr>
</table>
</div>
<p>
<input type="submit" value="Create" />
<input type="button" value="Cancel" '#Url.Action("List")');" />
</p>
</fieldset>
}
On dropdown change I am loading a partial view which is working(User can add n number of times)
#model MVCDynamicFormGenerator.Models.FormFieldViewModel
<div class="FormField">
#using (#Html.BeginForm())
{
<table>
<tr>
<th>
Form Field
</th>
<th>
Field Type
</th>
</tr>
<tr>
<td style="width: 45%;">
#Html.TextBoxFor(formfield => formfield.FormFieldName)
#Html.ValidationMessageFor(formfield => formfield.FormFieldName)
</td>
<td style="width: 25%;">
#Html.DropDownListFor(formfield => formfield.SelectedFormFieldType,
new SelectList(Model.FormFieldTypes, "Value", "Text",
Model.SelectedFormFieldType),
new { disabled = "disabled" })
#Html.HiddenFor(formfield => formfield.SelectedFormFieldType)
#Html.ValidationMessageFor(formfield => formfield.SelectedFormFieldType)
</td>
</tr>
</table>
}
</div>
/// form models
public class FormViewModel
{
//Properties
public Form Form { get; set; }
public List<FormFieldViewModel> FormFields { get; set; }
//Constructor
public FormViewModel()
{
Form = new Form();
FormFields = new List<FormFieldViewModel>();
}
}
public class FormFieldViewModel
{
public string FormFieldName { get; set; }
public string SelectedFormFieldType { get; set; }
}
controller methods
[HttpPost]
public ActionResult Create(FormViewModel viewModel)
{
return View();
}
All the field information related to main view gets available but FormFieldViewModel list gives zero count
Any help or suggestion to fix this

My list will be empty when POST the form

I have some problem with the MVC, I'll try to describe. I have 2 class in my model.
public class ApplicationPermissionVM
{
public ApplicationPermission Permission { get; set; }
public bool IsSelected { get; set; }
}
public class RoleAndPermissonsModel
{
//Constructor skipped
public ApplicationRole ApplicationRole { get; set; }
public IEnumerable<ApplicationPermissionVM> Permissions { get; set; }
}
The second model is the main model, and I initialize the model in controller. The ApplicationRole is null and I have got 19 element in the list. When I POST the form the ApplicationRole member will be created, but the Permissions list will be empty so will lost all selection. If anyone knows what is the problem please write to me.
Controller:
[HttpGet]
public ActionResult NewRole()
{
_model = new RoleAndPermissonsModel();
return View(_model);
}
[HttpPost]
public ActionResult NewRole(RoleAndPermissonsModel newRole)
{
if (ModelState.IsValid)
{
var id = _applicationRoleService.AddNewRole(newRole.ApplicationRole);
_applicationRoleService.AssignPermissionsToRole(newRole.SelectedItems, id);
}
return RedirectToAction("Index");
}
View:
#model EO.Core.WebUI.Models.RoleAndPermissonsModel
#using (Html.BeginForm("NewRole", "PermissionRole", FormMethod.Post, new { id = "frmNewRole" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>ApplicationRole</legend>
<div class="editor-label">
#Html.LabelFor(model => model.ApplicationRole.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ApplicationRole.Name)
#Html.ValidationMessageFor(model => model.ApplicationRole.Name)
</div>
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.IsSelected)
</th>
<th></th>
</tr>
#foreach (var item in Model.Permissions)
{
<tr>
<td>
#Html.EditorFor(modelItem => item.IsSelected)
</td>
<td>
#Html.DisplayFor(modelItem => item.Permission.Name);
</td>
</tr>
}
</table>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
you need manually to loop through the list and output it like
<input type="text"
id="Permissions[0].IsSelected"
name="Permissions[0].IsSelected" value="" />
so, change your code to:
#for(int i = 0; i < Model.Permissions.Count; i++)
{
<tr>
<td><input type="checkbox"
id="Permissions[#(i)].IsSelected"
name="Permissions[#(i)].IsSelected" /></td>
<td><input type="text"
id="Permissions[#(i)].Permission.Name"
name="Permissions[#(i)].Permission.Name" /></td>
</tr>
}
because you have an object inside your type Permissions remember to initialiate it or you will get a null reference.
public class RoleAndPermissonsModel
{
public RoleAndPermissonsModel() {
this.Permissions = new List<ApplicationPermissionVM>();
}
public ApplicationRole ApplicationRole { get; set; }
public IEnumerable<ApplicationPermissionVM> Permissions { get; set; }
}
or you can easily create a ViewModel instead and use that to interlink your Model to your View.
Note: I do wonder, if your list is always null (as you are passing an empty/null list) why are you looping through Model.Permissions ?
In order to do the "EDIT" view, the loop code should be:
#for(int i = 0; i < Model.Permissions.Count; i++)
{
<tr>
<td><input type="checkbox"
#(Permissions[i].IsSelected ? "checked='checked'" : "")
id="Permissions[#(i)].IsSelected"
name="Permissions[#(i)].IsSelected" /></td>
<td><input type="text"
id="Permissions[#(i)].Permission.Name"
name="Permissions[#(i)].Permission.Name"
value="#(Permissions[i].Permission.Name)" /></td>
</tr>
}
all you need to add is checked to the checkbox if it's selected and fill the permission name to the other input.

Postback checkboxes from table rows on MVC Razor Strongly Typed View

I have strongly typed view showing data from
ViewModel
public class GoldSetnUsers
{
bool Public { get; set; }
public List<GSUsers> gsUsers { get; set; }
public GoldSetnUsers()
{
UsersContext _dbm = new UsersContext();
this.gsUsers = _dbm.UserProfiles.Select(n => new GSUsers { UserName = n.UserName, isEditor = false, isReviewer = false }).ToList();
}
public class GSUsers
{
public string UserName { get; set; }
public bool isEditor { get; set; }
public bool isReviewer { get; set; }
}
}
Controller Httpget method display this view
Problem is, post-back model returns all rows check boxes as false. The check-box outside table, Public, returns correct post-back value though.
Controller Postback code
[HttpPost]
public ActionResult Create(GoldSetnUsers newGS)
{
if (ModelState.IsValid)
{ // newGS gets me value
}
}
View
#model mvc2db.Models.GoldSetnUsers
#using BootstrapSupport;
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
#Html.BeginControlGroupFor(model=>model.Public)
#Html.LabelFor(model => model.Public,new {#class="control-label"})
<div class="controls">
#Html.EditorFor(model => model.Public,new {#class="input-xlarge"})
#Html.ValidationMessageFor(model => model.Public,null,new{#class="help-inline"})
</div>
<div class="controls">
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Reviewer</th>
<th>Editor</th>
</thead>
<tbody>
#foreach (var item in Model.gsUsers) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.UserName)
</td>
<td>
#Html.EditorFor(modelItem => item.isEditor)
</td>
<td>
#Html.EditorFor(modelItem => item.isReviewer)
</td>
</tr>
}
</tbody>
</table></div>
#Html.EndControlGroup()
<div class="form-actions">
<button type="submit" class="btn btn-primary">Save changes</button>
<button class="btn">Cancel</button>
</div>
</fieldset>
}
I guess since you are generating the checkboxes using a foreach loop all the checkboxes will have the same id. Hence there will be an ambiguity so as to which is checked and which is not.
You can try giving the username as the id of the checkbox.