This is the second part of our blog series dealing with the development of a JavaScript add-in for Dynamics NAV 2013 R2. The idea of this development is to also provide a Web Client version of our Visual Production Scheduler add-in. The first blog post gave some getting started tips and then provided a detailed guidance how to use external libraries. With this second post we have a look at how to dynamically load JavaScript files and how to intelligently stretch the JavaScript add-in so that it automatically uses the free space in vertical and horizontal direction.
Generally, it is a good idea not to load all available JavaScript code at once. For instance, imagine you have code that is specific to regional settings. In that case, it is much more elegant to load only those code parts relevant to this region as this reduces the amount of code to be downloaded.
In our case, we have a lot of JavaScript files which are specific to a certain region (e.g the names of days and months etc. that we use in the timescale of the Gantt chart). Since a Web Client normally uses just one language, we were looking for a way to load the required file dynamically. Image resources turned out to be a valuable help as they can be loaded dynamically in contrast to the other resource types. Hence, we copied the region-specific JavaScript files to the Image folder. At runtime, we now can load the required file by the following JavaScript call:$.ajax({
url: Microsoft.Dynamics.NAV.GetImageResource(“ExtLib”+ cultureName +".min.js"),
dataType: "script",
async: false
});
This way, we succesfully “abuse” the mechanism of dynamically loading images for JavaScript files.
Normally, it should be possible to stretch a control add-in in such a manner that it uses all the available space both in vertical and in horizontal direction. For this purpose the tags <VerticalStretch> and <HorizontalStretch> are provided inside the manifest file. But unfortunately, the vertical stretching does not match our needs.
The reason for this is that Dynamics NAV embeds a control add-in into an <iframe>-element that has the height set to auto. This means the web browser will calculate the height of a control add-in depending on its content height.
In order to have a best possible usage of the screen and to avoid two vertical scrollbars, we developed a smart algorithm, which calculates the height currently available for the control add-in. The fundamental idea of that algorithm is to determine first the needed space – let us call it the rest – above and below the control add-in. We manage this by stretching the add-in to a huge firm value and then retrieving the scroll height of the container. At last, the available height can be calculated by subtracting the rest from the scroll height. This is implemented as follows:
var _stretchContainer = function () {
var scrollbarWidth = 17;
var $scrollContainer = $(parent.document).find('.ms-core-overlay');
if ($scrollContainer.length !== 0) {
var containerHeight = $scrollContainer[0].getBoundingClientRect().height;
var oldContainerScrollHeight = $scrollContainer.prop('scrollHeight');
// Determine the current additional height which lets appear the
// vertical scrollbar, if any.
var additionalHeight = 0;
if (oldContainerScrollHeight > containerHeight)
additionalHeight = oldContainerScrollHeight - containerHeight;
// Set the height of the iframe which contains the control add-in
// to a very high value so that a vertical scrollbar will appear
// in any case.
var $iframe = $(parent.document).find("iframe:first");
$iframe.css('height', '10000px');
// Calculate the available height.
// With (containerScrollHeight - 10000) we calculate the space which is
// used by all the other elements above and below the control add-in.
var containerScrollHeight = $scrollContainer.prop('scrollHeight');
var availableHeight = containerHeight - (containerScrollHeight - 10000)
- scrollbarWidth
+ additionalHeight;
// Ensure that the height will not go below the given minimum
var minHeight = $iframe.css("min-height").replace("px", "");
if (availableHeight < minHeight)
availableHeight = minHeight;
// Set the available height
$iframe.css('height', availableHeight + 'px');
}
// Reduce the height of the VPS Editor by the height of the tool bar ribbon
$('#VPSEditor').css('height', '100%')
.css('height', '-=' + $('#AppRibbon').outerHeight(true)
+ 'px');
}
// resize VPSEditor element
$(top.window).bind("resize", function () {
// resize the VPSEditor element when the browser window has been resized
_stretchContainer();
});
$(window).bind("resize", function () {
// resize the VPSEditor element when the element's parent window
// has been resized
_stretchContainer();
});
This was the second blog sharing our experience in developing JavaScript add-ins for Microsoft Dynamics NAV 2013 R2. From the below you can see what is coming next:
However, we will not stop after the third blog. In the meantime, we made some new interesting experiences that we also intend to share with you. Hence, we recommend that you come back and look out for additional stuff regarding the development of a JavaScript add-in for Dynamics NAV.
Please also share with us in the comments your experiences with NAV JavaScript development, and also your thoughts on this blog post here. Looking forward to a great discussion.
Last but not least: Have a look at our HTML5/JavaScript Framework that we use to develop individual web Gantt charts quickly.
In the meantime, we made the technology that we used to build our Visual Production Scheduler, also available for Dynamics NAV and Dynamics 365 Business Central developers. We call this the Visual Scheduling Add-in Development Toolbox and it comes with either a C/AL or an AL API. If you are a NAV/BC developer and want to build your own visual scheduler, you might have a look at this toolbox. By the way: you can download a trial version including a sample integration of a visual scheduler in Dynamics 365 Business Central and Dynamics NAV.