How to use EditorFor to save changes to the Model? - c#

I have a view like this:
#model IEnumerable<Namespace.MyClass>
#using Newtonsoft.Json;
<form asp-action="Update">
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Product)
</th>
<th>
#Html.DisplayNameFor(model => model.IsAvailable)
</th>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Product)
</td>
<td>
#Html.EditorFor(modelItem => item.IsAvailable)
</td>
</tr>
}
</tbody>
</table>
<div>
<a href=#Url.Action("SaveChanges", "Product", new {productList = JsonConvert.SerializeObject(Model) })> Save changes</a>
</div>
</form>
where SaveChanges looks like this:
[HttpGet] // Perhaps it should be HttpPost here, but if I change it to that nothing happens when I run the program after clicking the "Save changes" link
public ActionResult SaveChanges(string productList)
{
List<MyClass> products = JsonConvert.DeserializeObject<List<MyClass>>(productList);
// Here I continue with SqlCommand to later make an UPDATE to a database changing the value of IsAvailable which is the only adjustable value in my view
}
My issue is that when I run the program and I change IsAvailable (which is a bool) from false to true in my view and press "Save Changes", the model does not change, i.e. productList still has the value False for IsAvailable for that particular product.
Does anybody have an idea as to why? From my understanding if I have a and

Model information is not updated when you send the model to the action with the link. And the same initial amount is sent.
The changes you make to the model fields are only in the html controls and have nothing to do with the model. The model is updated when you post the form information.
I submitted the form to jQuery in the following code
in view
#model List<Namespace.MyClass>
#using (Html.BeginForm("SaveChanges", "Product", FormMethod.Post))
{
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.FirstOrDefault().Product)
</th>
<th>
#Html.DisplayNameFor(model => model.FirstOrDefault().IsAvailable)
</th>
</thead>
<tbody>
#for (int i = 0; i < Model.Count(); i++)
{
<tr>
<td>
#Html.DisplayFor(modelItem => Model[i].Product)
</td>
<td>
#Html.EditorFor(modelItem => Model[i].IsAvailable)
</td>
</tr>
}
</tbody>
</table>
<div>
#Html.ActionLink("Save changes", "", null, new { #id = "submit"})
</div>
}
#section scripts{
<script type="text/javascript">
$("#submit").click(function () {
document.forms[0].submit();
return false;
});
</script>
}
action in controller
[HttpPost] // Perhaps it should be HttpPost here, but if I change it to that nothing happens when I run the program after clicking the "Save changes" link
public ActionResult SaveChanges(IEnumerable<MyClass> products)
{
// Here I continue with SqlCommand to later make an UPDATE to a database changing the value of IsAvailable which is the only adjustable value in my view
}

Related

How to pass model as a parameter to [HttpPost] ActionMethod in ASP.NET MVC?

I have a usual grid which has edit and save button. When I click the Edit link from the grid it goes to Edit action method, where I can read the Id as a parameter. I am thinking since I can pass the Id then why not the whole model as a parameter to the Edit action? However, I am always getting null. I looked at some examples they all shows passing the id rather than the model object. I wonder why model cannot be passed? Even though when I debug the code I always see item row is binding with the parameter Student from item.
View for Grid with Edit link:
#model IEnumerable<MVC_BasicTutorials.Models.Student>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.StudentName)
</th>
<th>
#Html.DisplayNameFor(model => model.Age)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.StudentName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Age)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.StudentId, std=item }) |
</td>
</tr>
}
</table>
Controller action method:
// Get
public ActionResult Edit(int Id, Student std)
{
var checkSet=std; // coming null
var checkId=Id; //i am seeing the id value
return RedirectToAction("Index");
}
Try the following:
public ActionResult Index()
{
var model = /* prepare view data model */;
return View(model);
}
[HttpPost]
// The second parameter `Id` is removed because of the `Student` already contains it.
public ActionResult Edit(Student std)
{
System.Diagnostics.Debug.WriteLine($"Id= {std.StudentId}, Student Name= {std.StudentName} ");
return RedirectToAction("Index");
}
In the Index.cshtml you can use the Html.BeginForm helper method to specify that the target of the form is the 'Edit' action method.
#model IEnumerable<MVC_BasicTutorials.Models.Student>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.StudentName)
</th>
<th>
#Html.DisplayNameFor(model => model.Age)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
using (Html.BeginForm("Edit", "Home"))
{
#* Prepare a hidden data context to the able the MVC data binding work correctly *#
#Html.Hidden("StudentId", item.StudentId)
#Html.Hidden("StudentName", item.StudentName)
#Html.Hidden("Age", item.Age)
<tr>
<td>
#Html.DisplayFor(modelItem => item.StudentName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Age)
</td>
<td>
#*#Html.ActionLink("Edit", "Edit", new { id = item.StudentId, std = item }) *#
<input type="submit" value="Edit" />
</td>
</tr>
}
}
</table>

Index page with datatable took about 6-7 seconds before showing search box

I have a simple index page. When I load the page with only 500 records, the search box shows up straight away. But with 12k records, it take some time. Is there a way I can show a LOADING message, and after the search box is loaded, the LOADING message disappear.
This is the Index.cshtml
#model IEnumerable<BSMV2.Models.StoAppnOrgView>
<h2>LIST OF STONES</h2>
<table id="applicationTable" class="table table-striped table-bordered">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Stone)
</th>
<th>
#Html.DisplayNameFor(model => model.Applicant)
</th>
<th>
#Html.DisplayNameFor(model => model.Org)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Stone)
</td>
<td>
#Html.DisplayFor(modelItem => item.Applicant)
</td>
<td>
{#Html.DisplayFor(modelItem => item.Org)
</td>
<td>
#Html.ActionLink("Details", "Details", new { Id = item.Id })
</td>
</tr>
}
</tbody>
#section Scripts{
<script type="text/javascript">
$(document).ready(function () {
$('#applicationTable').DataTable();
});
</script>}
Here is the controller
public async Task<ActionResult> Index()
{
return View(await db.StoAppnOrgViewObj.ToListAsync());
}
Here is the Search box.
You should not be loading all 12k data on the UI. Instead use server side paging which will give the user similar experience but performance wise will be faster. The system will not be slower. The data will grow over the time and you will have to shift to server side logic anyways in the future.
You can also use the progress indicator that comes with datatable. All you have to do the followings:
$('#example').DataTable( {
"processing": true,
"serverSide": true,
"ajax": "../server_side/scripts/test.php"
} );
For the server side logic, you can follow the codes from here.

I can't see the input value in the input in html controller

The model of my html page is in the form of a list. I want to enter the exam grade here, but when I entered the exam grade, my data does not go to my actionResult type function. In fact, when I write an integer value to the input, it does not save its value. The database also lists the values I have written manually, but still does not bring the data to the function.
my html code:
#model IEnumerable<OnlineBasvuru.Entity.ViewModel.ExamViewModal>
#{
Layout = null;
}
<div>
#using (Html.BeginForm("Save", "Exam", FormMethod.Post))
{
<table class="table">
<thead>
<tr>
<th>
StudentId
</th>
<th>
Note
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.ToList())
{
<tr>
<td>
#Html.Label(item.StudentId.Value.ToString())
</td>
<td>
#Html.EditorFor(modelItem => item.Note)
</td>
</tr>
}
</tbody>
</table>
<button type="submit">Save</button>
}
</div>
my controller code:
[HttpPost]
public ActionResult Save(ICollection<ExamViewModal> nwModal) // Normally nwModal should be listed as a list of the model and the data should be in
{
foreach (ExamViewModal modal in nwModal)
{
EXAM exam = examService.Get(modal.Id);
exam.NOTE = modal.Note;
examService.Save(exam );
}
return RedirectToAction("ExamList", "Exam");
}
Please show me a way I do not know how to do. Thank you.
Try using a for loop instead of a foreach. This will then set the name property using indexes rather than spitting out the same name for each item in the loop.
For example:
for (int i = 0; i < Model.Count(); i++) {
Html.EditorFor(m => Model[i].Note)
}

How do I get my view to recognize my object

I already have a view created that I want to use to display results being pulled from the db and passed to the view in my action. When I created the view I didn't tell it what objects I wanted to pass in so I'm trying to add them manually but the view doesn't seem to recognize them.
Here is my Results view and the top line is what I'm trying to add, but VS doesn't recognize it. So spaces is red (unrecognized) and item.Name and item.description are red
#spaces IQueryable<GiftExchange.Core.Models.Space.YogaSpace>
#{
ViewBag.Title = "Results";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h3>Search Results</h3>
#using (Html.BeginForm("Results", "Home", FormMethod.Get))
{
<p>
#Html.TextBox("Location") <input value='Search' type="submit" />
</p>
}
<table border="1">
<tr>
<th>
#Html.DisplayNameFor(spaces => spaces.Name)
</th>
<th>
#Html.DisplayNameFor(spaces => spaces.Description)
</th>
</tr>
#foreach (var item in spaces)
{
<tr>
<th>
#Html.DisplayFor(modelItem => item.Name)
</th>
<th>
#Html.DisplayFor(modelItem => item.Description)
</th>
</tr>
}
</table>
Here is my action
[AllowAnonymous]
public ActionResult Results(string searchTerm)
{
IQueryable<YogaSpace> spaces;
using (var repo = new YogaSpaceRepository())
{
spaces = repo.All;
}
return View(spaces);
}
In the first line of your view, switch #spaces for #model.
And then where you want to use it, instead of spaces, use Model.
For more details, google for "strongly typed views".

MVC 4 How to pass an object to partial view when list item is clicked?

This is a controller
public class ProductController : Controller
{
//
// GET: /Product/
public ActionResult Index(int id = 0)
{
return View(DALCategory.GetCategoryList());
}
public PartialViewResult productPartial(int id)
{
if (id > 0)
{
return PartialView("_productPartial", DALProduct.GetProductListByCateDetail(id));
}
else
{
return PartialView("_productPartial", DALProduct.GetProductList());
}
}
This is code in index view
#model IEnumerable<Model.Category>
<h2>Products</h2>
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.name)
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.ActionLink(#item.name, "productPartial", new { id = item.id })
</td>
</tr>
}
</table>
#Html.Partial(productPartial)
And this is code for partial view.
#model IEnumerable<Model.Product>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.SKU)
</th>
<th>
#Html.DisplayNameFor(model => model.product_name)
</th>
<th>
#Html.DisplayNameFor(model => model.price)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.SKU)
</td>
<td>
#Html.DisplayFor(modelItem => item.product_name)
</td>
<td>
#Html.DisplayFor(modelItem => item.price)
</td>
<td>
#* #Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
#Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
#Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })*#
</td>
</tr>
}
</table>
So what I want to do is... when an item is clicked, it renders the partial with an new object. Yes, the partial view is only rendered on the same page.
I have been doing so many things. Although I do not think it is such a hard problem, I am not really sure what I need to do for this...
Since you want to update a part of the page you will need to use ajax to accomplish that. You have two options there:
User #Ajax.ActionLink (How can i load Partial view inside the view)
You can write your own jquery ajax request that invokes your controller method and returns the partial view.
It happened to me as well. I wanted the page to be partial and loaded on the same page but it kept forwarding me to other link. Make sure following points are taken care of:
You have included your jquery-1.6.2.js or whatever version of this file you have.
Also make you have included your jquery file you have created. Make sure the above one is included first.
If you have included these files in some section of your .cshtml section then make sure you render it in your _Layout.cshtml or other layout file you are using. For example you have included your file in head section of your index.cshtml like this
#section head{
}
then you have to render this section in _layout.cshtml with #RenderSection("head", required: false)
what you can also do is Make sure that jQuery is not included twice and that you don't have some javascript errors. Look at your javascript console in the browser as well as the Network tab to ensure that all your scripts are included properly.
Good Luck!!!

Categories