I have a pure JS grid I was using with an asp.net forms backend (.ashx). It has been working fine for six months. I am trying to convert it to an MVC controller for the backend now, but having no luck:
My material entry controller for the Create function looks like this:
I know the logic inside create isn't right. But the problem is that the 'materials' parameter is empty when the Create method is called. You can see that the form data seems to be being sent correctly in chrome's Netowork tab, by looking at the attached file.
Any ideas what I am doing wrong?
function
MaterialsGrid(ticket_ID, grid_id, is_editable, default_billable) {
var
self =
this
;
self.ticket_ID = ticket_ID;
self.GRID_ID =
'#'
+ grid_id;
self.HANDLER_URL =
"/MaterialEntry"
;
self.IS_EDITABLE = is_editable;
self.DEFAULT_BILLABLE = default_billable;
self.material_source =
new
kendo.data.DataSource({
batch:
true
,
schema: {
model: {
id:
"MaterialEntryID"
,
fields: {
MaterialEntryID: { type:
"string"
},
TicketID: { type:
"string"
},
ItemID: { type:
"number"
, defaultValue: 0 },
ItemName: { type:
"string"
, defaultValue: GridCommon.emptyText },
Description: { type:
"string"
},
Quantity: { type:
"number"
, defaultValue: 0, validation: { required:
true
, min: 0 } },
Rate: { type:
"number"
, defaultValue: 0 },
Total: { type:
"number"
, defaultValue: 0 },
Billable: { type:
"boolean"
, defaultValue: self.DEFAULT_BILLABLE },
},
}
},
transport: {
read: {
url: self.HANDLER_URL +
"/Read"
,
dataType:
"json"
,
type:
"GET"
,
cache:
false
,
},
update: {
url: self.HANDLER_URL +
"/Update"
,
dataType:
"json"
,
type:
"PUT"
,
},
destroy: {
url: self.HANDLER_URL +
"/Destroy"
,
dataType:
"json"
,
type:
"POST"
,
},
create: {
url: self.HANDLER_URL +
"/Create"
,
dataType:
"json"
,
type:
"POST"
,
},
parameterMap:
function
(options, operation) {
if
(operation ===
"read"
) {
return
{ ticketID: self.ticket_ID };
}
if
(operation ===
"read"
) {
return
{ ticketID: self.ticket_ID };
}
else
if
(options.models) {
return
{ materials: kendo.stringify(options.models), ticketID: self.ticket_ID };
}
}
},
error: GridCommon.showCallBackError
});
self.items_src =
new
kendo.data.DataSource({
transport: {
read: {
url: self.HANDLER_URL +
"/GetItems"
,
dataType:
"json"
,
type:
"GET"
}
},
error: GridCommon.showCallBackError
});
self.itemDropDownEditor =
function
(container, options) {
$(
'<input required data-text-field="ExtendedItemName" data-value-field="ItemName" data-bind="value:'
+ options.field +
'"/>'
)
.appendTo(container)
.kendoDropDownList({
autoBind:
false
,
optionLabel: { ExtendedItemName: GridCommon.emptyText, ItemID: 0 },
dataSource: self.items_src,
change:
function
(e) {
options.model.set(
'ItemID'
, e.sender.dataItem().ItemID);
}
});
}
self.updateTotal =
function
(e) {
var
r = e.values.Rate ? e.values.Rate : e.model.Rate;
var
q = e.values.Quantity ? e.values.Quantity : e.model.Quantity;
e.model.set(
'Total'
, q * r);
}
self.init =
function
() {
var
tools =
null
;
var
row_commands =
null
;
if
(self.IS_EDITABLE) {
tools = [
{ name:
"save"
, text:
"Save"
},
{ name:
"cancel"
, text:
"Cancel"
},
{ name:
"create"
, text:
"Add"
},
{ template: GridCommon.toggleBillableTemplate(self.GRID_ID) }
];
row_commands = [{
name:
"destroy"
,
template:
'<a href="##" class="k-grid-delete"><img img src="/Content/images/icons/delete.png" /></a>'
}]
}
else
{
$(self.GRID_ID).addClass(
'readonly'
);
}
$(self.GRID_ID).kendoGrid({
toolbar: tools,
save: self.updateTotal,
columns: [
{ field:
"ItemName"
, title:
"Item Type"
, editor: self.itemDropDownEditor },
{ field:
"Description"
},
{ field:
"Quantity"
, title:
"QTY"
, width: 65, editor: GridCommon.numberEditor },
{ field:
"Rate"
, title:
"Price"
, format:
"{0:c}"
, width: 90, editor: GridCommon.numberEditor },
{ field:
"Total"
, editor: GridCommon.notEditable, format:
"{0:c}"
, width: 95 },
{ field:
"Billable"
, template:
'#= GridCommon.getBillableText(Billable) #'
, width: 100},
{ command: row_commands, width: 40 }
],
pageable:
false
,
scrollable:
true
,
editable: self.IS_EDITABLE,
navigatable:
true
,
sortable:
true
,
batch:
true
,
dataSource: self.material_source,
saveChanges: GridCommon.saveAll
});
}
}
@model Guid
<
div
class
=
"grid-wrapper"
>
<
div
id
=
"materials-data"
class
=
"grid-global-save"
>
<!-- grid will appear here -->
</
div
>
</
div
>
<
script
type
=
"text/javascript"
>
var mat_grid = new MaterialsGrid('@Model', 'materials-data', true, true);
$(document).ready(mat_grid.init);
</
script
>
[AcceptVerbs(HttpVerbs.Post)]
public
JsonResult Create([DataSourceRequest] DataSourceRequest request, IEnumerable<TempVM> materials, string ticketId)
{
ModelState.Remove(
"MaterialEntryId"
);
ModelState.Remove(
"Id"
);
return
Json(
""
);
}
public
class
TempVM
{
public
string
MaterialEntryID {
get
;
set
; }
public
string
TicketID {
get
;
set
; }
public
int
ItemID {
get
;
set
; }
public
string
Description {
get
;
set
; }
}
I know the logic inside create isn't right. But the problem is that the 'materials' parameter is empty when the Create method is called. You can see that the form data seems to be being sent correctly in chrome's Netowork tab, by looking at the attached file.
Any ideas what I am doing wrong?