Skip to content

Commit 2783bed

Browse files
committed
Add foreign key editing.
1 parent 5ebdd0e commit 2783bed

File tree

6 files changed

+133
-202
lines changed

6 files changed

+133
-202
lines changed

grid/odata-v4-web-api-binding/OdataTest/App_Start/WebApiConfig.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public static void Register(HttpConfiguration config)
1414
// Web API configuration and services
1515
ODataModelBuilder builder = new ODataConventionModelBuilder();
1616
builder.EntitySet<Product>("Products");
17-
builder.EntitySet<Employee>("Employees");
17+
builder.EntitySet<Category>("Categories");
1818
config.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());
1919

2020
//ODataModelBuilder builderEmployees = new ODataConventionModelBuilder();
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Data;
4+
using System.Data.Entity;
5+
using System.Data.Entity.Infrastructure;
6+
using System.Linq;
7+
using System.Net;
8+
using OdataTest.Models;
9+
using System.Web.OData;
10+
11+
namespace OdataTest.Controllers
12+
{
13+
/*
14+
To add a route for this controller, merge these statements into the Register method of the WebApiConfig class. Note that OData URLs are case sensitive.
15+
16+
using System.Web.Http.OData.Builder;
17+
using OdataTest.Models;
18+
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
19+
builder.EntitySet<Category>("Categories");
20+
builder.EntitySet<Product>("Product");
21+
config.Routes.MapODataRoute("odata", "odata", builder.GetEdmModel());
22+
*/
23+
public class CategoriesController : ODataController
24+
{
25+
private NorthwindEntities db = new NorthwindEntities();
26+
27+
// GET odata/Categories
28+
[EnableQuery]
29+
public IQueryable<Category> GetCategories()
30+
{
31+
return db.Categories;
32+
}
33+
34+
// GET odata/Categories(5)
35+
36+
37+
protected override void Dispose(bool disposing)
38+
{
39+
if (disposing)
40+
{
41+
db.Dispose();
42+
}
43+
base.Dispose(disposing);
44+
}
45+
}
46+
}

grid/odata-v4-web-api-binding/OdataTest/Controllers/EmployeesController.cs

Lines changed: 0 additions & 82 deletions
This file was deleted.

grid/odata-v4-web-api-binding/OdataTest/Controllers/ProductsController.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ public IHttpActionResult Post(Product product)
8282
return BadRequest(ModelState);
8383
}
8484
db.Products.Add(product);
85-
//db.SaveChanges();
85+
db.SaveChanges();
86+
8687
return Created(product);
8788
}
8889

grid/odata-v4-web-api-binding/OdataTest/KendoUIMVC5.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@
117117
</ItemGroup>
118118
<ItemGroup>
119119
<Compile Include="App_Start\WebApiConfig.cs" />
120+
<Compile Include="Controllers\CategoriesController.cs" />
120121
<Compile Include="Controllers\ProductsController.cs" />
121-
<Compile Include="Controllers\EmployeesController.cs" />
122122
<Compile Include="Global.asax.cs">
123123
<DependentUpon>Global.asax</DependentUpon>
124124
</Compile>
Lines changed: 83 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,142 +1,108 @@
11
<!DOCTYPE html>
22
<html xmlns="http://www.w3.org/1999/xhtml">
33
<head>
4-
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1119/styles/kendo.common.min.css">
5-
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1119/styles/kendo.rtl.min.css">
6-
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1119/styles/kendo.default.min.css">
7-
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1119/styles/kendo.dataviz.min.css">
8-
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1119/styles/kendo.dataviz.default.min.css">
9-
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1119/styles/kendo.mobile.all.min.css">
4+
<link rel="stylesheet" href="http://cdn.kendostatic.com/2015.2.624/styles/kendo.common.min.css">
5+
<link rel="stylesheet" href="http://cdn.kendostatic.com/2015.2.624/styles/kendo.default.min.css">
106
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
11-
<script src="http://cdn.kendostatic.com/2014.3.1119/js/kendo.all.min.js"></script>
7+
<script src="https://kendo.cdn.telerik.com/2015.2.624/js/kendo.all.min.js"></script>
128
<meta charset=utf-8 />
139
<title>Odata 4 with WebAPI</title>
1410
</head>
1511
<body>
1612
<div id="products"></div>
17-
<div id="employees"></div>
18-
1913
<script>
20-
$(document).ready(function () {
21-
$("#products").kendoGrid({
22-
dataSource: {
23-
type: "odata-v4",
24-
transport: {
25-
read: {
26-
url: "/odata/Products",
27-
data: {
28-
$expand: "Category"
29-
}
30-
},
31-
update: {
32-
url: function (data) {
33-
return "/odata/Products(" + data.ProductID + ")";
34-
}
35-
},
36-
create: {
37-
url: "/odata/Products"
14+
$("#products").kendoGrid({
15+
dataSource: {
16+
type: "odata-v4",
17+
transport: {
18+
read: {
19+
url: "/odata/Products",
20+
data: {
21+
$expand: "Category"
3822
}
39-
},
40-
schema: {
41-
model: {
42-
id: "ProductID",
43-
fields: {
44-
UnitPrice: { type: "number" },
45-
SupplierID: { type: "number" },
46-
UnitsInStock: { type: "number" },
47-
UnitsOnOrder: { type: "number" },
48-
ProductID: { type: "number" },
49-
Discontinued: { type: "boolean" }
50-
}
51-
}
52-
5323
},
54-
requestEnd: function(e) { //this is no longer needed in latest internal build
55-
if (e.type == "create") {
56-
delete e.response["@odata.context"];
24+
update: {
25+
url: function (data) {
26+
return "/odata/Products(" + data.ProductID + ")";
5727
}
5828
},
59-
pageSize: 10,
60-
serverFiltering: true,
61-
serverPaging: true,
62-
serverSorting: true
29+
create: {
30+
url: "/odata/Products?$expand=Category"
31+
}
6332
},
64-
height: 550,
65-
toolbar: ["create"],
66-
groupable: true,
67-
sortable: true,
68-
filterable: {
69-
mode: "row"
33+
sort: {
34+
field: "ProductID",
35+
dir: "desc"
7036
},
71-
pageable: {
72-
refresh: true,
73-
pageSizes: true,
74-
buttonCount: 5
75-
},
76-
columns: [{
77-
field: "ProductName",
78-
width: 300
79-
}, {
80-
field: "ProductID"
81-
},
82-
"UnitPrice", "UnitsOnOrder", "Discontinued", { command: "edit" }
83-
],
84-
editable: "inline"
85-
});
86-
87-
88-
89-
$("#employees").kendoGrid({
90-
dataSource: {
91-
type: "odata-v4",
92-
transport: {
93-
read: {
94-
url: "/odata/Employees"
95-
},
96-
update: {
97-
url: function (data) {
98-
return "/odata/Employees(" + data.EmployeeID + ")";
99-
}
100-
}
101-
},
102-
schema: {
103-
model: {
104-
id: "EmployeeID",
105-
fields: {
106-
Firstname: { type: "string" },
107-
BirthDate: { type: "date" },
108-
EmployeeID: { type: "number" }
109-
}
37+
schema: {
38+
model: {
39+
id: "ProductID",
40+
fields: {
41+
UnitPrice: { type: "number" },
42+
SupplierID: { type: "number" },
43+
UnitsInStock: { type: "number" },
44+
UnitsOnOrder: { type: "number" },
45+
ProductID: { type: "number", editable: false },
46+
SupplierID: { type: "number", defaultValue: 1 },
47+
Discontinued: { type: "boolean" },
48+
CategoryID: { type: "number" },
49+
Category: { defaultValue: { CategoryID: 1, CategoryName: "Beverages" } }
11050
}
51+
}
11152

112-
},
113-
pageSize: 10,
114-
serverFiltering: true,
115-
serverPaging: true,
116-
serverSorting: true
11753
},
118-
height: 550,
119-
120-
groupable: true,
121-
sortable: true,
122-
filterable: {
123-
mode: "row"
54+
requestEnd: function(e) {
55+
if (e.type == "create") {
56+
// Make a read request to expand Category. By default the OData controller doesn't expand on create.
57+
this.read();
58+
}
12459
},
125-
pageable: {
126-
refresh: true,
127-
pageSizes: true,
128-
buttonCount: 5
129-
},
130-
columns: [
131-
{ field: "FirstName", width: 300 },
132-
{ field: "LastName", width: 300 },
133-
{ field: "BirthDate", width: 300, format: "{0: MM/dd/yyyy}" },
134-
{ command: ["edit", "destroy"] }
135-
],
136-
editable: "inline"
137-
});
60+
pageSize: 10,
61+
serverFiltering: true,
62+
serverPaging: true,
63+
serverSorting: true
64+
},
65+
height: 650,
66+
toolbar: ["create"],
67+
groupable: true,
68+
sortable: true,
69+
filterable: {
70+
mode: "row"
71+
},
72+
pageable: {
73+
refresh: true,
74+
pageSizes: true,
75+
buttonCount: 5
76+
},
77+
save: function(e) {
78+
// Sync Product.CategoryID with Product.Category.CategoryID to avoid referential integrity constraint errors.
79+
e.model.set("CategoryID", e.model.Category.CategoryID);
80+
},
81+
columns: [
82+
{ field: "ProductID" },
83+
{ field: "ProductName", width: 300 },
84+
{ field: "Category", template: "#: Category ? Category.CategoryName : '' #", editor: categoryEditor },
85+
"UnitPrice", "UnitsOnOrder", "Discontinued", { command: "edit" }
86+
],
87+
editable: "inline"
13888
});
13989

90+
function categoryEditor(container, options) {
91+
$('<input required data-text-field="CategoryName" data-value-field="CategoryID" data-bind="value:' + options.field + '"/>')
92+
.appendTo(container)
93+
.kendoDropDownList({
94+
autoBind: false,
95+
dataSource: {
96+
type: "odata-v4",
97+
pageSize: 10,
98+
transport: {
99+
read: {
100+
url: "/odata/Categories"
101+
}
102+
}
103+
}
104+
});
105+
}
140106
</script>
141107
</body>
142108
</html>

0 commit comments

Comments
 (0)