Thursday, October 23, 2014

JQuery Plugin Creation – with Sample Code!


Ben Daland
Business Analytics Specialist

With JQuery being one of the most widely used JavaScript libraries, there are times where you have to reuse code.  A function isn’t always the answer and oftentimes you need to write your own JQuery plugin or extend an already existing one. The purpose of this post is to show how to make a simple JQuery plugin.

Before starting your plugin, there are a few things to consider. Will this plugin be used for one element or will it perform actions on a group of elements? Will it be chainable with other methods or plugins? Will it allow customization? This example will be for a group of elements, chainable and customizable. The plugin will be a simple length validator that will add a CSS class to an input based on whether it is a valid or invalid length.

To start off, we will add a new property to the JQuery.fn object—the property will be the name of your plugin. In the example below, I named the plugin LengthValidator. Now we are going to make the plugin work for multiple elements and have it chainable to other events. To do that, we need to make sure the plugin returns the ‘this’ keyword; to work with a group of elements simply perform the ‘each’ method. See example below.
_________________________________________________________________________________________________________________

(function($) {
    $.fn.LengthValidator = function () {
               return this.each(function () {
                //add code here
        });
    };
} (jQuery));

_________________________________________________________________________________________________________________
Now we can allow this plugin to be customized by the user. We need to change our plugin method to allow one argument by adding the ‘options’ argument.  
_________________________________________________________________________________________________________________
$.fn.LengthValidator = function (options) {
_________________________________________________________________________________________________________________
When allowing customization, it’s a good idea to have a default object that has default values for the settings. This allows the user to set whatever they want or none at all.
_________________________________________________________________________________________________________________
   $.fn.LengthValidator.defaults = {
min: 1,
max: 999,
valid: 'valid',
invalid: 'invalid'
    };
_________________________________________________________________________________________________________________
With the plugin accepting options and our own default settings, we need to merge them using the JQuery method ‘extend’. This method combines two or more objects into one, which is the option we will use throughout the plugin.
_________________________________________________________________________________________________________________
options = $.extend({}, $.fn.LengthValidator.defaults, options);
_________________________________________________________________________________________________________________
Now we can make this plugin actually do something! In my example, I’m going to have this plugin register the focusin, focusout and change events to each object in the collection. This needs to happen inside of the ‘each’ method so these events get registered to the object(s). See example below.
_________________________________________________________________________________________________________________
 $.fn.LengthValidator = function (options) {                                                                                                            
        options = $.extend({}, $.fn.LengthValidator.defaults, options);
        return this.each(function () {
               var elm = $(this);
               elm.focusin(function () {  })
                              .focusout(function () {  })
                              .change(function () { });                 
        });
    };
_________________________________________________________________________________________________________________
Since this plugin will be preforming the same length validation for each event, I added the method ‘checkLength’ inside the scope to reduce the same validation being written more than once. The method will be added inside of the events to perform the validation.
_________________________________________________________________________________________________________________
checkLength($(this), options, $.trim(elm.val()).length);
_________________________________________________________________________________________________________________
With this method, we pass the element, settings and length of the input value to check if it meets our min and max settings. If the value is less than or greater than, it will add the invalid class. If not, it will add the valid class. The method is being called before the events are registered—this is to validate the inputs when the plugin is assigned to the element. The complete plugin code is below.
_________________________________________________________________________________________________________________
(function($) {
    $.fn.LengthValidator = function (options) {
        options = $.extend({}, $.fn.LengthValidator.defaults, options);
        return this.each(function () {
               var elm = $(this);              
               checkLength($(this), options, $.trim(elm.val()).length);      
               elm.focusin(function () { checkLength($(this), options, $.trim(elm.val()).length); })
                              .focusout(function () { checkLength($(this), options, $.trim(elm.val()).length); })
                              .change(function () { checkLength($(this), options, $.trim(elm.val()).length); });                       
        });
    };
    function checkLength(elm, opts, len) {
               if(elm.hasClass(opts.valid)){ elm.removeClass(opts.valid); }
               if(elm.hasClass(opts.invalid)){ elm.removeClass(opts.invalid); }
               if( len < opts.min || len > opts.max ){
                              elm.addClass(opts.invalid);
               } else {
                              elm.addClass(opts.valid);
               }
    }
    $.fn.LengthValidator.defaults = {
        min: 1,
        max: 999,
        valid: 'valid',
        invalid: 'invalid'
    };
} (jQuery));
_________________________________________________________________________________________________________________
Now we are ready to use this plugin!
_________________________________________________________________________________________________________________
$('input[type=text]').LengthValidator({ min: 5, max: 10, valid: 'input-valid', invalid: 'input-invalid' });
_________________________________________________________________________________________________________________
This is a very simple JQuery plugin that can be extended to meet your needs. This is a good option for keeping your JavaScript nice and clean when using the same code over and over again. 

This example can be viewed and downloaded here. 

Thursday, October 9, 2014

How much memory is needed for a great user experience in QlikView?



Susie Bann
Business Analytics Specialist

This is a question I am always asked when designing and releasing QlikView applications to various user groups.  As I’m sure you know, QlikView allows users to analyze data quickly due to the associative in-memory technology design.  Unique entries are only stored once in-memory; other entries are pointers to the parent data.  Therefore, memory and CPU sizing is very important for the end-user experience.  Performance is directly connected to the hardware QlikView is running on.

The main performance factors in QlikView are data model complexity, amount of unique data, UI design and concurrent users.  All of these factors play into scalability, which is pretty linear when discussing QlikView.

There is a basic formula that can be used to determine the amount of memory that is needed as a starting point. 

The formula:

For every QVW
((Size of Disk) * 4) + (Size of Disk * 4) * .05 * (Number of Concurrent Users)

Here’s an example:

Source Data size = 50GB
Compression Ratio = 90%
File Size = 4 for multiplier
User Ratio = 5%
Concurrent Users = 50

*Note that concurrent users is NOT the total number of supported users

The size of disk is (50GB * (1-0.9)) = 5GB

RAM = (5GB * 4) + (5GB * 4) * 0.05 * 50 = 70GB for 50 concurrent users

Given the formula and these specs, the suggested minimum would be 70GB HD at the start of an implementation.

Under normal QlikView deployments, word eventually gets out about return-on-investment and more departments will request to have their own QlikView deployments.  Additional departments = more diverse sets of data and increase of demand on the server.

It is important to know of any increases in demand, as you need to make sure that the size of server is still appropriate.  One tool that is very helpful for performance monitoring is the QVS System Monitor.  Please follow this link for more details about the QVS System Monitor app and how to deploy: http://community.qlik.com/docs/DOC-6699