How to defer Kendo UI Initialization scripts when using Kendo UI ASP.NET MVC Wrappers

About Kendo UI:

Kendo UI is a flagship product from Telerik which is a HTML5 powered client side JavaScript framework. We have Widgets/Controls apart from a plethora of framework level goodies like MVVM, Validation, Globalization etc. out of the box. Although this is a client side framework which means that you program against Kendo UI using JavaScript – obviously. But Kendo UI also has a server side wrapper for ASP.NET MVC very similar to HtmlHelper extensions available from Microsoft (TextBox, CheckBox etc.). What this means is, the wrappers shield you from writing JavaScript yourself and instead you code in your natural comfort zone of C# and Razor and the wrappers output the JavaScript for you. These JavaScript are the initialization scripts for the widgets.

Widget Initialization Scripts:

Kendo UI relies  on 2 things – JQuery framework and Kendo Web JavaScript file. Before you can start working with Kendo you need these 2 JavaScript file references added to your page. Assume that we have referenced the 2 script files in the head section of the page.

When you use wrappers to code on the server side, the wrappers output the necessary JavaScript code required for Kendo UI to work on the client side. Note: the wrappers do not out put the markup rather output the JavaScript which is required to initiate a widget on the client side. But the initialization code blocks are rendered right at the place where the widget was defined in your source code.

To illustrate this – lets take a simplest of the code as an example. We will use the AutoComplete Widget and see the rendered code on the client side. Here is the Razor syntax using AutoComplete Kendo UI Wrapper:

@(Html.Kendo().AutoComplete()
.Name("countries")
.Filter("startswith")
.Placeholder("Select country...")
.BindTo(new string[] {
"Bulgaria",
"India",
"Australia",
"Germany",
"USA",
"UK",
"Hong Kong"
})
.Separator(", ")
)
<div class="hint">Start typing the name of an European country</div>

Notice that we have a div after the autocomplete widget. Now at run time right click on the browser and view the source code. Here is the code that gets generated:


<input id="countries" name="countries" type="text" /><script>

jQuery(function(){jQuery("#countries").kendoAutoComplete({"dataSource":["Bulgaria","India","Australia","Germany","USA","UK"],"filter":"startswith","placeholder":"Select country...","separator":", "});});

</script>

<div class="hint">Start typing the name of an European country</div>

As you can see the initialization script code is rendered right at the place where we had defined the wrapper in our source code. This works fine as long as the Jquery and Kendo script references are done at the head level of the document. In next section we will see what happens when we move the script reference to the end of the page.

Following Best Practice for Script References:

One of the best practice of the web development is to load any scripts we need at the end of the page. What this does is it doesn’t block the page from loading. Page continues to load & render and the scripts gets loaded at the end and user does not see any blockings in the page load. But we have a problem. As seen in the previous section, the widget initialization script gets rendered at the position where the widget was defined in source code and gets executed immediately. if the Jquery and Kendo scripts are loaded at the end of the page, the initialization script will fail with errors as the frameworks are not yet loaded. Here is the error we get:

image

Deferring Initialization Scripts:

Luckily, Kendo UI Wrappers have a answer to the initialization scenario we saw in the previous section. Each of the widget wrappers expose a method called Deferred(). It’s a fluent method and will suppress immediate script statement rendering. The next question we may have is – we deferred the initialization, but how do we initialize the widget once page is loaded. Answer is, Kendo wrappers expose one more fluent method called DeferredScripts(). DeferredScripts method will output all the previously deferred initialization statements.

Here is the updated code to handle deferring the scripts:

First, I moved the Jquery and Kendo script  reference to end of the page and made a call to RenderSection. This is the section where we will out put the initialization scripts from the pages.

<script src="@Url.Content("~/Scripts/kendo/2013.2.716/jquery.min.js")"></script>
<script src="@Url.Content("~/Scripts/kendo/2013.2.716/kendo.all.min.js")"></script>
@RenderSection("PageScripts", required:false)

Second, I have called the Deferred() fluent method on the auto complete wrapper. Declared a section PageScripts and called DeferredScripts() fluent method to output the deferred statements.

@(Html.Kendo().AutoComplete()
.Name("countries")
.Filter("startswith")
.Placeholder("Select country...")
.BindTo(new string[] {
"Bulgaria",
"India",
"Australia",
"Germany",
"USA",
"UK",
"Hong Kong"
})
.Separator(", ")
.Deferred()
)
<div class="hint">Start typing the name of an European country</div>
@section PageScripts {
@Html.Kendo().DeferredScripts()
}

With the above code changes, we now have the initialization statements deferred till we explicitly call the DeferredScripts() fluent method in the PageScripts section. Here is the generated code at run time:

<input id="countries" name="countries" type="text" />
<div class="hint">Start typing the name of an European country</div>
<script src="<a href="http://localhost:39897/Scripts/kendo/2013.2.716/jquery.min.js">/Scripts/kendo/2013.2.716/jquery.min.js</a>"></script>
<script src="<a href="http://localhost:39897/Scripts/kendo/2013.2.716/kendo.all.min.js">/Scripts/kendo/2013.2.716/kendo.all.min.js</a>"></script>
<script>jQuery(function(){jQuery("#countries").kendoAutoComplete({"dataSource":["Bulgaria","India","Australia","Germany","USA","UK","Hong Kong"],"filter":"startswith","placeholder":"Select country...","separator":", "});});</script>

Conclusion:

When using Kendo UI ASP.NET MVC wrappers, you should pay attention to how you want to use the widgets. Since the wrappers output the initialization statements immediately at the position of the wrappers definition, it needs the JQuery and kendo scripts to be available upfront. If you follow the best practice of loading the scripts at the end of the page, you will need to defer the initialization statement and manually output all deferred statements after you have loaded the JQuery and Kendo scripts. This blog post introduces you to Deferred() and DeferredScripts() fluent method supported in Kendo. Hope this information is useful to you. If you have not experienced Kendo UI, encourage you to visit www.kendoui.com and take a look at our demos.

Till next time, Happy Coding!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s