Introduction
This article and video recaps the Rich Client Module Development session I presented at the Southern Fried DNN Conference Day of DNN day on April 13, 2013. The session was a short 1 hour presentation of a large topic. The goal of the session was to show a new paradigm for module development that takes us beyond webforms development which focuses on server-side page composition and moves us into developing modules that compose the page mostly from the client. This is an important evolution for DNN developers to not only get less dependent on server side controls, but also translates into skills for mobile development and other next generation technologies.
The Data Visualizer module
First I demonstrate the functionality of the Data Visualizer module that I built for this presentation. This module is a functioning chart generator. You can change the chart type from bar to line or pie, flip the axis, change the dimensions, or edit the caption. After every change, you will see the chart re-render itself dynamically without any page postbacks. You can also change the chart series data (which I preloaded). This data is stored in a table and, if changed from the dropdown, the chart will re-render itself with posting back the page.
DotNetNuke module architecture (typical and best practice)
Next I show how we must evolve our module development architecture in 2 ways:
- Enhancing our module projects with MVP and other patterns to make them more scaleable and maintainable applications that can be unit tested
- Making our architecture support rich client development by way of using DNN framework service that can be accessed directly by our javascript
The Data Visualizer technology stack
Here is a rundown of the stack:
- DNN Services Framework
- DAL2 Data Layer
- JSON
- jQuery Ajax
- jQuery Visualize plugin (Html5 Canvas)
- Knockoutjs
Developing DotNetNuke 7 Framework Services and Client
Our chart plugin expects its data to come from an html table. So to get the data and build the html table dynamically, we create a DNN framework service to feed us a json object that consists of the chart's default options and series data that is stored in the database. Then we use knockout templating to build an html table out of the json object. So we start by creating the tables and DAL2 layer. For more detail on the DAL2 development in DNN7, see my DNN7 complete course training.
Next we expose our data with a DNN7 framework service. For a tutorial of the DNN services framework, check out my introduction study article. To keep it simple, I am just using anonymous authorization for this data service. It is probably more appropriate to use DnnModuleAuthorizeAttribute for this. Check out Brian Duke's presentation about Mobile APIs or Peter Donker's article on Authorization in the new DNN Services Framework for some great study on this topic.
Now that we have our service working to give us json data, we build the ajax function that will call it.
function getChartData(chartId, serviceRoot) {
jQuery.ajax({
type: "GET",
url: serviceRoot + "chartdata/datasets/" + chartId,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
ko.applyBindings(new ChartViewModel(response));
},
error: function (xhr, ajaxOptions, thrownError) {
alert("status: " + xhr.status + "\n" + thrownError);
}
});
}
KnockoutJS
Once we retrieve our chart data from the service, our ajax function will initialize our knockoutjs view model. Knockout is used to bind our chart options to their respective form elements thereby controlling the event handling between the view model and the DOM elements. It is also used to create the series data html table for consumption by our chart plugin using it's template engine. There is a lot about knockout that I cannot properly teach in this tutorial, so if you are brand new to it, go to knockoutjs.com and go through their tutorials to get a basic understanding.
For the chart options, we create observable attributes in our viewmodel that are initialized to our corresponding chart data fields.
self.title = ko.observable(chartData.Title);
Then we add the data-bind attribute to the DOM element that we want to edit the attribute.
<input type="text" name="title" id="title" class="longSingleText" data-bind="value: title" />
Then we add a computed function to compose any options change into the options array that the chart plugin needs by using a computed function.
self.chartOptions = ko.computed(function () { … } , this);
For our series data, we create an observable array which is a copy of the chart data's series array. We probably could skip this step, but it makes a future possibility of binding the data to textboxes to make it editable.
// Bind the series data
var seriesObservableArray = ko.observableArray();
for (i = 0; i < chartData.SeriesData.length; i++) {
series = chartData.SeriesData[i];
seriesObservableArray.push(new Series(series.Name, series.Values));
}
self.seriesData = seriesObservableArray;
Now we use knockout's template engine to write the html table using the observable array. A better way to do this is to modify the jquery plugin to take the json data directly, but I didn't want to mess with that code for this demonstration.
<tbody data-bind="template: { name: 'bodyTmpl', foreach: seriesData }, visualize: chartOptions"> …
Finally we create a custom event in knockout to refresh the jQuery chart plugin when either the chart data or chart options are updated
// Create handler for refreshing the chart based on setting or chart data update
ko.bindingHandlers.visualize = {
update: function (element, valueAccessor, allBindingsAccessor) {
// get value which should be chartoptons
var value = ko.utils.unwrapObservable(valueAccessor());
$('.visualize').remove();
if (value != null)
$('#VDatatable').visualize(value);
}
}
Installing the project
To install the project and start building onto it, do the following:
- Download the code project zip file
- Unzip the project into the DesktopModules folder of you DotNetNuke 7 installation
- Open the project in Visual Studio and do a release build
- In the project root folder, there should be an install folder with some zip packages, go to your DNN installation in the browser and install the source package
- Once installed, the module can be added to a page for testing.
- Download the SQL data script and run it to create the test data like I have. You will have to change the moduleID in the inserts to match your moduleID.