Reputation: 63
this is my table in view.
<table class="customtable" width="100%">
<thead>
<tr>
<td>
<div style="width: 80px">Employee ID</div>
</td>
<td>
<label class="control-label">Employee Name:</label>
</td>
<td>
<div style="width: 100px">Employee Type</div>
</td>@foreach (var workDay in dayList) {
<td>@workDay.Value
<br> @workDay.Key</td>}</tr>
</thead>
<tbody>@for (int i = 0; i
< Model.LineItems.Count; i++) { <tr>
<td>@Html.DisplayFor(m =>@Model.LineItems[i].EmployeeNo)</td>
<td>@Html.DisplayFor(m => @Model.LineItems[i].EmployeeName)</td>
<td>@Html.DisplayFor(m => @Model.LineItems[i].EmployeeType)</td>@for (int j = 0; j
< Model.LineItems[i].EmployeeLineItems.Count; j++) { <td>@Html.EditorFor(m => m.LineItems[i].EmployeeLineItems[j].ShiftCode, MVC.Shared.Views.EditorTemplates.ShiftCodePicker)</td>}</tr>}</tbody>
</table>
I want to pass this to controller via ajax post method
function ajaxAdd() {
var i = 0;
var model;
for (i = 0; i < 10; i++) {
model = {
'EmployeeId': $("#@Html.FieldIdFor(m => m.EmployeeId)").val(),
'SignatureId': $("#@Html.FieldIdFor(m => m.SignatureId)").val(),
'StoreId': $("#@Html.FieldIdFor(m => m.StoreId)").val(),
'ScheduleDate': $("#@Html.FieldIdFor(m => m.ScheduleDate)").val(),
'LineItems[0].EmployeeLineItems[1].ShiftCode': $("#@Html.FieldIdFor(m => m.LineItems[0].EmployeeLineItems[1].ShiftCode)").val()
};
}
$.ajax({
url: "@Url.Action(MVC.WorkSchedule.ActionNames.AddNew, MVC.WorkSchedule.Name)",
type: "post",
data: JSON.stringify(model),
contentType: 'application/json',
success: function () {
window.location.href = "@Url.Action(MVC.WorkSchedule.ActionNames.Create, MVC.WorkSchedule.Name)";
}
});
}
when i pass the values like $("#@Html.FieldIdFor(m => m.LineItems[0].EmployeeLineItems[1].ShiftCode)").val()
i can get that value in controller method. but once i replace them with 'i' it will not work.
Is there any other way i can send this data to controller with ajax post method?
Upvotes: 1
Views: 4972
Reputation: 4375
I don't have the details of your models but given the mark-up and code you provided I pull out this example using Microsoft jQuery Unobtrusive Ajax
(You have to install it if you haven't yet, using Nuget is the easiest way. In the Nuget console enter Install-Package Microsoft.jQuery.Unobtrusive.Ajax
. You can also use the NuGet Packages Manager).
This works as expected sending to the server (via AJAX into the action EmployeesPost
) the new values on shift codes TextBoxes.
After install the Microsoft.jQuery.Unobtrusive.Ajax
you have to add a bundle in your BundleConfig.cs
file under the App_Start
folder, like this:
bundles.Add(new ScriptBundle("~/bundles/jqueryajax").Include(
"~/Scripts/jquery.unobtrusive-ajax.js"));
Here are the models I create trying to reproduce yours :
(I put all these in a EmployeeViewModels.cs
file under Models
folder)
using System.Collections.Generic;
namespace ExemplesApplication.Models
{
public class ShiftCode
{
public string Name { get; set; }
}
public class EmployeeLine
{
public ShiftCode ShiftCode { get; set; }
}
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public List<EmployeeLine> EmployeeLineItems { get; set; }
public Employee()
{
EmployeeLineItems = new List<EmployeeLine>
{
new EmployeeLine {ShiftCode = new ShiftCode {Name = "Morning" }},
new EmployeeLine {ShiftCode = new ShiftCode {Name = "NOON"}},
new EmployeeLine {ShiftCode = new ShiftCode {Name = "Afternoon"}},
new EmployeeLine {ShiftCode = new ShiftCode {Name = "evening"}},
new EmployeeLine {ShiftCode = new ShiftCode {Name = "Night"}}
};
}
}
public class EmployeesViewModel
{
public bool HaveToAddRow { get; set; }
public Dictionary<string, string> WorkDays
{
get
{
return new Dictionary<string, string>
{
{"Monday", "1"},
{"Tuesday", "2"},
{"Wednesday", "3"},
{"Thursday", "4"},
{"Friday", "5"}
};
}
}
public List<Employee> Employees { get; set; }
public EmployeesViewModel()
{
Employees = new List<Employee>
{
new Employee {Id = 1, Name = "Robert", Type = "Engineer"},
new Employee {Id = 2, Name = "Albert", Type = "Driver"},
new Employee {Id = 3, Name = "Fred", Type = "Manager"},
new Employee {Id = 4, Name = "Thomas", Type = "Sales"},
new Employee {Id = 5, Name = "Sahra", Type = "Engineer"}
};
}
}
}
Then the controller looks like this (EmployeeController.cs
) :
using ExemplesApplication.Models;
using System.Web.Mvc;
namespace ExemplesApplication.Controllers
{
public partial class EmployeeController : Controller
{
public virtual ActionResult Index()
{
return View(new EmployeesViewModel());
}
public virtual ActionResult EmployeesPost(EmployeesViewModel model)
{
if (model.HaveToAddRow)
{
//add row
model.Employees.Add(new Employee {Id = 1, Name = "New employee", Type = "Engineer"});
return PartialView(MVC.Employee.Views._TableEmployees, model);
}
else
{
// your logic to save
//here
// render the partial view
return PartialView(MVC.Employee.Views._TableEmployees, model);
}
}
}
}
Then I created one view and one partial view :
View (/Views/Employee/Index.cshtml
)
@model ExemplesApplication.Models.EmployeesViewModel
@{
ViewBag.Title = "Employees";
var ajaxOptions = new AjaxOptions {UpdateTargetId = "employees-table-container", Url = Url.Action(MVC.Employee.EmployeesPost())};
}
<h2>Index</h2>
@using(Ajax.BeginForm(ajaxOptions))
{
@Html.HiddenFor(m=>m.HaveToAddRow)
<div id="employee-container">
<div id="employees-table-container">
@Html.Partial(MVC.Employee.Views._TableEmployees, Model)
</div>
<input id="add-row" type="button" value="Add Row" />
<input id="save-table"type="submit" value="Submit" />
</div>
}
@section scripts
{
@Scripts.Render("~/bundles/jqueryajax")
<script type="text/javascript">
$(document).ready(function () {
var $form = $("form"),
$haveToAddRowHidden = $("#HaveToAddRow");
$("#add-row").on("click", function() {
$haveToAddRowHidden.val(true);
$form.submit();
});
$("#save-table").on("click", function () {
$haveToAddRowHidden.val(false);
});
});
</script>
}
PartialView (/Views/Employee/_TableEmployees.cshtml
)
@model ExemplesApplication.Models.EmployeesViewModel
<table class="customtable" width="100%">
<thead>
<tr>
<td>
<div style="width: 80px">Employee ID</div>
</td>
<td>
<label class="control-label">Employee Name:</label>
</td>
<td>
<div style="width: 100px">Employee Type</div>
</td>
@foreach (var workDay in Model.WorkDays)
{
<td>
@workDay.Value
<br> @workDay.Key
</td>
}
</tr>
</thead>
<tbody>
@for (var i = 0; i < Model.Employees.Count(); i++)
{
<tr>
<td>
@Html.DisplayFor(m => @Model.Employees[i].Id)
@Html.HiddenFor(m => @Model.Employees[i].Id)
</td>
<td>
@Html.DisplayFor(m => @Model.Employees[i].Name)
@Html.HiddenFor(m => @Model.Employees[i].Name)
</td>
<td>
@Html.DisplayFor(m => @Model.Employees[i].Type)
@Html.HiddenFor(m => @Model.Employees[i].Type)
</td>
@for (var j = 0; j < Model.Employees[i].EmployeeLineItems.Count; j++)
{
<td>@Html.EditorFor(m => m.Employees[i].EmployeeLineItems[j].ShiftCode, MVC.Shared.Views.EditorTemplates.ShiftCodePicker)</td>
}
</tr>
}
</tbody>
</table>
Finally I created the EditorTemplate
(Views/Shared/EditorTemplates/ShiftCodePicker.chtml
)
@model ExemplesApplication.Models.ShiftCode
@Html.TextBoxFor(m=> m.Name, new { @class = "editor-for-shiftcode" })
Upvotes: 1