This question already has answers here:
Post an HTML Table to ADO.NET DataTable
(2 answers)
Closed 4 years ago.
I am trying to return table values of my view back to the controller to save on db but I keep getting null. I can post the values without problem and bind them to the view.
I cannot understand why, I am using a server side view model.
Is there any way to perform this?
View:
#model IEnumerable<MultiEdit.Models.TableViewModel>
#using (Ajax.BeginForm("Save", "UUTs", new AjaxOptions
{
HttpMethod = "Post",
}, new { id = "tableForm" }))
{
#Html.AntiForgeryToken()
<div class="row" style="padding-top:10px;">
<div class="col-lg-12">
<table class="table table-bordered table-striped ">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.IsChassis)
</th>
<th>
#Html.DisplayNameFor(model => model.Justification)
</th>
</tr>
</thead>
<tbody id="tblMultiEdit">
#foreach(var item in Model)
{
<tr>
<td>
#Html.CheckBoxFor(modelItem => item.CheckIsChassis)
</td>
<td>
#Html.EditorFor(modelItem => item.Justification)
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
}
Controller:
public void Save(IEnumerable<TableViewModel> vm)
{
DoSomething();
}
You need to iterate through your collection with a for loop and index qualifier. Something like the below. The syntax is not exact but you should be able to see what I mean.
#for(var index = 0; index <= Model.Count - 1; index++)
{
<tr>
<td>
#Html.CheckBoxFor(modelItem => Model[index].CheckIsChassis)
</td>
<td>
#Html.EditorFor(modelItem => Model[index].Justification)
</td>
</tr>
}
This is required so the index can be used to create the unique id's of the Enumerable items and aids model binding
Hope that helps
I resolved it by using IList insead of IEnumerable.
View:
#model IList<MultiEdit.Models.TableViewModel>
#Html.CheckBoxFor(modelItem => modelItem[index].CheckIsChassis, new { #class = "form-control" })
Controller:
public void Save(IList<TableViewModel> vm)
{
var x = vm;
}
Related
I am having an issue with the values selected in multiple dropdownlistfor(s) being available in the controller when the form is submitted. The model is always blank. I know there are issues with mvc having dropdowns in loops but I thought I have solved for this. Let me know what you think.
View
#model DataDictionaryConversion.Models.FinalResults
#{ using (Html.BeginForm("SaveMapping", "Home", FormMethod.Post, null))
{
#Html.AntiForgeryToken()
<table class="table table-striped">
<thead>
<tr>
<th>Converted to Name</th>
<th>Your Project Name</th>
<th><input type="button"
onclick="checkAll()"/></th>
</tr>
</thead>
<tbody>
#{for (int x = 0; x < Model.DDObjects.Count(); x++)
{
var isSelection = false;
<tr>
<td class="filterable-cell">#Model.DDObjects[x].ObjectName</td>
<td class="filterable-cell">
#Html.DropDownList(Model.DDObjects[x].ObjectName, new
SelectList(Model.ProjectObjects, "ObjectName", "ObjectName"),
htmlAttributes: new { #id = "ddlObject", #class = "js-example-basic-single" })</td>
</td>
<td>
<input type="checkbox" id="NoValue-
#Model.DDObjects[x].ObjectName" name="NoValue-
#Model.DDObjects[x].ObjectName" onclick="byPassObject(this)" /> Object
Not
Used
</td>
</tr>
}
}
</tbody>
<tfoot>
<tr>
<td style="text-align:right; height:20px"><input
type="submit" class="btn btn-warning" value="Generate Conversion Mapping"
/></td>
</tr>
</tfoot>
</table>
}
}
Controller
[HttpPost]
public ActionResult SaveMapping([FromServices]ApplicationDbContext context, FinalResults model)
{
return View("Mapping");
}
Model
public class FinalResults
{
public IList<FinalObjectModel> ProjectObjects { get; set; }
public IList<Conversion_CSD_ObjectNameLearningModel> DDObjects {
get; set; }
FinalResults model is null
You're using Html.DropDownList. The first param there is a string, which should correspond with the name you're binding to. However, you're passing the value of Model.DDObjects[x].ObjectName, not literally something like "DDOjbects[0].ObjectName".
Instead, you should be using Html.DropDownListFor like so:
#Html.DropDownListFor(m => m.DDObjects[x].ObjectName, ...)
Then, the select list will be bound correctly.
I have the following Razor lines for now:
<table border=1 cellpadding=3 cellspacing=1 rules="rows" frame="box">
<tr>
<th>Türkçe Söz Dizisi</th>
<th>English Word Sequence</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Tr)
</td>
<td>
#Html.DisplayFor(modelItem => item.En)
</td>
<td>
#Html.ActionLink((String)#ViewBag.Edit, "Edit", new { id=item.ID }) |
#Html.ActionLink((String)#ViewBag.Delete, "Delete", new { id=item.ID })
</td>
</tr>
}
</table>
However, I will add some columns automatically from the program to database table. I need a way to print this th's and td's accordingly. In short, I need a way to go through Model's dynamic columns. How can I achieve this?
EDIT: My Model type here is "Proposal". However, I want to reach dynamic attribute of Proposal.Type.Word(Tr, En, or any other added Language Enum). How can I?
#foreach (var item in Model) {
Type objectType = Type.GetType(typeof(RexamOneriSistemi.Models.Word).AssemblyQualifiedName);
System.Reflection.PropertyInfo[] fields = objectType.GetProperties();
<tr>
<td>#Html.DisplayFor(modelItem => item.ID)</td>
<td>#Html.DisplayFor(modelItem => item.Owner.Name)</td>
#foreach (System.Reflection.PropertyInfo f in fields) {
if (f.Name.ToString() == #HttpContext.Current.Session["Language"].ToString())
{
<td>
// What to do here exactly to get item.Type.Word.[dynamic attribute]?
</td>
}
</tr>
}
I can get Razor String
string s = "#Html.Displayfor(modelItem => item.Type.Word." + System.Web.HttpContext.Current.Session["Language"] + ")"
Resulting: #Html.Displayfor(modelItem => item.Type.Word.Tr)
Can I insert a string to be rendered as Razor Syntax? If yes, how?
I have tried this code and it works
<table border=1 cellpadding=3 cellspacing=1 rules="rows" frame="box">
<tr>
#{
Type objectType = Type.GetType(typeof(yourProjectNamespace.Models.Language).AssemblyQualifiedName);
System.Reflection.PropertyInfo[] fields = objectType.GetProperties();
foreach (System.Reflection.PropertyInfo f in fields)
{
<th> #f.Name.ToString() </th>
}
}
</tr>
#foreach (yourModelType item in Model) {
<tr>
foreach (System.Reflection.PropertyInfo f in fields)
{
<td>#Html.Display(f.Name.ToString())</td>
}
<td>
#Html.ActionLink((String)#ViewBag.Edit, "Edit", new { id=item.ID }) |
#Html.ActionLink((String)#ViewBag.Delete, "Delete", new { id=item.ID })
</td>
</tr>
}
</table>
To get Assemply Qualified Name of your class , see this link here
Came across this question, wrote this maybe it will help someone else. This code will dynamically load your model into a table.
#model System.Collections.Generic.List<App.Client.Models.MyModel>
<table>
<thead>
<tr>
#foreach (var property in Model.GetType().GetGenericArguments()[0].GetProperties())
{
<th>#property.Name</th>
}
</tr>
</thead>
<tbody>
#foreach (var modelItem in Model)
{
<tr>
#foreach (var property in modelItem.GetType().GetProperties())
{
<td>#property.GetValue(modelItem)</td>
}
</tr>
}
</tbody>
</table>
I have had look at a few post already here but I am none the wiser. I tried my first example of Ajax but to no avail. The Partial View is loaded into a separate page as opposed to changing the dom element in the current page.
The pupose is by clicking on the Refresh link in updates the "Last Activity Date" value of the current row only.
Please if there is an easy well of doing this can you also let me know?
View:
#model IEnumerable<RegistrationManager.User>
#{
ViewBag.Title = "Users";
}
#section scripts {
#Content.Script(Url, "jquery-unobtrusive-ajax.min.js")
}
<h2>Users</h2>
<table>
<tr>
<th>Email Address</th>
<th>Given Names</th>
<th>Surname</th>
<th>Last Activity Date</th>
<th>Refresh</th>
</tr>
#foreach (var item in Model)
{
string selectedRow = "";
if (ViewBag.UserId != null && item.UserId == ViewBag.UserId)
{
selectedRow = "selectedrow";
}
<tr class="#selectedRow" valign="top">
<td>
#item.UserName
</td>
<td>
#item.Profile.GivenNames
</td>
<td>
#item.Profile.Surname
</td>
<td>
<div id="#String.Format("LastActivityDate{0}", item.UserId)">#Html.Partial("_DateOnlyPartialView", item.LastActivityDate)</div>
</td>
<td>
#Ajax.ActionLink("Refresh", "Refresh",
new { UserId = item.UserId },
new AjaxOptions {
UpdateTargetId = "LastActivityDate" + item.UserId,
InsertionMode = InsertionMode.Replace,
HttpMethod = "GET"
})
</td>
</tr>
}
</table>
Conrtoller:
public PartialViewResult Refresh(Guid? UserId)
{
User user = _db.Users.Find(UserId);
user.RefreshLastActivityDate();
return PartialView("_DateOnlyPartialView", user.LastActivityDate);
}
Have you included/referenced all the necessary javascript files?
If you have UnobtrusiveJavaScriptEnabled then you'll need:
jQuery
jquery.unobtrusive-ajax.js
if you also use client side validation, you'll need;
jquery.validate.js
jquery.validate.unobtrusive.js
These files can all be found when you create a new MVC3 project.
I am passing a viewmodel into a view containing a foreach loop. This viewmodel contains two lists. These lists are filled using Linq.
With the following code, I get the following error: The model item passed into the dictionary is of type '_320.Models.MyViewModel', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[_320.Models.MyViewModel]'.
I want to reach properties contained in the two lists in the ViewModel in my view's foreach loop.
UPDATE
I have been able to display the view by modifying the end of my controller code to:
List<MyViewModel> MyList = new List<MyViewModel>();
MyList.Add(_myViewModel);
return View(MyList);
However, it is an empty view with nothing but headers. When I attempt to change my fields in my view from something like #Html.DisplayFor(modelItem => item.rx.Rx_ID) to #Html.DisplayFor (modelItem => item.Rxes.rx.Rx_ID) it is labeled red. Is it impossible to access a property located that far down in a list?
END OF UPDATE
Model
public class MyViewModel
{
public Patient patient { get; set; }
public Rx rx { get; set; }
public Fill fill { get; set; }
public List<Rx> Rxes { get; set; }
public List<Fill> Fills { get; set; }
Controller
public ActionResult AllFilled()
{
MyViewModel _myViewModel = new MyViewModel();
List<Fill> FillList = db.Fills.Where(p => p.Status == "Filled").ToList();
List<Rx> RxList = new List<Rx>();
Rx myRx = new Rx();
foreach (var item in FillList)
{
myRx = db.Rxes.Single(p => p.Rx_ID == item.Rx_ID);
RxList.Add(myRx);
}
_myViewModel.Fills = FillList;
_myViewModel.Rxes = RxList;
return View(_myViewModel);
}
}
View
#model IEnumerable<_320.Models.MyViewModel>
#{
ViewBag.Title = "AllFilled";
}
<h2>AllFilled</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
NDC
</th>
<th>
Rx_ID
</th>
<th>
Fill_ID
</th>
<th>
Status
</th>
<th>
Filled Date
</th>
<th>
Filled By
</th>
<th></th>
</tr>
{
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.rx.NDC)
</td>
<td>
#Html.DisplayFor(modelItem => item.rx.Rx_ID)
</td>
<td>
#Html.DisplayFor(modelItem =>item.fill.Fill_ID)
</td>
<td>
#Html.DisplayFor(modelItem => item.fill.Status)
</td>
<td>
#Html.DisplayFor(modelItem => item.fill.Filled_Date)
</td>
<td>
#Html.DisplayFor(modelItem => item.fill.Filled_By)
</td>
<td>
#Html.ActionLink("Details", "Details", new { id=item.rx.Rx_ID })
</td>
</tr>
}
</table>
Your view is expecting a model of type IEnumerable<_320.Models.MyViewModel> due to the first line in the view.
#model IEnumerable<_320.Models.MyViewModel>
If you want to use a model object of type MyViewModel (as coded in your controller), change this line to
#model _320.Models.MyViewModel
I am trying to display a list in a View, how to fix this error?
The model item passed into the dictionary is of type
'System.Data.Objects.ObjectQuery1[System.Linq.IGrouping2[System.Int32,mvc3Post.Models.Contact]]',
but this dictionary requires a model item of type
'System.Collections.Generic.IEnumerable`1[mvc3Post.Models.Contact]'.
controller:
public ActionResult Index()
{
AdventureWorksEntities db = new AdventureWorksEntities();
var result = from soh in db.SalesOrderHeaders
join co in db.Contacts
on soh.ContactID equals co.ContactID
orderby co.FirstName
group co by co.ContactID into g
select g;
return View(result.AsEnumerable());
}
view:
#model IEnumerable<mvc3Post.Models.Contact>
#{
ViewBag.Title = "Index";
}
<h2>
Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
NameStyle
</th>
<th>
Title
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.NameStyle)
</td>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.ContactID }) |
#Html.ActionLink("Details", "Details", new { id = item.ContactID }) |
#Html.ActionLink("Delete", "Delete", new { id = item.ContactID })
</td>
</tr>
}
</table>
Updated now that I see the controller method:
You might need to transform your LINQ result set into a list or something (e.g., contacts.ToList()) more concrete.
Another alternative might be to create a root object for your page's list object to live on. I find it a little easier to follow and maintain if each View has a corresponding Model class that represents it's entire state.
I think either route will resolve your issue though. I think that the latter is probably the better way if I had to recommend one vs the other.