kmp
kmp

Reputation: 10875

How to use Kendo UI MVC Extensions with require js?

I have a controller that looks like this:

using System.Collections.Generic;
using System.Web.Mvc;

using Kendo.Mvc.Extensions;
using Kendo.Mvc.UI;

namespace KendoMvcApplication.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult GetData([DataSourceRequest] DataSourceRequest req)
        {
            var products = CreateProducts();
            var result = products.ToDataSourceResult(req);
            return Json(result);
        }     

        private static IEnumerable<Product> CreateProducts()
        {
            for (int i = 1; i <= 20; i++)
            {
                yield return new Product
                {
                    ProductId = i,
                    ProductName = "Product " + i,
                    ProductPrice = i * 2.5
                };
            }
        }
    }

    public class Product
    {
        public int ProductId { get; set; }
        public string ProductName { get; set; }
        public double ProductPrice { get; set; }
    }
}

And a view that looks like this:

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8" />
    <link href="~/Content/kendo.common.min.css" rel="stylesheet" />
    <link href="~/Content/kendo.default.min.css" rel="stylesheet" />
    <script type="text/javascript" src="~/Scripts/require.js"></script>
</head>
<body>            
<div id="grid"></div>
<script type="text/javascript">            
    require.config({
        baseUrl : '@Url.Content("~/Scripts")',
        paths: {
            'jquery': 'jquery-2.0.3.min',
            'kendo': 'kendo-ui'
        },
        shim: {
            'jquery': {
                exports: 'jQuery'
            }
        }            
    });           
    require(['jquery', 'kendo/kendo.grid.min'], function ($) {
        $(document).ready(function () {
            $('#grid').kendoGrid({
                dataSource: {
                    schema: {
                        data: 'Data',
                        total: 'Total',
                        aggregates: 'AggregateResults',
                        model: {
                            id: "ProductId",
                            fields: {
                                ProductName: { type: "string" },
                                ProductPrice: { type: "number" }
                            }
                        }
                    },
                    transport: {
                        read: {
                            url: "@Url.Action("GetData", "Home")",
                            dataType: "json",
                            method: "post"
                        }
                    },
                    pageSize: 10,
                    serverPaging: true,
                    serverSorting: true,
                    type: "aspnetmvc-ajax"
                },
                sortable: {
                    mode: "single"
                },
                columns: ["ProductName", "ProductPrice"],
                scrollable: false,
                pageable: true
            });
        });            
    });
</script>
</body>
</html>

And my directory structure is:

which nearly works except that server-side sorting doesn't get applied.

This is because the kendo.aspnet.mvc.min.js file is never downloaded (of course, as require JS doesn't know anything about it) so to remedy that I tried this:

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8" />
    <link href="~/Content/kendo.common.min.css" rel="stylesheet" />
    <link href="~/Content/kendo.default.min.css" rel="stylesheet" />
    <script type="text/javascript" src="~/Scripts/require.js"></script>
</head>
<body>            
<div id="grid"></div>
<script type="text/javascript">
    require.config({
        baseUrl: '@Url.Content("~/Scripts")',
        paths: {
            'jquery': 'jquery-2.0.3.min',
            'kendo': 'kendo-ui',
            'kendo-mvc': 'kendo/kendo.aspnetmvc.min'
        },
        shim: {
            'jquery': {
                exports: 'jQuery'
            }
        }
    });
    require(['jquery', 'kendo-mvc', 'kendo/kendo.grid.min'], function ($) {
        $(document).ready(function () {
            $('#grid').kendoGrid({
                dataSource: {
                    schema: {
                        data: 'Data',
                        total: 'Total',
                        aggregates: 'AggregateResults',
                        model: {
                            id: "ProductId",
                            fields: {
                                ProductName: { type: "string" },
                                ProductPrice: { type: "number" }
                            }
                        }
                    },
                    transport: {
                        read: {
                            url: "@Url.Action("GetData", "Home")",
                            dataType: "json",
                            method: "post"
                        }
                    },
                    pageSize: 10,
                    serverPaging: true,
                    serverSorting: true,
                    type: "aspnetmvc-ajax"
                },
                sortable: {
                    mode: "single"
                },
                columns: ["ProductName", "ProductPrice"],
                scrollable: false,
                pageable: true
            });
        });
    });
</script>
</body>
</html>

But that produced this error:

split configuration error

And attempted to load the js files thus:

try 1 files

The red spots are 404 not found as it is looking for the js files in a folder called kendo under the scripts folder.

So then I thought I would try including the all version instead so I tried this:

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8" />
    <link href="~/Content/kendo.common.min.css" rel="stylesheet" />
    <link href="~/Content/kendo.default.min.css" rel="stylesheet" />
    <script type="text/javascript" src="~/Scripts/require.js"></script>
</head>
<body>            
<div id="grid"></div>
<script type="text/javascript">
    require.config({
        baseUrl: '@Url.Content("~/Scripts")',
        paths: {
            'jquery': 'jquery-2.0.3.min',
            'kendo': 'kendo-ui/kendo.all.min',
            'kendo-mvc': 'kendo-ui/kendo.aspnetmvc.min'
        },
        shim: {
            'jquery': {
                exports: 'jQuery'
            }
        }
    });
    require(['jquery', 'kendo', 'kendo-mvc'], function ($) {
        $(document).ready(function () {
            $('#grid').kendoGrid({
                dataSource: {
                    schema: {
                        data: 'Data',
                        total: 'Total',
                        aggregates: 'AggregateResults',
                        model: {
                            id: "ProductId",
                            fields: {
                                ProductName: { type: "string" },
                                ProductPrice: { type: "number" }
                            }
                        }
                    },
                    transport: {
                        read: {
                            url: "@Url.Action("GetData", "Home")",
                            dataType: "json",
                            method: "post"
                        }
                    },
                    pageSize: 10,
                    serverPaging: true,
                    serverSorting: true,
                    type: "aspnetmvc-ajax"
                },
                sortable: {
                    mode: "single"
                },
                columns: ["ProductName", "ProductPrice"],
                scrollable: false,
                pageable: true
            });
        });
    });
</script>
</body>
</html>

But that produced these errors:

ASP NET MVC Errors

And attempted to load the js files thus:

case 2 files

In this case - the red spots are 404 not found as it is looking for the files directly under the Scripts folder.

So here is my question:

How can I include said file in a require JS type scenario?

Aside: I would like to be using the kendo.all.min file and not the separate ones as I want to use knockout-kendo in the future and that seems to not work with the separate file but if the only way to make this work is to use the separate file approach, that is fine.

Upvotes: 4

Views: 5281

Answers (2)

Ohlin
Ohlin

Reputation: 4178

It took me a while to get your code working but after having been fiddling around with it a little I managed to get the sorting to work with just a tiny little change in your original code.

The only thing I changes was on the require line where I added the mvc file as well. Then all the paths became correct and it all worked out fine.

['jquery', 'kendo/kendo.grid.min', 'kendo/kendo.aspnetmvc.min']

In my code I've used "Kendo UI for ASP.NET MVC Q2 2013" with the jQuery.min.js file that was included in that package. The complete View code then becomes:

<script type="text/javascript">            
  require.config({
    baseUrl : '@Url.Content("~/Scripts")',
    paths: {
        'jquery': 'jquery-2.0.3.min',
        'kendo': 'kendo-ui'
    },
    shim: {
        'jquery': {
            exports: 'jQuery'
        }
    }            
  });           
  require(['jquery', 'kendo/kendo.grid.min', 'kendo/kendo.aspnetmvc.min'], function ($) {
    $(document).ready(function () {
        $('#grid').kendoGrid({
            dataSource: {
                schema: {
                    data: 'Data',
                    total: 'Total',
                    aggregates: 'AggregateResults',
                    model: {
                        id: "ProductId",
                        fields: {
                            ProductName: { type: "string" },
                            ProductPrice: { type: "number" }
                        }
                    }
                },
                transport: {
                    read: {
                        url: "@Url.Action("GetData", "Home")",
                        dataType: "json",
                        method: "post"
                    }
                },
                pageSize: 10,
                serverPaging: true,
                serverSorting: true,
                type: "aspnetmvc-ajax"
            },
            sortable: {
                mode: "single"
            },
            columns: ["ProductName", "ProductPrice"],
            scrollable: false,
            pageable: true
        });
    });            
  });
</script>

I hope it'll work in your code as well.

Upvotes: 4

Chris
Chris

Reputation: 6095

Let's try building up from a minimal working version. You said you have the following in the directory:

  • Scripts/kendo-ui/* (all the kendo files, including the mvc one)
  • Scripts/require.js
  • Scripts/jquery-2.0.3.min.js

To get that to load all the dependencies, you might try something like this:

<html>
<body>
<script type="text/javascript" src="~/Scripts/require.js"></script>
<script type="text/javascript">
    require.config({
        baseUrl: '@Url.Content("~/Scripts")',
        paths: {
            'jquery': 'jquery-2.0.3.min',
            'kendo': 'kendo-ui/kendo.all.min',
            'kendo-mvc': 'kendo-ui/kendo.aspnetmvc.min'
        },
        shim: {
            'jquery': {
                exports: 'jQuery'
            },
            'kendo-mvc' : {
                deps: ['kendo'] //kendo needs to be loaded before kendo-mvc?
            }
        }
    });
    require(['jquery', 'kendo', 'kendo-mvc'], function ($) {
    });
</script>
</body>
</html>

I played around with putting it in a jsFiddle, but ran into a number of problems (Kendo actually requires jQuery 1.9.0, etc.) that you can probably resolve on your own.

The key seems to be that your last version is loading kendo.data, kendo.combobox, and a bunch of other files that aren't referenced anywhere. Figuring out where those requests came from would help solve this mystery.

Update: Here's one possibility. If kendo-mvc is loading dependencies like this:

["./kendo.data.min","./kendo.combobox.min","./kendo.multiselect.min","./kendo.‌​validator.min"]

Then it may fail because RequireJS looks for dependencies relative to the name of the module, which has been aliased as kendo-mvc. Let's try not renaming it (see below), and see if that works:

<script type="text/javascript">
    require.config({
        baseUrl: '@Url.Content("~/Scripts")',
        paths: {
            'jquery': 'jquery-2.0.3.min',
            'kendo-ui/kendo': 'kendo-ui/kendo.all.min',
            'kendo-ui/kendo-mvc': 'kendo-ui/kendo.aspnetmvc.min'
        },
...
    require(['jquery', 'kendo-ui/kendo', 'kendo-ui/kendo-mvc'], function ($) {
    });

Upvotes: 2

Related Questions