this is my ajax call:
$('#SaveItemButton').click(function () {
var tableData = { 'ItemViewModel': table.$('input, select').serialize() }; // here the data gets returned
//Add Data Function
function Add() {
$.ajax({
url: "/Item/Add",
data: tableData,
type: "POST",
contentType: "application/json;charset=utf-8",
dataType: "json",
success: function (result) {
alert("success: " + result);
},
error: function (errormessage) {
alert("error: " + errormessage);
}
});
}
} );
And this is my controller action:
public JsonResult Add(List<ItemViewModel> ItemViewModel)
{
var x = ItemViewModel;
return Json(1, JsonRequestBehavior.AllowGet);
}
actual data returned by tableData:
"ItemType=Type1&Unit=select&Quantity=12&Price=1000&Total=&ItemType=Type2&Unit=//select&Quantity=11&Price=2000&Total="
my controller action is receiving ItemViewModel = null. Can anyone tell me what I need to do with the data received so I can successful postback to the server and bind to the model:
public class ItemViewModel
{
public int Id { get; set; }
public string ItemType { get; set; }
public int Quantity { get; set; }
public decimal Price { get; set; }
public ICollection<ProductViewModel> Products { get; set; }
public ICollection<ServiceViewModel> Services { get; set; }
public ICollection<CustomerViewModel> Customers { get; set; }
public InvoiceViewModel Invoice { get; set; }
public string ApplicationUserID { get; set; }
public int ProductId { get; set; }
public int ServiceId { get; set; }
public int InvoiceId { get; set; }
public int CustomerId { get; set; }
public string InvoiceDate { get; set; }
public string TransferDate { get; set; }
public string TransferPlace { get; set; }
public string InvoiceDescription { get; set; }
}
This is my view:
@using (Html.BeginForm("Add", "Item", FormMethod.Post, new { @class = "form-horizontal", id = "ItemForm", role = "form" }))
{
<body>
<h2>Invoice</h2>
<table id="ItemTable" class="table table-hover table-secondary" style="width:100%">
<thead>
<tr>
<th></th>
<th>ItemType</th>
<th>Unit</th>
<th>Quantity</th>
<th>Price</th>
<th>Total</th>
<th></th>
</tr>
</thead>
</table>
</body>
}
And this is the jquery DataTable, javascript:
$(document).ready(function () {
var table = $('#ItemTable').DataTable({
"dom": '<"toolbar">frtip',
"paging": true,
"pagingType": "full_numbers",
"searching": false,
responsive: {
details: {
type: 'column'
}
},
columnDefs: [{
className: 'control',
orderable: false,
targets: 0
}],
order: [1, 'asc']
});
$("div.toolbar").html(
'<button id="addRow" type="button" class="btn btn-outline-info fa fa-plus"> Add</button> <div class="divider"/>' +
'<button id="SaveItemButton" type="submit" class="btn btn-outline-secondary fa fa-save"> Save</button> <div class="divider"/>' +
'<button id="PreviewButton" type="button" class="btn btn-outline-info fa fa-eye"> Preview</button> <div class="divider"/>' +
'<button id="PrintButton" type="button" class="btn btn-info fa fa-print"> Print</button> <div class="divider"/>' +
'<button id="SendButton" type="button" class="btn btn-lump-sum fa fa-envelope"> Send</button> <div class="divider"/>' +
'<button id="DeleteButton" type="button" class="btn btn-secondary fa fa-trash"> Delete </button> <div class="divider"/>'
);
var counter = 1;
$('#addRow').on('click', function () {
table.row.add([
'',
'<input name="ItemType" class="form-control" type="text">',
'<select name="Unit" class="form-control defaultpicker">' +
'<option value="select">dan</option>' +
'<option value="select">Komad</option>' +
'<option value="select">Sat</option>' +
'<option value="select">m</option>' +
'<option value="select">m2</option>' +
'<option value="select">m3</option>' +
'<option value="select">kg</option>' +
'<option value="select">lit</option>' +
'<option value="select">pak</option>' +
'<option value="select">reč</option>' +
'</select > ',
'<input name="Quantity" class="form-control" type="number">',
'<input name="Price" class="form-control" type="text">',
'<input name="Total" class="form-control" type="text" readonly>',
'<button type="button" Id="DeleteButton" class="fa fa-times select-row btn btn-secondary btn-sm" data-id=""></button>',
]).draw(false);
counter++;
$('#ItemTable').dataTable().fnPageChange('last');
});
$('#ItemTable').on("click", "#DeleteButton", function () {
var table = $('#ItemTable').DataTable();
var row;
console.log($(this).closest('table'));
if ($(this).closest('table').hasClass("collapsed")) {
var child = $(this).parents("tr.child");
row = $(child).prevAll(".parent");
} else {
row = $(this).parents('tr');
}
table.row(row).remove().draw();
});
// Automatically add a first row of data
$('#addRow').click();
$('#SaveItemButton').click(function () {
debugger;
//Add Data Function
function Add() {
$.ajax({
url: "/Item/Add",
data: table.$('input, select').serialize(),
type: "POST",
dataType: "json",
success: function (result) {
alert("success: " + result);
},
error: function (errormessage) {
alert("error: " + errormessage);
}
});
}
} );
});
You cannot use combine
.serialize()inside a javascript object, and when using.serialize(), you need to use the defaultcontentType('application/x-www-form-urlencoded; charset=UTF-8') in any case.One option would be to include the collection indexer in the name attribute, so that the
nameattributes of you form controls arename="[#].ItemType"where#is a zero based, consecutive indexer, in which case the ajax call can behowever since you also appear to want to delete items, that also means you need to add an input for the collection indexer (e.g.
<input name="Index" value="#">) in each row.Alternatively, you need to generate and array of objects based on the values of each form control in each
<tr>, stringify it, and send it usingcontentType: 'application/json'To build the array
And then to post it
As a side note, you are creating a
<select>withname="Unit"but there does not appear to be a property in your model with that name. In addition, you have given each<option>the samevalue="select"