53940

Submitting model with entities in MVC using DataTable fails when using pagination

Question:

I want to submit model with entities, but controller is not receiving entities when switching to another page when using DataTable plugin.

VIEW:

using (Ajax.BeginForm("EditLeads", new { mode = Model.leadMode }, new AjaxOptions { OnBegin = "displayAllDataTable", UpdateTargetId = "leadDisplay", LoadingElementId = "spinner", OnSuccess = "refreshLeadsAfterRemovingAndTabSwitching" }, new { id="dataTableForm"})) { <table id="dataTable"> <thead> <tr> <th style="max-width: 40px;"> Select </th> <th> Date added </th> <th> Contact name </th> <th> Contact number </th> <th> Email </th> <th> Source </th> <th> Status </th> <th> Assigned to user: </th> <th> Back up user: </th> <th> Comments </th> </tr> </thead> <tbody> @for (int i = 0; i < Model.leadsList.Count; i++) { <tr> <td style="width: 40px; vertical-align: middle; text-align: center"> <span class="hideDisplayField">@Model.leadsList[i].leadId</span> @Html.HiddenFor(model => model.organisationId) @Html.HiddenFor(model => Model.leadsList[i].leadId) @Html.CheckBoxFor(model => Model.leadsList[i].selected, new { @class = "selectedLead", data_val = false, data_leadId = Model.leadsList[i].leadId, id = "selected_" + Model.leadsList[i].leadId }) </td> @* <td> @Html.DisplayFor(model => model.leadsList[i].leadId) @Html.HiddenFor(model => Model.leadsList[i].leadId) </td>*@ <td> <span class="hideDisplayField">@Model.leadsList[i].leadDate</span> @Html.DisplayFor(model => Model.leadsList[i].leadDate) </td> @* <td> @Html.HiddenFor(model => Model.leadsList[i].leadId) <span class="hideDisplayField">@Model.leadsList[i].description</span> @Html.EditorFor(model => Model.leadsList[i].description) </td>*@ <td> <span class="hideDisplayField">@Model.leadsList[i].contactName</span> @Html.DisplayFor(model => Model.leadsList[i].contactName) </td> <td> <span class="hideDisplayField">@Model.leadsList[i].contactMobile</span> @Html.EditorFor(model => Model.leadsList[i].contactMobile) </td> <td> <span class="hideDisplayField">@Model.leadsList[i].contactEmail</span> @Html.EditorFor(model => Model.leadsList[i].contactEmail) @Html.HiddenFor(model => Model.leadsList[i].contactId) </td> <td> </td> <td> <span class="hideDisplayField">@Model.leadsList[i].leadStatusName</span> @Html.DropDownListFor(model => Model.leadsList[i].leadStatusId, new SelectList(Model.leadStatusList, "leadStatusId", "name", Model.leadsList[i].leadStatusId), null, new { data_val = false }) </td> <td> <span class="hideDisplayField">@Model.leadsList[i].assignedToUserId</span> @Html.DropDownListFor(model => Model.leadsList[i].assignedToUserId, new SelectList(Model.users, "UserId", "Email", Model.leadsList[i].assignedToUserId), "Select user", new { data_val = false, data_users = Model.leadsList[i].leadId, @class = "usersList" }) </td> <td> <span class="hideDisplayField">@Model.leadsList[i].backupUserId</span> @Html.DropDownListFor(model => Model.leadsList[i].backupUserId, new SelectList(Model.users, "UserId", "Email", Model.leadsList[i].backupUserId), "Select user", new { data_val = false }) </td> <td> </td> </tr> } </tbody> <tfoot> <tr> <th> Select </th> <th> Date added </th> <th> Contact name </th> <th> Contact mobile </th> <th> Email </th> <th> Source </th> <th> Status </th> <th> Assigned to user </th> <th> Back up user </th> <th> Comments </th> </tr> </tfoot> </table> <div id="assignUserToLeads"> <h4> Assign selected to</h4> @Html.DropDownList("userList", new SelectList(Model.users, "UserId", "Email"), "Select user") </div> <input type="submit" value="Save" /> }

My constroller is expecting to receive model with list of leads.

public ActionResult EditLeads(LeadsVM leadVM, string mode, FormCollection form) { // Assign user to lead var user = form["userList"]; var leadsToUpdate = leadVM.leadsList.Where(m => m.selected == true); foreach (var lead in leadsToUpdate) ...

If I select value from dropdown list to display 100 items on page, everything works fine, but once I switch to another page, name binding is falling apart and model is passing null for leadVM.leadsList. I did small hack which I thought might help. Before model is send to controller I am calling displayAllDataTable function.

function displayAllDataTable() { console.log($("#dataTable_length select")); $("#dataTable_length select").val(100); $("#dataTable_length select").trigger("change"); }

Unfortunately the function forces dataTable to display all results on 1st page, but model still passes null for leadsList. I would assume I will have to call some dataTable function to refresh the fields in table and then the form can be correctly submitted, but there must be simpler way.

To summarize I always want to pass all data from table to controller, regardless on which page I am currently in.

DataTable

table = $('#dataTable').DataTable({ 'dom': '<lf<"table_wrapper"t>ip>', "aoColumns": [ { "bSearchable": true }, { "bSearchable": true }, { "bSearchable": true }, { "bSearchable": true }, { "bSearchable": true }, { "bSearchable": true }, { "bSearchable": false }, { "bSearchable": false }, { "bSearchable": false }, { "bSearchable": true } ] });

Answer1:

Found solution!

First I tweaked a value in dataTables js.

"aLengthMenu": [ 10, 25, 50, 100, 1000 ].

I added 1000, but you can add any value you want.

Under form I changed input type from submit to button and called function.

<input type="button" value="Save" onclick="displayAllDataTable()">

I define the function:

function displayAllDataTable() { $("#dataTable_length select").val(1000); $("#dataTable_length select").trigger("change"); $("#dataTableForm").submit(); }

Everything works fine now.

Answer2:

I read through API documentation and came up with another solution that allows databinding by drawing the entire table with page.len. This would not be an ideal solution with a large table with thousands of rows, and would look weird from a UI perspective as the entire table draws before form submits to controller. Also I noted that on the Controller side, that if you are binding to a list from the Datatable, the ordering of the binding / list is not in respect to the Datatable ordering.

<a href="https://datatables.net/reference/api/page.len()" rel="nofollow">page.len</a>

Here is source to add to the end of your page:

<script> $(document).ready(function () { $.fn.dataTable.ext.legacy.ajax = true; $('#YourTable').dataTable(); }); $("#YourTable").submit(function (event) { var table = $('#YourTable').DataTable(); table.page.len(-1).draw(); }); </script>

Answer3:

Based on Adam Bielecki post, I've tweked it a little bit to avoid a 1,000 lenght option as follows... just use -1 instead!

lengthMenu": [[10, 25, 50, **-1**], [10, 25, 50, "All"]] function displayAllDataTable() { $("#example1_length select").val(**-1**); $("#example1_length select").trigger("change"); $("#groupForm").submit(); }

Recommend

  • Submitting model with entities in MVC using DataTable fails when using pagination
  • Assign value to textbox onchange of php while select
  • Jquery datatables Plug-In , display “No data available in table” after Sorting/Filtering Data
  • Express.js 4 routes not matching with router.route
  • Flatten XML structure by element with linq to xml
  • Search GROUP_CONCAT using LIKE
  • NSPredicate predicateWithFormat passing in name of attribute
  • Editing and deleting a newly added table row using Jquery
  • JavaScript reference error can't find variable plus closure blues
  • How to make iContact API call from Google scripts
  • MySQL - Get Distinct Primary Col Table Row Order By Foreign Key Table
  • Cursor inside Trigger not working
  • How to get complex values as columns [duplicate]
  • How to pass a dynamic function name to the click event in Vue Js
  • Use Linq or C# to parse Json
  • jqGrid not rendering JSON data into grid
  • replace character in text generated by html.displayfor(function
  • Mongoose aggregate, can't dynamically add someField: { $not; null }
  • ASP.NET Display Templates - No output
  • Need to add multiple filter in angular ui select
  • Join and filter condition between CRM entities using Odata query
  • PHP associate arrays, multidimension. How do I access them?
  • ASP.NET MVC + Retrieving one to many relationship using jQuery Tab
  • Database field containing HTML display raw text
  • MVC - Binding dynamically added controls to a List in a Model
  • Large Photo Version from contacts in android
  • Is it possible to display more than one item in a cell with a foreach condition?
  • How insert image in HTML Body Email Swift 3?
  • What is the proper way to add a Field to a custom Part in code?
  • Get all RSS feed entries with Rome Library
  • Get selected data
  • Mapping JSON to Java Object return null value
  • update record in database using jdatabase
  • How can the INSERT … ON CONFLICT (id) DO UPDATE… syntax be used with a sequence ID?
  • QLPreviewController hide print button in ios6
  • Uncaught Error: Could not find module `ember-load-initializers`
  • Bitwise OR returns boolean when one of operands is nil
  • sending mail using smtp is too slow
  • costura.fody for a dll that references another dll
  • Binding checkboxes to object values in AngularJs