1

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>&nbsp; @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?

0

1 Answer 1

1

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.csfile 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>&nbsp; @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" })
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for your reply. for this requirement i need to have two buttons. one is to add rows to table. and other one to save the table. My issue is with the first one. for the Save button i am getting the values in [Httppost] method. but for the other add button which is adding rows to the Table. what i need is get the existing model which have shiftcode pickers selected. and add a new row with default shiftcodes. and pass it back to the view. this is where i need to get the model. (I tried to add a image but it needs 10 credits :(
you can add a property to your model (say, public bool HasToAddRow{get; set;}) whitch you put as a Hidden on the view, and within the event click of your buttons change the value of that hidden. Then in the action (EmployeePost) you can have a if handling what you want: (`if(model.HasToAddRow){ //add row }else{ //save })
@ISP I modified my post following your comment. You can see I add a property to the model and I modified both the view and the controller to manage this new property. Now you can add a row wen clicking to the Add Rowbutton.
@ISP I also edited the Partial view to get my demo to work correctly.
Thanks.. adding that field do the trick..Thanks for you help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.